持久化
-
RDB 快照
触发持久化的条件
1.save bgsave
2.配置 save m n
3.主从复制 从库全量复制,主库执行
4.flushall 清库
5.shutdown 关闭库
-
bgsave 执行过程
主进程fork子进程,此时主进程阻塞,fork完子进程后,主进程继续接收客户端命令,子进程根据内存副本进行快照, 快照完成后通知主进程跟新快照信息。
- AOF持久化
redis 通过redis协议将每一次的命令写入aof_buf缓冲区 ,根据appendaof参数确定是否调用fsync和时间间隔,来刷新磁盘。
- bgrewriteaof重写
重写触发条件
手动触发:bgrewriteaof 自动触发:auto-aof-rewrite-min-size: 重写的最小大小 auto-aof-rewrite-percentage:增长百分比
aof_rewrite_buf重写缓冲区,用于接收aof重写期间主进程接收的命令。
主从复制方案
一主多从 链式主从
初始复制阶段:主从建立socket连接 验证密码
数据同步阶段:从库向主库发送psync命令,主库开始向从库同步数据
命令传播阶段:主从维持心跳,从节点每隔一秒向主节点发送REPLCONF ACK {offset}命令,主节点根据偏移量发送未同步命令
sync 断线重连后依旧需要全量复制
psync1 主从都维护一个偏移量 复制积压缓冲区,存储每个字节得偏移量 ,runnid -从库重启之后runnid会发生变化
psync2 解决从库重启后可以部分复制,将复制信息保存再RDB文件中 当从库开启了AOF持久化,redis加载顺序发生变化优先加载AOF文件,但是由于aof文件中没有复制信息,所以导致重启后从实例依旧使用全量复制!
Sentinel哨兵
-
主观下线 SDOWN:单个sentinel对redis实例做出了下线判断,sentinel向redis实例发送了ping心跳后,一段时间内没有收到合法回复,就做出主观下线的判断。
-
客观下线 ODOWN:多个sentinel实例对同一个redis实例做出SDOWN判断,并通过SENTINEL is-master-down-by-addr 命令互相交流之后,得出的redis实例下线判断。
从SDOWN切换到ODOWN不需要任何一致性算法,只需要一个gossip协议:如果一个sentinel收到了足够多的sentinel发来消息告诉它某个master已经down掉了, SDOWN状态就会变成ODOWN状态。如果之后master可用了,这个状态就会相应地被清理掉。
真正进行failover需要一个授权的过程,这个授权的过程即是leader选取过程,但是所有的failover都开始于一个ODOWN状态。ODOWN状态只适用于master, 对于不是master的redis节点sentinel之间不需要任何协商,slaves和sentinel不会有ODOWN状态。
-
故障切换过程
sentinel和主库建立两条连接,一条用于监控redis实例,另一条用于获取监控这个redis实例的其他sentinel。
1.sentinel主库发送info命令,获取主库的信息(主库id,复制信息,从库信息),而后和从库建立同样的两条连接监控从库。
2.哨兵间进行信息的分享
3.哨兵向redis实例和sentinel发送ping命令,超时没有回复,则认为主观下线。如果redis实例是master,进一步判断是否需要故障恢复,sentinel向其他sentinel节点发送命令询问是否认为该库主观下线,如果是,则选取领头哨兵进行故障恢复。
4.领头哨兵的选举会考虑以下情况
- 和master断开的时常,超过down-after-milliseconds的10倍+master的宕机时常则不合适。
- savle的优先级,优先级一样,选择复制偏移量靠后的。
- 都相同,选runid小的。
选出从库后,零头哨兵将向从数据库发送saveof no one 命令升级其为新的主库,然后在向其他从库发送saveof命令将从的主库升级到最新的主库,最后更新内部记录将已经停止的主库更新为新的主库的从库,使得当该故障的主库再次恢复时候自动以从库角色继续提供服务,从启动到故障恢复完成这一些列过程即是哨兵的工作的完整流程也是其原理所在。
-
领头哨兵选举
1.发现master挂掉的sentinel A,向每个哨兵节点发送命令要求选择自己为leader。
2.如果哨兵没有选过其他节点,则同意将A选为leader。
3.如果有超过半数且超过quorum参数的节点同意选A为leader,那么A则成功当选。
4.当有多个节点参加选举,并且当选leader,则在下个随机时间进行新一轮选举,直到有一个节点当选。
Redis Cluster
Redis Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。节点之间使用gossip协议传播信息以及发现新节点。