11-Redis的高可用
01、Redis自带主从复制配置
【1】主从复制原理
1、连接阶段
- slavenode启动时(执行slaveof命令),会在自己本地保存masternode的信息,包括masternode的host和ip。
- slavenode内部有个定时任务replicationCron(源码replication.c),每隔1秒钟检查是否有新的masternode要连接和复制,如果发现,就跟masternode建立socket网络连接,如果连接成功,从节点为该socket建立一个专门处理复制工作的文件事件处理器,负责后续的复制工作,如接收RDB文件、接收命令传播等。
- 当从节点变成了主节点的一个客户端之后,会给主节点发送ping请求。
2、数据同步阶段
master node第一次执行全量复制,通过bgsave命令在本地生成一份RDB快照,将RDB快照文件发给slavenode(如果超时会重连,可以调大repl-timeout的值)。slavenode首先清除自己的旧数据,然后用RDB文件加载数据。
生成RDB期间,master接收到的命令怎么处理?
开始生成RDB文件时,master会把所有新的写命令缓存在内存中。在slave node保存了RDB之后,再将新的写命令复制给slavenode。
3、命令传播阶段
masternode持续将写命令,异步复制给slave node。
延迟是不可避免的,只能通过优化网络。
当设置为yes时,TCP会对包进行合并从而减少带宽,但是发送的频率会降低,从节点数据延迟增加,一致性变差;具体发送频率与Linux内核的配置有关,默认配置为40ms。当设置为no时,TCP会立马将主节点的数据发送给从节点,带宽增加但延迟变小。
4、主从复制的不足
- RDB文件过大的情况下,同步非常耗时。
- 在一主一从或者一主多从的情况下,如果主服务器挂了,对外提供的服务就不可用了,单点问题没有得到解决。如果每次都是手动把之前的从服务器切换成主服务器,这个比较费时费力,还会造成一定时间的服务不可用。
02、高可用性Sentinel
【1】、Sentinel原理
创建一台监控服务器来监控所有Redis服务节点的状态,比如,master节点超过一定时间没有给监控服务器发送心跳报文,就把master标记为下线,然后把某一个slave变成master。应用每一次都是从这个监控服务器拿到master的地址。
通过运行监控服务器来保证服务的可用性。
保证监控服务器的可用性,对Sentinel做集群的部署。Sentinel之间也相互监控
注意:Sentinel本身没有主从之分,只有Redis服务节点有主从之分。
概念梳理:master,slave(redisgroup),sentinel,sentinel集合
【2】、服务下线
Sentinel默认以每秒钟1次的频率向Redis服务节点发送PING命令。如果在down-after-milliseconds内都没有收到有效回复,Sentinel会将该服务器标记为下线
1、主观下线
2、客观下线
这个时候Sentinel节点会继续询问其他的Sentinel节点,确认这个节点是否下线,如果多数Sentinel节点都认为master下线,master才真正确认被下线。这个时候就需要重新选举master。
3、故障转移
master被标记为下线后,就会开始故障转移流程。
这么多的Sentinel节点,由谁来做故障转移的事情呢?
故障转移流程的第一步就是在Sentinel集群选择一个Leader,由Leader完成故障转移流程。Sentinle通过Raft算法,实现Sentinel选举。
4、Ratf算法
http://thesecretlivesofdata.com/raft/
【3】、故障转移
怎么让一个原来的slave节点成为主节点?
- 选出SentinelLeader之后,由SentinelLeader向某个节点发送slaveofnoone命令,让它成为独立节点。
- 然后向其他节点发送slaveofx.x.x.xxxxx(本机服务),让它们成为这个节点的子节点,故障转移完成。
这么多从节点,选谁成为主节点?
四个因素影响选举的结果:
断开连接时长、优先级排序、复制数量、进程id。
在配置文件里可以设置(replica-priority100),数值越小优先级越高。
【4】、Sentinel的功能总结
- 监控:Sentinel会不断检查主服务器和从服务器是否正常运行。
- 通知:如果某一个被监控的实例出现问题,Sentinel可以通过API发出通知。
- 自动故障转移(failover):如果主服务器发生故障,Sentinel可以启动故障转移过程。把某台服务器升级为主服务器,并发出通知。
- 配置管理:客户端连接到Sentinel,获取当前的Redis主服务器的地址。
02、Sentinel实战
hostname | IP地址 | 节点角色&端口 |
master | 192.168.8.203 | Master:6379/Sentinel:26379 |
slave1 | 192.168.8.204 | Slave:6379/Sentinel:26379 |
slave2 | 192.168.8.205 | Slave:6379/Sentinel:26379 |
【1】、在204和205的src/redis.conf配置文件中添加
slaveof 192.168.8.203 6379
【2】、在203、204、205创建sentinel配置文件(安装后根目录下默认有sentinel.conf):
cd /usr/local/soft/redis-5.0.5
mkdir logs
mkdir rdbs
mkdir sentinel-tmp
vim sentinel.conf
【3】、三台服务器内容相同:
daemonize yes
port 26379
protected-mode no
dir "/usr/local/soft/redis-5.0.5/sentinel-tmp"
sentinel monitor redis-master 192.168.8.203 6379 2
sentinel down-after-milliseconds redis-master 30000
sentinel failover-timeout redis-master 180000
sentinel parallel-syncs redis-master 1
hostname | IP地址 |
protected-mode | 是否允许外部网络访问 |
dir | sentinel的工作目录 |
sentinel monitor | sentinel监控的redis主节点 |
down-after-milliseconds(毫秒) | master宕机多久,才会被Sentinel主观认为下线 |
sentinelfailover-timeout(毫秒) | 1同一个sentinel对同一个master两次failover之间的间隔时间。 2.当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。 3.当想要取消一个正在进行的failover所需要的时间。 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。 |
parallel-syncs | 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态。 |
【4】、Sentinel验证
1、启动Redis服务和Sentinel
2、查看集群状态:
redis>info replication
203
204和205
03、哨兵机制的不足
- 主从切换的过程中会丢失数据,因为只有一个master。
- 只能单点写,没有解决水平扩容的问题。
- 如果数据量非常大,这个时候我们需要多个master-slave的group,把数据分布到不同的group中。