7.1 搭建基于主从复制模式的集群
在主从复制模式的集群里,主节点一般是一个,从节点一般是两个或多个,写入主节点的数据会被复制到从节点上,这样一旦主节点出现故障,应用系统就能切换到从节点去读写数据,提升系统的可用性.再采用主从复制模式里默认的读写分离机制,就能提升系统的缓存读写性能.对性能和实时性不高的系统而言,主从复制模式足以满足一般的性能和安全性方面的需求.
7.1.1 主从复制模式概述
在实际应用中,如果有相应的设置,在向一台Redis服务器里写数据后,这个数据可以复制到另外一台(或多台)Redis服务器,这里数据源服务器叫主服务器(Master Server),复制数据目的地所在的服务器叫从服务器(Slave Server)
这种主从复制模式能带来2个好处:
可以把写操作集中到主服务器上,把读操作集中到从服务器上,以提升读写性能
由于出现了数据备份,因此能提升数据的安全性,比如当主Redis服务器失效后,能很快切换到从服务器上读数据

主从复制模式的要点:
一个主服务器可以带一个或多个从服务器,从服务器可以再带从服务器,但在复制数据时只能把主服务器的数据复制到从服务器上,反之不能
一台从服务器只能跟随一台主服务器,不能出现一从多主的模式
在Redis2.8以后的版本里,采用异步的复制模式,即进行主从复制时不会影响主服务器上的读写数据操作
7.1.2 用命令搭建主从集群
本例中使用Docker搭建1主2从模式的集群.配置主从关系时,需要在从节点上使用SLAVEOF命令
step1. 创建主节点容器
step2. 创建从节点1容器
step3. 检查主节点容器的IP地址
可以看到,主节点容器的IP地址为172.17.0.2
step4. 进入主节点容器,检查当前的主从模式状态
其中:
role:master:表示该节点的角色为主服务器connected_slaves:0:表示当前该主服务器没有携带从服务器step5. 进入从节点容器,检查当前主从模式状态
step6. 设置从节点容器为从服务器
在redis-slave1容器中执行如下命令:
检查从节点容器的主从状态:
其中:
role:slave:表示该节点的角色为从服务器master_host:172.17.0.2:主节点IP地址master_port:6379:主节点端口step7. 在主节点中查看主从状态
connected_slaves:1:可以看到,此时已经有1个从节点了step8. 创建从节点2容器
step9. 进入从节点2容器,设置该容器为从服务器
可以看到,此时该容器为主节点
step10. 在主节点容器中查看主从情况
可以看到,此时有2个从节点
7.1.3 通过配置搭建主从集群
step1. 编写主节点的配置文件
step2. 根据配置文件启动主节点容器
启动容器:
检查容器状态:
进入容器检查用户名密码是否配置正确:
step3. 检查主节点容器IP地址
step4. 编写从节点1的配置文件
step5. 根据配置文件启动从节点1容器
启动容器:
检查容器状态:
进入容器检查用户名密码是否配置正确:
step6. 在从节点1容器中确认主从状态
step7. 在主节点容器中确认主从状态
step8. 编写从节点2的配置文件
step9. 根据配置文件启动从节点2容器
启动容器:
检查容器状态:
进入容器检查用户名密码是否配置正确:
step10. 在从节点2容器中确认主从状态
step11. 在主节点容器中确认主从状态
可以看到,此时主节点上可以看到2个从节点的信息
step12. 测试
主节点上写入:
分别在2个从节点上读取:
7.1.4 配置读写分离效果
在2个从节点上查看配置主从状态:
其中:
slave_read_only:1:表示从服务器为只读
修改slave2节点为可读可写:
step1. 停止redis-slave2容器
step2. 修改redis-slave2的配置文件
step3. 启动redis-slave2容器
step4. 进入redis-slave2容器并尝试写入
可以看到,此时已经可以在从节点2上写入了
在主节点和从节点1上读取:
因此,需要注意的是:
在Redis主从集群模式下,从节点(Slave)默认是只读的.当你将从节点设置为可写入模式(slave-read-only no),这意味着客户端可以直接写入到这个从节点.然而,这种配置并不是常规的使用模式,并且有其特定的行为和限制.
以下是关于在从节点上写入时发生的事情的解释:
写入不会同步到主节点或其他从节点:当你直接在从节点上进行写入操作时,这些写入不会被传播到主节点或其他从节点.这是因为在Redis的复制模型中,只有主节点才会将其写入操作传播到从节点
数据可能丢失:由于从节点上的写入不会同步到其他节点,因此如果这个从节点出现故障或重新启动,这些写入可能会丢失.因为当从节点重新连接到主节点时,它会从主节点获取最新的数据快照,从而丢弃任何在从节点上直接进行的写入
可能导致数据不一致:由于从节点上的写入不会传播,这意味着集群中的不同节点可能会有不同的数据,从而导致数据不一致
基于上述原因,允许直接在从节点上进行写入(将slave-read-only设置为no)通常不是推荐的做法.这种配置可能会导致数据丢失、数据不一致,并且与Redis的传统复制模型不符
如果您需要一个可写的分布式数据存储解决方案,您可能需要考虑使用Redis Cluster,它支持多个主节点,并可以在节点之间自动分片数据
7.1.5 用心跳机制提高主从复制的可靠性
在Redis主从复制模式里,如果主从服务器之间有数据同步的情况,那么从服务器会默认以一秒一次的频率向主服务器发送REPLCONF ACK命令,以此来确保二者间连接通畅.这种用定时交互命令来确保连接的机制叫做"心跳"机制.
在主节点上执行INFO replication命令,可以看到从节点的心跳情况:
其中:
此处的lag表示的就是从节点与主节点之间的延迟(单位:秒)
在Redis中,min-slaves-to-write参数用于指定主节点需要多少个从节点(slaves)处于已同步状态(即与主节点的数据差异小于min-slaves-max-lag所指定的秒数),才允许写入操作
参数的详细含义如下:
min-slaves-to-write:这是一个整数值,指定了主节点要求处于已同步状态的从节点数量,才允许执行写入操作.如果已同步的从节点数量少于此值,主节点将拒绝所有的写入命令并返回一个错误min-slaves-max-lag:与min-slaves-to-write配合使用,它定义了一个从节点被认为是已同步的最大延迟值(单位:秒).如果从节点的延迟大于此值,它将被认为是未同步的
这两个参数的目的是在某些场景下增加数据的持久性和可用性.例如,如果你有一个Redis设置,其中数据的可用性和不丢失写入操作是关键要求,那么你可能希望确保至少有一定数量的从节点已经接收和确认了最近的写入,才继续更多的写入
但是,请注意,这些设置可能会增加写入操作的延迟,尤其是在网络不稳定或从节点经常出现延迟的情况下.在配置这些参数之前,你应该仔细考虑其影响,并根据你的具体需求进行测试
在主节点的配置文件中增加配置心跳的参数:
重新启动主节点容器:
7.1.6 用偏移量检查数据是否一致
在主节点中查看偏移量:
其中:
master_repl_offset:表示主节点向从节点发送的字节数
在从节点中查看偏移量:
其中:
slave_repl_offset:表示从节点从主节点中接收到的字节数.若和主节点的master_repl_offset一致,说明主从服务器之间的数据是同步的
在主节点上写入1条数据:
再观察主节点的同步信息:
观察从节点的同步信息:
此时从节点从主节点处读取到的字节数等于主节点向从节点发送的字节数.说明刚刚的写操作同步成功了.若同步出现问题,则可以通过master_repl_offset和slave_repl_offset参数值进行排查
Last updated