1、redis数据备份原理,RDB和AOF。
RDB:redis基于当前自身的所有数据所生成的数据快照,纯粹的数据,若redis从rdb启动,可直接加载使用。
AOF:类似redis日志文件,aof文件内部是redis收到的写命令,若redis从aof启动,需要先读aof文件,然后执行里面的命令,生产数据。
当触发生成rdb时,redis会开启后台线程,生成一份rdb,触发条件可以设置,类似隔多长时间或有多少数据改动时,生成rdb。
aof类似redis日志,可控制写入的频率,如每秒写入,当开启aof时(默认关闭),redis内部维护一个aof文件,实时将redis收到的写命令写入aof中。
aof由于不断地写入,会变得越来越大,当aof大小从0增大到设定的大小时,会触发aof的第一次rewrite操作,redis会将基于当前的数据生成新的aof文件,在此期间,如果redis收到新的写命令,redis会将写命令暂时保存在内存,等新的aof完成后,再将内存中的命令追加到新aof中,当新aof完全完成后(假设大小为n),redis会删除原aof文件。当新的aof文件不断扩大到2n时(默认2倍),会触发rewrite操作。
2、redis主从复制原理,断点续传和过期key处理
主从复制:redis主节点(master)向从节点(slave)复制数据,当集群没有任何问题正常运转时,主节点将收到的如set,del等命令实时复制给从节点,从节点会读命令并生产数据。当slave第一次连接master时,master后台生成一份rdb,并等待一段时间,保证更多的slave接入,然后将rdb发给从节点,slave接到rdb后,首先在本地磁盘上备份,然后载入rdb。在此期间,master会将收到的写命令先存在缓存中,然后发给slave。
断点续传:master和slave内部都会维护一个backlog文件,backlog里面保存一个offset数据,记录复制数据位置。如果slave在工作中断开一段时间又重新连接,会将自身的offset发给master进行对比,如果能在master找到对应的offset,则从offset开始复制,如果没找到,则生成完整的rdb给slave。
过期key处理:master的key倍lru处理掉,会发del命令给slave。
3、redis哨兵底层原理(包括选举算法)
》1、sdown和odown转换机制
sdown和odown两种失败状态
sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机
odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机
sdown达成的条件很简单,如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机
sdown到odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机
。
》2、哨兵集群的自动发现机制
哨兵互相之间的发现,是通过redis的pub/sub系统实现的,每个哨兵都会往__sentinel__:hello这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在
每隔两秒钟,每个哨兵都会往自己监控的某个master+slaves对应的__sentinel__:hello channel里发送一个消息,内容是自己的host、ip和runid还有对这个master的监控配置
每个哨兵也会去监听自己监控的每个master+slaves对应的__sentinel__:hello channel,然后去感知到同样在监听这个master+slaves的其他哨兵的存在
每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步
。
》3、slave配置的自动纠正
哨兵会负责自动纠正slave的一些配置,比如slave如果要成为潜在的master候选人,哨兵会确保slave在复制现有master的数据; 如果slave连接到了一个错误的master上,比如故障转移之后,那么哨兵会确保它们连接到正确的master上。
》4、slave->master选举算法
如果一个master被认为odown了,而且majority哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave来
会考虑slave的一些信息
(1)跟master断开连接的时长
(2)slave优先级
(3)复制offset
(4)run id
如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master
(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
接下来会对slave进行排序
(1)按照slave优先级进行排序,slave priority越低,优先级就越高
(2)如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高
(3)如果上面两个条件都相同,那么选择一个run id比较小的那个slave
》5、quorum和majority
每次一个哨兵要做主备切换,首先需要quorum数量的哨兵认为odown,然后选举出一个哨兵来做切换,这个哨兵还得得到majority哨兵的授权,才能正式执行切换
如果quorum < majority,比如5个哨兵,majority就是3,quorum设置为2,那么就3个哨兵授权就可以执行切换
但是如果quorum >= majority,那么必须quorum数量的哨兵都授权,比如5个哨兵,quorum是5,那么必须5个哨兵都同意授权,才能执行切换
》6、configuration epoch
哨兵会对一套redis master+slave进行监控,有相应的监控的配置
执行切换的那个哨兵,会从要切换到的新master(salve->master)那里得到一个configuration epoch,这就是一个version号,每次切换的version号都必须是唯一的
如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待failover-timeout时间,然后接替继续执行切换,此时会重新获取一个新的configuration epoch,作为新的version号
》7、configuraiton传播
哨兵完成切换之后,会在自己本地更新生成最新的master配置,然后同步给其他的哨兵,就是通过之前说的pub/sub消息机制
这里之前的version号就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次新的切换之后,新的master配置是跟着新的version号的
其他的哨兵都是根据版本号的大小来更新自己的master配置的
。
4、数据分布算法,hash,一致性hash算法,hash slot
一致性hash算法要解决的问题:在多master集群中,所有数据需要按照给定的规则存在固定的master中,保证要查找的时候能知道在哪个master的从节点上。
最原始hash算法:对key计算hashcode值,对master个数取余数,得到master位置,类似hashmap。但是hashmap可以这么做,因为hashmap不存在某个entry宕机的情况。这种做法如果某个master宕机,那么取数据就会出错。例如,有三个master,第二个master宕机,那么第二个master的数据全丢失,而且master个数变成2,取数据时要除的数字变成2,存的时候除的数字是3,这样肯定不能找到正确的master。
一致性hash算法:一致性hash算法引入和hash环的概念,所有的master均匀分布在一个长度为(2^32-1)的圆环上,所有的K/V存储时,都是将key的hashcode%(圆环长度),这个数字对应环上的位置顺时针移动,打到哪个master,就存到其中。可以避免某一台master宕机导致整个集群不可用。
hash slot:redis集群固定持有16384个hash slot(虚拟节点),K/V存储时,对K的取CRC16%16384,找到对应的hash slot,存储在hash slot上,集群中每个master持有一部分hash slot,当某个master宕机,master上的hash slot会迅速转移到其他master上,减小数据损失,而hash slot转移的消耗是极低的。在读取数据时,真正寻找的,是hash slot,与hash slot在哪个maste上无关,所以即便是master宕机了,上面的数据也不会全部消失,而且剩余数据还能正常工作。
来源:https://www.cnblogs.com/VanVanilla/p/9881364.html