数据复制搓个副本部署到其他机器,满足故障恢复和负载均衡等需求,是Redis高可用的基础。
1. 配置
1.1 建立复制
每个从节点slave只能有一个主节点master,而主节点可以同时具有多个从节点。
slaveof命令可以运行期动态配置,也可以提前写到配置文件。
1.2 断开复制
流程:
- 断开与主节点复制关系
- 从节点晋升为主节点(注意不会抛弃原有数据)
切主操作:会删除从节点当前所有数据,对新主节点进行复制操作。
1.3 安全性
对于数据重要的节点,主节点通过设置requirepass参数进行密码验证。
1.4 只读
默认情况,从节点使用slave-read-only=yes配置为只读,所以不能修改从节点。
1.5 传输延迟
通过repl-disable-tcp-nodelay参数控制是否关闭TCP_NODELAY
- 关闭时,主节点命令数据及时发送,延迟小,带宽消耗高
- 开启时,合并较小的TCP数据包从而节省带宽,默认发送时间间隔40ms
2. 拓扑
- 一主一从结构:主节点不开启AOF
- 一主多从结构(星形拓扑):多个从节点,读写分离
- 树状主从结构:从节点还可以作为主节点继续向下层复制。引入复制中间层,降低主节点负载和传输数据量,当主节点需要挂载多个从节点避免性能干扰时使用
3. 原理
3.1 复制过程
主从节点建立复制流程.jpg3.2 数据同步
- 全量复制:初次复制场景
- 部分复制:因网络闪断等造成的数据丢失,补发丢失数据
-
复制偏移量
参与复制的主从节点都会维护自身复制偏移量,通过对比主从节点的赋值偏移量判断数据是否一致 -
复制积压缓冲区
复制积压缓冲区是保存在主节点上的一个固定长度1MB队列,当建立复制关系时,主节点响应写命令,不但会把命令发送给从节点,还会写入复制积压缓冲区,保存最近已复制数据,用于部分复制和复制命令丢失的数据补救。
复制积压缓冲区.jpg -
主节点运行ID:40位十六进制字符串作为运行ID,唯一识别Redis节点。ip+port方式识别是不对的。
-
psync:从节点使用psync命令完成部分复制和全量复制功能
psync运行流程.jpg
3.3 全量复制
redis2.8版本之前,都是sync,后来才是psync
流程如下:
全量复制流程.jpg
几个注意点:
- 主节点是通过bgsave保存RDB文件到本地,然后发送RDB给从节点
- Redis支持无盘复制,生成的RDB文件不保存到硬盘直接通过网络发送,降低主节点磁盘开销
- 从节点开始接收RDB快照期间,主节点的命令会写入缓冲区,最后发送给从节点,保证主从一致
- 从节点接收完全部数据后会清空自身旧数据,然后加载RDB
3.4 部分复制
部分复制使用psync {runId} {offset} 命令实现
部分复制过程.jpg
3.5 心跳
主从节点建立复制后,之间维护长连接并彼此发送心跳命令。
- 主节点默认10秒对从节点发送ping
- 从节点在主线程中每隔1秒发送replconf ack {offset}命令,上报当前的复制偏移量
3.6 异步复制
主节点写命令发送给从节点的过程是异步完成的,没有等待。
4. 开发与运维中的问题
基于复制的应用场景,数据集存在多个副本。
4.1 读写分离
可能问题:
- 复制数据延迟:异步复制特性导致无法避免的,无法容忍大量延迟的话,需要外部监控程序监听主从节点的复制偏移量
- 读到过期数据:惰性删除,主节点每次读的时候检查超时后del命令同步给从节点;定时删除:主节点内部定时任务循环检查键超时
- 从节点故障问题:客户端维护可用从节点列表,及时切换。
4.2 主从配置不一致
主节点关闭AOF,从节点开启,OK
内存配置肯定要一致,压缩列表参数也要一致
4.3 规避全量复制
- 第一次建立复制
- 节点运行ID不匹配,主节点故障重启后,运行ID会改变,应当故障转移避免从节点全量复制新的主节点,比如手动提升从节点为主节点
- 复制积压缓冲区不足,大流量场景需要增大缓冲区
4.4 规避复制风暴
复制风暴是指大量从节点对同一主节点或者同一台机器的多个主节点短时间内发起全量复制的过程
- 单主节点复制风暴,不会创建多个筷子,但是同时向多个从几点发送快照会导致网络带宽消耗严重,可以通过树状结构来解决
- 单机器复制风暴:避免在单台机器上部署过多的主节点,提供故障转移机制
网友评论