当启动一个salve node时会发送PSYNC 命令到master。 salve第一次连接master时master会根据当前数据复制一份RDB(full resynchronization 全量复制)到slave,slave会将本地数据写入磁盘,然后从本地磁盘加载到内存中,master会将内存中的数据发送给slave,slave会同步这些数据。如果master与slave发生故障master,会自动重连
概念:主从复制过程中如果网络断掉了,可以从上次复制的地方继续复制而不是从头复制
原理:master会在自己内存里维护一个backlog,master和salve都会保存一个复制数据的replica offset ,offset里有一个master的id,offset保存在backlog中,如果网络断掉的话,salve会从master 的offset开始复制
(1).maste和slave都会维护offset
master和slave都会不断累加offsetslave会每秒上传自己的offset,master也会保存每一个slave的offsetslave和master都知道各自的offset,才知道各自数据不一致的情况(2).backlog
master node有一个backlog默认是1MB,master node给slave复制数据时也会给把backlog同步一份,backlog主要用来做全量复制中断的时增量复制的(3).master run id info server 可以看到master run id 根据host+ip定位到master node是不靠谱的,如果master node重启或数据发生变化,那么slave node 会根据不同的run id进行分区,run id不同做全量复制,如果不更改run id 重启redis 则可以用 redis-cli debug reload
(4).psync
从节点使用psync到maser node,进行复制,psync run idmaster node根据自身情况进行响应,可能是FULLRESTYNC run id offset,也可能是CONTINUE触发增量复制(5)全量复制
master 执行BGSAVE,在本地生成RDB快照master node会将RDB快照文件发送给slave node,如果RDB再复制过程中时间超过60s(repl-timeout),slave-node会认为复制失败,可以适当调大复制时间参数(repl-timeout) 3.对于千兆网卡的机器来说1s传输100MB,6G时间可能超过60smaster node生成RDB时,会将所有的命令缓存到内存中,在slave node保存rdb后,再将新的命令复制到slave node中client-output-buffer-limit slave 256MB 64MB 60,如果再复制期间内存缓冲区消耗超过64MB,或一次性超过256MB则复制失败slave node在接收到rdb后会清空自己的旧数据,然后重新加载rdb到自己内存中,同时基于旧的数据提供服务 7.如果slave node开启了AOF会立即执行BGRERITEAOF,重写AOF如果复制数据在4-6G之间,很可能全量复制的时间在1.5-2分钟
(6)增量复制
如果在全量复制的过程中master-slave网络断掉,salve node在重新连接master node时会触发增量复制master 直接从backlog获取部分丢失数据,发送给slave node,默认backlog是1MBmaster会根据slave发送的psync中的offset获取数据(7)heartbeat
主从节点相互发送heartbeat信息master每隔10s发送一次heartbeat信息,slave每隔1s发送一次heartbeat信息(8)异步复制 master接收到命令后在内部写入,异步发送给slave node
(1)定期删除+惰性删除
每个100ms检查key是否过期如果过期则删除惰性删除可能会导致很多过期的key没有被删除,如果查询时到某个key过期则删除(2)redis内存淘汰策略
noeviction:当内存不足以容纳新的数据时,写入操作就会报错allkeys-lru:当内存不足以容纳新的数据时,就会淘汰最近最少使用的keyallkeys-random:当内存不足以容纳新的数据时,就会随机删除keyvolatile-lru:当内存不足以容纳新的数据时,在过期key删除中删除最近最少使用的volatile-ttl:当内存数据不足以容纳新的数据时,删除那些即将过期的key哨兵和slave的自动发现机制 哨兵之间相互发现通过pub/sub系统实现,每个两秒钟哨兵都会监控自己的master+slaves对应的_sentinel_:hello channel发送消息,内容主要是hos、IP、run id还有master对应的监控配置,感知同样监听master+slaves哨兵的存在,哨兵间还会交换master监控配置,实现监控配置的同步
slave配置的自动纠正 哨兵模式会负责纠正slave的一些配置,比如slave要成为master的潜在候选人,哨兵会确保slave会复制master现有的数据,如果slave连接到一个错误的master上故障转移后哨兵会保证它连接到正确的master上
slave->master选举算法
如果master被认为是odown而且majoitry哨兵都允许主备切换,此时哨兵就会执行主备切换,选举slave需要考虑的信息
跟master断开连接的时长slave优先级复制offsetrun id如果一个slave与master断开时长超过down-after-milliseconds的10倍,外加master宕机时长此时就会认为不适合选举为master (down-after-milliseconds *10)+milliseconds_since_master_is_in_sdown
接下来会对slave进行排序
按照slave优先级进行排序,slave priority越小优先级越高如果两个slave priority相同,则查看那个offset复制数据多,offset越靠后优先级越高如果上面两个条件都相同那就查看那个run id比较小quorum和majority 每次主备切换,首先确认quorum数量的odown,然后选举出一个哨兵进行切换,这个哨兵还必须得到majority哨兵的授权,才能被正式授权 如果quorum<majority比如5个哨兵,majority是3,quorum的数量是2,那么3哨兵授权就可以切换 但如果quorum>=majority,那么必须所有的quorum都必须授权,比如 quorum是5必须5个哨兵都授权才能切换
configuration epoch 执行切换的哨兵,要切换到新的master需要得到一个configuration epoch这就是一个版本号,每次版本号必须唯一 如果第一个哨兵切换失败,那么其他哨兵会等待faliover-timeout时间,然后继续执行切换获得一个新的configuration epoch,作为新的版本号
configuration传播 哨兵切换完成后会将本地跟新为最新的master配置,然后pub/sub机制同步给其他哨兵 这里之前的version就很重要,因为消息都是通过一个channel发布监听,完成主备切换后新的master跟着新的version,其他哨兵也跟着version大小更新自己的master