主从复制是如何工作的
一个从服务器,在连接时它发送了一个SYNC命令,不管它是第一次连接还是再次连接都没有关系。然后主服务器开始后台存储,并且开始缓存新连接进来的修改数据的命令。当后台存储完成后,主服务器把数据文件发送到从服务器,从服务器将其保存在磁盘上,然后加载到内存中。然后主服务器把刚才缓存的命令发送到从服务器。这是作为命令流来完成的,并且和Redis协议本身格式相同
主从复制开启
默认情况下,Redis都是主节点。每个从节点只能有一个主节点,而主节点可以同时具有多个从节点。
- 在配置文件中加入slaveof {masterHost} {masterPort}随Redis启动生效
- 在redis-server启动命令后加入--slaveof {masterHost} {masterPort}生效
- 直接使用命令:slaveof {masterHost} {masterPort}生效
主从复制断开
断开复制后并不会抛弃原有数据,只是无法再获取主节点上的数据变化。
切主操作流程如下:
1)断开与旧主节点复制关系。
2)与新主节点建立复制关系。
3)删除从节点当前所有数据。
4)对新主节点进行复制操作。
- 执行slaveof no one命令断开与master的连接
- 执行slaveof{newMasterIp} {newMasterPort}命切换到其他的master
主从复制方式
- 全量复制:一般用于初次复制场景,Redis早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。
- 部分复制:用于处理在主从复制中因网络闪断等原因造成的数据丢失 场景,当从节点再次连上主节点后,如果条件允许,主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销。
主从复制安全
主节点可以设置密码校验,此时从节点需要配置masterauth参数与主节点密码保持一致,配置在redis.conf中。并且客户端访问必须使用auth命令实行校验。
- 主节点配置
requirepass 123456
- 从节点配置
slaveof <masterip> <masterport>
masterauth 123456
主从复制-主节点宕机
主从复制-节点配置命令
- slaveof <masterip> <masterport>
从节点配置主节点的IP、端口 - masterauth <master-password>
如果主节点配置requirepass,则从节点需配置此项 - slave-serve-stale-data yes
从节点与主节点断开连接或正进行主从复制,从节点有两种模式。
yes 表示从服务器可以响应客户端请求
no 表示响应客户端“"SYNC with master in progress"”信息但除INFO、SLAVEOF命令 - slave-read-only yes
开启从节点只读模式 - repl-diskless-sync no
复制过程需要主节点将内存的数据写到硬盘中,再将数据从硬盘读进内存,再发送给slave。Redis2.8版本开始,实验性地加上了无硬盘复制的功能。这个功能能将数据从内存中直接发送到slave,而不用经过硬盘的存储。功能默认关系 - repl-diskless-sync-delay 5
主节点开启无硬盘复制后,其等待多个slave一起来请求之间的时间间隔 - repl-ping-slave-period 10
主节点默认每隔10秒对从节点发送ping命令,判断从节点的存活性和连接状态。 - repl-timeout 60
通过使用info replication命令,查看统计中的lag信息。lag表示与从节点最后一次通信延迟的秒数。如果超过repl-timeout配置的值(默认60秒)
判定从节点下线并断开复制客户端连接。主节点判定从节点下线后,如果从节点重新恢复,心跳检测会继续进行。 - repl-disable-tcp-nodelay no
用于控制是否关闭 TCP_NODELAY,默认关闭,说明如下:
当关闭时,主节点产生的命令数据无论大小都会及时地发送给从节点,这样主从之间延迟会变小,但增加了网络带宽的消耗。适用于主从之间的网络环境良好的场景,如同机架或同机房部署。 ·
当开启时,主节点会合并较小的TCP数据包从而节省带宽。默认发送时间间隔取决于Linux的内核,一般默认为40毫秒。这种配置节省了带宽但增大主从之间的延迟。适用于主从网络环境复杂或带宽紧张的场景,如跨机房部署。 - repl-backlog-size 1mb
- repl-backlog-ttl 3600
复制积压缓冲区大小和复制积压缓冲区存活时间,作用为当主从节点网络中断后,从节点再次连上主节 点时会发送psync{offset}{runId}命令请求部分复制,如果请求的偏移量不在主节点的积压缓冲区内,则无法提供给从节点数据,因此部分复制会退化为 全量复制。 - slave-priority 100
sentinel模块,权重值最小的slave将被提升为master。如果为0则不参与master选举 - min-slaves-to-write 3
- min-slaves-max-lag 10
从redis2.8版本开始,master可以被配置为,只有master当前有至少N个slave连接着的时候才接受写数据的请求。
这个机制的工作原理如下所示:
slave每秒发送ping心跳给master,询问当前复制了多少数据。
master会记录下它上次收到某个slave的ping心跳是什么时候。
使用者可以配置一个时间,来指定ping心跳的发送不应超过的一个超时时间。如果master有至少N个slave,并且ping心跳的超时不超过M秒,那么它就会接收写请求。
主从环境问题
-
数据延迟
Redis复制数据的延迟由于异步复制特性是无法避免的,延迟取决于网络带宽和命令阻塞情况。 -
读到过期数据
当主节点存储大量设置超时的数据时,如缓存数据,Redis内部需要维护过期数据删除策略,删除策略主要有两种:惰性删除和定时删除
1)惰性删除:主节点每次处理读取命令时,都会检查键是否超时,如果超时则执行del命令删除键对象,之后del命令也会异步发送给从节点。
2)定时删除:Redis主节点在内部定时任务会循环采样一定数量的键,当发现采样的键过期时执行del命令,之后再同步给从节点。 -
全量复制
1)第一次建立复制:由于是第一次建立复制,从节点不包含任何主节点数据,因此必须进行全量复制才能完成数据同步。对于这种情况全量复制无法避免。当对数据量较大且流量较高的主节点添加从节点时,建议在低峰时进行操作,或者尽量规避使用大数据量的Redis节点。
2)节点运行ID不匹配:当主从复制关系建立后,从节点会保存主节点的运行ID,如果此时主节点因故障重启,那么它的运行ID会改变,从节点发现主节点运行ID不匹配时,会认为自己复制的是一个新的主节点从而进行全量复制。对于这种情况应该从架构上规避,比如提供故障转移功能。当主节点发生故障后,手动提升从节点为主节点或者采用支持自动故障转移的哨兵或集群方案。
3)复制积压缓冲区不足:当主从节点网络中断后,从节点再次连上主节点时会发送psync{offset}{runId}命令请求部分复制,如果请求的偏移量不在主节点的积压缓冲区内,则无法提供给从节点数据,因此部分复制会退化为全量复制。针对这种情况需要根据网络中断时长,写命令数据量分析出合理的积压缓冲区大小。 -
复制风暴
1)单主节点复制风暴单主节点复制风暴一般发生在主节点挂载多个从节点的场景。当主节点重启恢复后,从节点会发起全量复制流程,这时主节点就会为从节点创建RDB快照,如果在快照创建完毕之前,有多个从节点都尝试与主节点进行全量同步,那么其他从节点将共享这份RDB快照。这点Redis做了优化,有效避免了创建多个快照。但是同时向多个从节点发送RDB快照,可能使主节点的网络带宽消耗严重,造成主节点的延迟变大,极端情况会发生主从节点连接断开,导致复制失败。 解决方案首先可以减少主节点(master)挂载从节点(slave)的数量, 或者采用树状复制结构,加入中间层从节点用来保护主节点。
2)由于Redis的单线程架构,通常单台机器会部署多个Redis实例。当一台机器(machine)上同时部署多个主节点(master)时,如果这台机器出现故障或网络长时间中断。当它重启恢复后,会有大量从节点(slave)针对这台机器的主节点进行全量复制,会造成当前机器网络带宽耗尽。解决方案第一点应该把主节点尽量分散在多台机器上,避免在单台机器上部署过多的主节点。第二点当主节点所在机器故障后提供故障转移机制,避免机器恢复后进行密集的全量复制。
搭建主从复制环境
-
服务器
192.168.6.128(slave)
192.168.6.129(master)
192.168.6.130(slave)- 129master节点设置
requirepass 123456
- 128/130slave节点设置
slaveof 192.168.6.129 6379
masterauth 123456
其他相关命令信息,可自行根据需求开启。
官网链接
Redis主从复制之repl_backlog
《redis开发与运维》
网友评论