事故经常有,最近有点多!这不,水哥最近又遇到一个线上事故。不过还好不是公司的系统。
因为我最近偷偷做了个私活小项目,由于初期没有什么用户量,就搞了个redis单机版,想着能跑就行。
结果国庆放假的前一天,在和同事聚餐的时候,客户一个电话打过来,怎么系统突然登陆不了了,快看看。于是我在同事鄙夷的目光下拿出了电脑,在饭桌上排查了起来。啪,很快啊,就发现是redis挂了!由于这时候菜已经上了,于是草草采用重启大法,系统才恢复运行。
在聚餐回去之后,我还是觉得有点羞愧,我这项目未来可是要成长为航母级项目的,想着还是搞个redis高可用吧,不然吃个饭都吃不安宁。。便给项目搭建了一下redis的哨兵模式,防止再次拉垮。
下面是保姆式的教学,教大家手动搭一遍,看了就能学废了。
redis主从架构手动配置过程
1、复制一份redis配置文件 cp redis.conf redis-1.conf
2、修改相关配置
port 6380
pidfile /var/run/redis_6380.pid
logfile "6380.log"
dir /usr/local/redis-5.0.4/data/6380 #指定数据存放目录
#配置主从
#replicaof <masterip> <masterport>
replicaof 192.9.1.102 6379 #从本机6379的redis实例内复制数据
replica-read-only yes # 配置从节点只读复制
3、启动从节点,验证数据是否能进行同步
最简单的主从架构搭建完成
Redis主从工作原理
1、全量复制
全量复制一般发生在Slave的初始化阶段,这时slave需要将master的数据全部复制。具体步骤如下:
slave向master发送SYNC命令
master收到SYNC命令后,执行bgsave命令生成持久化文件(rdb文件),同时使用缓冲区记录同步开启之后的修改数据的命令。
bgsave完成后,把rdb文件发送给从slave,发送期间依旧持续记录修改数据的命令
slave收到文件后,丢弃原有的旧数据,载入收到的rdb快照文件
master再把缓冲区的修改数据的命令发送给slave
slave载入完成快照后,开始接受master的命令,并执行master发送的缓存区的命令。
2、增量复制
增量复制是指slave初始化后正常工作时master的修改命令同步到slave的过程。增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
3、部分复制(断点续传)
部分同步是指当master和slave之间的连接断掉之后,再次重连之后不需要进行全量复制,可以进行部分复制(redis2.8之后才有,在那之前重连都是全量同步)。具体的实现如下:
前提:master和slave都维护了一份同步日志和同步标识,salve在和master进行同步的时候会写到自己的同步标识和上次同步的最后位置
当连接断开后,slave会请求master,如果slave的标识还在master服务器的同步日志里,那么就从slave发送的偏移量开始继续同步操作。
如果在master找不到slave的标识了,那么就需要进行一次全量复制。
4、主从复制风暴
如果有多个从节点,当拉起或者多个同时重启的时候,由于slave启动就会发送sync请求master进行全量同步,可能导致master(主节点)压力过大甚至宕机。
要缓解主从复制风暴问题,可以尝试使用联级的结构,具体如下:
redis哨兵模式
在我们使用了redis的主从时,如果master服务挂了,我们是不是希望slave可以替代master继续进行工作,这个时候,其中一个slave就应该变成master继续提供服务。但从服务器(slave)并不能自动的切换成主服务器。那么为了解决这个问题,就需要使用这个哨兵模式。接下来我们介绍一下哨兵模式。
1、哨兵模式主要功能
监控redis是否按照预期运行
如果发现某个redis结点运行异常,可以进行消息通知
当master结点可不用时,可以通过选举挑选一个slave作为新的master
可以提供服务发现,客户端连接哨兵,哨兵提供当前master的地址
哨兵也支持集群,可以搭建多个
2、工作示意图
如上图所示,开启了三个sentinel组成哨兵集群,其中每个sentinel都会对redis服务器进行监控,同时各个sentinel之间还会进行监控,这就是哨兵集群模式。
当redis的master服务出现故障时,会进行故障切换操作。
1、在集群模式下,如果master宕机了,sentinel1首先检测到,此时master会被当前哨兵标记为主观下线。
2、当一个master被标记为主观下线后,其他也在监测这个master的sentinel会加大频率确认该master的主观下线状态。
3、当足够多的sentinel都认定该master主观下线,此时就会被标记为客观下线。
4、sentinel领导者节点进行选举一个新的master,并通过发布订阅通知到各个服务器进行切换。
3、搭建哨兵
上文里已经介绍了redis主从的搭建,我们搭建的redis集群具体配置如下:
接下来开始搭建哨兵集群:
1、找到sentinel.conf文件复制一份
cp sentinel.conf sentinel-23679.conf
2、修改相关配置文件
port 26379
daemonize yes
pidfile "/var/run/redis‐sentinel‐26379.pid"
logfile "26379.log" 9 dir "/usr/local/redis‐5.0.4/data"
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster 192.9.1.103 6379 2 # mymaster这个名字随便取,客户端访问时会用到复制
3、启动sentinel哨兵
src/redis-sentinel sentinel-23679.conf
4、按照相同的方法调整配置文件,再启动2个哨兵,具体配置如下
这里为了简单都在一个服务器上搭建了,实际使用建议在不同的服务器上进行搭建
验证哨兵
我们根据要求搭建完哨兵集群后,可以再配置文件里看到集群的一些信息,具体如下所示:
sentinel known-replica mymaster 127.0.0.1 6381 #redis的从节点信息
sentinel known-replica mymaster 127.0.0.1 6380 #redis的从节点信息
sentinel known-sentinel mymaster 127.0.0.1 26381 764ed5ce643dbe7925df530aae8782b088451836 #代表感知到的其他哨兵节点
sentinel known-sentinel mymaster 127.0.0.1 26380 0cc13f38fbb496b569bf52b580edea92a53397a0 #代表感知到的其他哨兵节点复制
当主节点挂了之后。哨兵集群会重新选举出新的redis主节点,同时,所有sentinel节点的配置文件也会跟着进行修改。比如我们现在的6379挂了,可以看看配置文件的变化如下:
可以看到一开始我们的mymaster的端口是6379,经过重新选举后变成了6380,同时,当6379再次启动时,6379就会边充从节点继续加入集群。
小结
通过哨兵sentinel工具来监控master节点的状态,我们可以在master出现异常时依据哨兵进行主从切换。但哨兵的主从切换需要一定时间,并且在性能和高可用上表现一般,同时在主从切换的瞬间,可能出现访问瞬间断开的情况。在redis3.0之前的版本要实现集群一般是借助哨兵工具来实现。在更高版本,一般使用redis-cluster(下次再讲)