一、目录
Redis内存回收策略
主从+哨兵模式核心知识点
注:Redis主从+sentinel哨兵集群部署:参考
二、关于Redis内存回收策略
Redis会因为内存不足而产生错误,也会因为回收过久而导致系统长期处于卡顿状态。当Redis的内存达到规定的最大值时,可以进行配置淘汰key, 并对key进行回收。
redis八大回收机制:
noeviction[默认策略]
不淘汰任何键值对, 当内存满时,读操作(例如:get命令) 它将政策工作,而做写操作,它将返回错误。所以,当内存满时,redis就不能写了
volatile-lru: 采用最近最少的淘汰策略, Redis将回收那些超时的(仅仅是超时的)键值对。
allkeys-lru: 采用最近最少的淘汰策略,Redis将对所有的(不仅仅是超时的)键值对采用最近最少使用的淘汰策略
volatile-lfu: 采用最近最不常用的淘汰策略,也就是在一定时间内,被访问次数最少的(已超时)键值对将被回收。
allkeys-lfu: 采用最近最不常用的淘汰策略,Redis将对所有的键值对采用最近最不常用的淘汰策略。
volatile-random:采用随机淘汰策略删除超时的键值对。
allkeys-random:采用随机淘汰策略删除所有的键值对,这个策略不常用。
volatile-ttl:采用删除存活时间最短的键值对策略。
注:LRU算法或者TTL算法都是不精确的算法,而是一个近似算法。
动态设置回收策略
1 | config set maxmemory 768mb #最大限制内存 |
三、主从+哨兵模式核心知识点
1. 关于哨兵的介绍
sentinel, 中文:哨兵,哨兵是redis重要的一个组件,具有以下功能
集群监控: 负责监控redis master和slave进程是否正常工作
消息通知: 如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
故障转移:如果master node挂掉了,master功能会自动转移到slave node上
配置中心:如果故障转移发生了,通知client客户端新的master地址
哨兵用于实现redis集群高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。
故障转移时,判断一个master node是否宕机了,需要大部分的哨兵同意才行,涉及到了分布式选举的问题。
即使部分哨兵节点挂掉了,哨兵集群还是可以正常工作的。
2. 哨兵的核心知识
哨兵至少需要3个实例来保证自己的健壮性。
哨兵+redis主从的部署架构,是不保证数据零丢失的,只能保证redis集群的高可用性
哨兵sentinel主备切换导致的数据丢失问题
3. 两种情况导致的数据丢失:
- 异步复制过程中导致的数据丢失
因为master –> slave的同步是异步的,所以有可能有部分数据还没复制到slave,master就down机了,此时这部分数据就丢失了。
- 脑裂导致的数据丢失
脑裂,也就是说某个master所在的机器突然脱离了网络,跟其他slave不能正常通信,但是实际上Master还运行着。此时哨兵会认为master已经宕机了,然后开始重新选举,将其他slave切换成了master。这个时候集群里出现了2个master。
如果某个slave被哨兵选举切换成了master,但是可能client还没来得及切换到新master,还会继续向旧master写数据。因此,旧master再次恢复的时候,会被作为一个slave挂到新的master上去,而自己的数据会被清空,重新从新的master复制数据。而新的master并没有后来client写入的数据,因此,这部分数据就丢失了
数据丢失问题解决方案:
1 | control data loss |
减少异步复制数据丢失
min-slaves-max-lag这个参数,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求。从而把数据丢失降低到可控范围
减少脑裂的数据丢失
如果一个master出现了脑裂,跟其他slave断开了连接,如果不能给指定数量的slave发送数据,那么如果slave超过10秒没有给自己发送ack消息,则直接拒绝客户端的写请求。因此在脑裂环境下,最多就丢失10秒的数据。
3. 关于sdown和odown转换机制
哨兵如何去判断master是否宕机?
- sdown是主观宕机,就一个哨兵如果自己觉得master宕机了,那么就是主观宕机
- odown是客观宕机,如果quorum数量的哨兵都认为一个master宕机了,那么就是客观宕机。
sdown达成条件很简单,如果一个哨兵ping一个master, 超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机了;
如果一个哨兵在指定的时间内,收到了quorum数量的其他哨兵也认为那个master是sdown的状态,那么就认为是odown
4. 哨兵集群的自动发现机制
哨兵互相之间的发现,是通过 redis 的 pub/sub
系统实现的,每个哨兵都会往 __sentinel__:hello
这个 channel 里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在。
每隔两秒钟,每个哨兵都会往自己监控的某个 master+slaves 对应的 __sentinel__:hello
channel 里发送一个消息,内容是自己的 host、ip 和 runid 还有对这个 master 的监控配置。
每个哨兵也会去监听自己监控的每个 master+slaves 对应的 __sentinel__:hello
channel,然后去感知到同样在监听这个 master+slaves 的其他哨兵的存在。
每个哨兵还会跟其他哨兵交换对 master
的监控配置,互相进行监控配置的同步。
5. Slave配置的自动纠正
哨兵会负责自动纠正 slave 的一些配置,比如 slave 如果要成为潜在的 master 候选人,哨兵会确保 slave 复制现有 master 的数据;如果 slave 连接到了一个错误的 master 上,比如故障转移之后,那么哨兵会确保它们连接到正确的 master 上。
6. Slave —> Master选举算法
如果一个 master 被认为 odown 了,而且 majority 数量的哨兵都允许主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个 slave 来,会考虑 slave 的一些信息:
- 跟 master 断开连接的时长
- slave 优先级
- 复制 offset
- run id
如果一个 slave 跟 master 断开连接的时间已经超过了 down-after-milliseconds
的 10 倍,外加 master 宕机的时长,那么 slave 就被认为不适合选举为 master。
1 | (down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state |
接下来会对 slave 进行排序:
- 按照 slave 优先级进行排序,slave priority 越低,优先级就越高。
- 如果 slave priority 相同,那么看 replica offset,哪个 slave 复制了越多的数据,offset 越靠后,优先级就越高。
- 如果上面两个条件都相同,那么选择一个 run id 比较小的那个 slave。
7. quorum和majority
每次一个哨兵要做主备切换,首先需要 quorum 数量的哨兵认为 odown,然后选举出一个哨兵来做切换,这个哨兵还需要得到 majority 哨兵的授权,才能正式执行切换。
如果 quorum < majority,比如 5 个哨兵,majority 就是 3,quorum 设置为 2,那么就 3 个哨兵授权就可以执行切换。
但是如果 quorum >= majority,那么必须 quorum 数量的哨兵都授权,比如 5 个哨兵,quorum 是 5,那么必须 5 个哨兵都同意授权,才能执行切换。
8. configuration epoch
哨兵会对一套 redis master+slaves 进行监控,有相应的监控的配置。
执行切换的那个哨兵,会从要切换到的新 master(salve->master)那里得到一个 configuration epoch,这就是一个 version 号,每次切换的 version 号都必须是唯一的。
如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待 failover-timeout 时间,然后接替继续执行切换,此时会重新获取一个新的 configuration epoch,作为新的 version 号。
9. configuration传播
哨兵完成切换之后,会在自己本地更新生成最新的 master 配置,然后同步给其他的哨兵,就是通过之前说的 pub/sub
消息机制。
这里之前的 version 号就很重要了,因为各种消息都是通过一个 channel 去发布和监听的,所以一个哨兵完成一次新的切换之后,新的 master 配置是跟着新的 version 号的。其他的哨兵都是根据版本号的大小来更新自己的 master 配置的。
- 本文作者: GaryWu
- 本文链接: https://garywu520.github.io/2019/09/19/Redis主从-sentinel哨兵-理论/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!