Redis主从复制、读写分离、哨兵机制
Redis 主从库读写分离
- 读:主库、从库均可
- 写:写入主库,然后主库同步给从库
1. 主从库数据全量同步
- 实例1:192.168.1.101
- 实例2:192.168.1.102
假如实例1为主库,实例2为从库,则在实例2上执行 replicaof 命令:
replicaof 192.168.1.101 6379
这样实例2就变成了实例1的从库
在 redis.conf 配置文件中,要修改的地方
# 主库 ip 和端口
replicaof <masterip> <masterport>
# 主库密码
masterauth <master-password>
# 设置从库只读
replica-read-only yes
第一次同步的三个阶段
-
建立连接后,从库会给主库发送命令:PSYNC ? -1
psync 命令包含两个参数:runID 和 offset
- runID: 每个实例启动时自动生成的一个随机 ID,第一次复制时,从库不知道主库的 runID,所以将参数值设置为 ?
- offset: -1,表示第一次复制
主库接收到命令后,会使用 FULLRESYNC [runID] [offset] 进行回应,FULLRESYNC命令表示第一次是全量复制,runID 就是主库的id,offset就是主库目前的复制进度。
部分重新同步命令 ParticalReSync
-
数据同步
主库执行 bgsave 命令生成 RDB 文件,然后将文件发送给从库;
从库接收到文件后,清空当前数据库,再执行加载 RDB 文件;
-
主库发送新命令给从库
在主库生成 RDB 文件期间,主库没有阻塞仍然是可以正常处理数据的,这期间新写入或改动的数据,主库会保存到 replication buffer 中,等RDB 文件发送给从库后,再把 replication buffer 中的操作发给从库,让从库执行,这样就完成了主从库的同步。
主 - 从 - 从 级联模式
当有很多实例要组成集群时,如果从库数量很多,从库都从同一个主库进行数据的全量同步时,这样会导致主库 fork 子进程生成 RDB 文件阻塞主线程,影响主库��理正常的请求。
“主 - 从 - 从” 模式的意思就是说不要所有的从库都和主库进行连接,可以让部分的从库和从库进行连接,分散主库同步的压力。
2. 主从库数据增量同步
主从库断连后,主库会把这期间接收到的写操作命令,写入 replication buffer 和 repl_backlog_buffer
repl_backlog_buffer 是一个环形缓冲区,如下图所示:
当主从库恢复连接后,从库就会发送 PSYNC 命令给主库,其中 offset 参数的值就是当前从库已经读取到位置的偏移量
主库接收到命令后,会把传递过来的偏移量和自己已经写到位置的偏移量进行比较,这时只要把中间差距部分的数据同步给从库即可。
因为 repl_backlog_buffer 是一个环形缓冲区,所以如果从库的读速度赶不上主库的写速度,可能会导致从库没有读取到的数据被主库的写操作给覆盖掉。
要避免该情况,可以调整 repl_backlog_size 参数的大小,该参数调整的是缓冲空间的大小
计算公式如下:
缓冲空间大小 = (主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小)*2
Redis 哨兵机制
哨兵间的通信
通过 pub/sub 机制:在主库上有一个名为 sentinel:hello 的频道,哨兵间就是通过该频道来互相发现、通信的;
哨兵将自己的 IP 和端口 发送到该频道,订阅了该频道的其它哨兵就能获取到它的 IP 和端口号;
哨兵给主库发送 INFO 命令,主库就会把从库列表信息返回给哨兵,这样哨兵就能和从库进行连接;
哨兵的3个任务:监控、选主、通知。
1. 监控主库是否下线
-
主观下线:其中某个哨兵监测到主库没有响应,单方面判断为主观下线;
-
客观下线:当有哨兵判断主库主观下线了,需要给其它哨兵发送 is-master-down-by-addr 命令,其它哨兵会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票,当得票数大于等于配置文件中的 quorum 配置项设定的值时,则标记主库为客观下线状态。
2. 选择新主库
-
先筛选
- 检查从库的当前在线状态
- 判断从库之前的网络连接状态
-
后打分
-
优先级高的得分高;
可以通过 slave-priority 配置实例的优先级
-
与旧主库同步程度最接近的从库得分高;
-
实例 ID 号小的从库得分高;
筛选出符合条件的实例后,按以上顺序来打分,如果第一项就选出来最高分的,则不用进行后面的打分了。
-
-
哨兵Leader选举
在第一步中,如果已经确定主库客观下线后,则哨兵可以继续发送命令,想要由自己来进行主从切换,这时还需要其它哨兵进行投票;
如果该哨兵希望成为Leader,需要满足以下两个条件: 1. 拿到半数以上赞成票 2. 拿到的票数需要大于等于哨兵配置文件中的 quorum 值
如果该轮投票没有产生Leader,集群会等待一段时间再重新进行选举。
3. 通知从库和客户端
同样也是基于 pub/sub 机制通知客户端
4. 哨兵集群注意事项
- 如果哨兵集群只有 2 个实例,此时,一个哨兵要想成为 Leader,必须获得 2 票,而不是 1 票。所以如果有个哨兵挂掉了,那么此时的集群是无法进行主从库切换的。因此,通常我们至少会配置 3 个哨兵实例;
- 要保证所有哨兵实例的配置是一致的。
转载自:https://juejin.cn/post/7390670212726276123