主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是**单向**的,只能由主节点到从节点。Master以写为主,Slave以读为主。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制的作用主要包括:
1)、数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2)、故障恢复∶当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
3)、负载均衡∶在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
4)、高可用基石︰除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的,原因如下∶
1、从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大;
2、从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量为256G,也不能将所有内存用作Redis存储内存,一般来说,单台Redis最大使用内存不应该超过20G,
电商网站上的商品,一般都是一次上传,无数次浏览的,说专业点也就是"多读少写。
对于这种场景,我们可以使如下这种架构:
主从复制,读写分离!80%的情况下都是在进行读操作!减缓服务器的压力!架构中经常使用!一主二从!
# 运行第一个服务
docker run -itd --name redis9090 -p 9090:6379 redis:6.0-rc
# 运行第二个服务
docker run -itd --name redis9091 -p 9091:6379 redis:6.0-rc
# 运行第三个服务
docker run -itd --name redis9092 -p 9092:6379 redis:6.0-rc
redis启动后,默认是主机。因此只需要配置从机就可以了,可以通过如下命令查看当前的redis是主还从:
# 进入容器
docker exec -it redis9092 /bin/bash
# 查看节点状态
info replication
通过如下命令获取ip信息:
# 获取主节点信息
docker inspect redis9090
3个redis的内网ip地址为:
# 设置主机信息
slaveof 172.17.0.2 6379
# 查看复制信息
info replication
当我们配置SpringBoot连接时,出现如下错误:
2021-08-09 17:29:13.313 WARN 1800 --- [ioEventLoop-4-3] i.l.c.c.t.DefaultClusterTopologyRefresh : Cannot retrieve partition view from redis://127.0.0.1:9090, error: java.util.concurrent.CompletionException: io.lettuce.core.RedisCommandExecutionException: ERR This instance has cluster support disabled
2021-08-09 17:29:13.313 WARN 1800 --- [ioEventLoop-4-3] i.l.c.c.t.DefaultClusterTopologyRefresh : Cannot retrieve partition view from redis://127.0.0.1:9091, error: java.util.concurrent.CompletionException: io.lettuce.core.RedisCommandExecutionException: ERR This instance has cluster support disabled
2021-08-09 17:29:13.313 WARN 1800 --- [ioEventLoop-4-3] i.l.c.c.t.DefaultClusterTopologyRefresh : Cannot retrieve partition view from redis://127.0.0.1:9092, error: java.util.concurrent.CompletionException: io.lettuce.core.RedisCommandExecutionException: ERR This instance has cluster support disabled
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisException: Cannot obtain initial Redis Cluster topology
这时,可以使用下面命令查看一下集群的状态:
# 查看集群
cluster nodes
结果出现如下结果:
127.0.0.1:6379> cluster nodes
ERR This instance has cluster support disabled
这时候需要修改redis的配置文件,并把默认注释的下面选项放开:
cluster-enabled yes
这时候再运行cluster nodes
,则会显示如下界面:
当然,对应使用docker运行的redis来说,容器内是没有redis.conf文件的,这时候就需要通过下面的命令来运行了。
# 运行主节点
docker run -itd --name redis9090 -p 9090:6379 -v D:/app/redis/redis.conf:/usr/local/etc/redis/redis.conf:rw redis:6.0-rc redis-server /usr/local/etc/redis/redis.conf
# 运行从节点1
docker run -itd --name redis9091 -p 9091:6379 redis:6.0-rc
# 运行从节点2
docker run -itd --name redis9092 -p 9092:6379 redis:6.0-rc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.0</version>
</dependency>
spring.redis.cluster.nodes=127.0.0.1:9090,127.0.0.1:9091,127.0.0.1:9092
spring.redis.timeout=60000
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-active=300
spring.redis.lettuce.pool.max-idle=100
spring.redis.lettuce.pool.min-idle=20
```java
```