详解Redis的高可用和高并发机制
一、高并发机制
我们知道redis是基于单线程的,在单机模式下能承载的也就几万左右吧,所以怎么提高其在大数据下几十万的高并发请求,通过redis的主从架构和读写分离。
视频课程推荐→:《千万级数据并发解决方案(理论+实战)》
1.主从复制
redis主从复制的配置就不强调,主要看主从复制的原理及过程:在进行redis的主从复制的过程中,需要一台master主机作为管理员,去搭建多台slave从机。当slave从机试图启动时会向master主机发送一个命令PSYNC,如果这个时候slave从机是重新连接的,那么会从master主机上把slave从机没有的数据复制过去,如果是第一次连接那么会触发full resynchronization。触发以后master主机会在后台开启一个进程去生成一个RDB快照文件,同时将这个时间段的写操作存入缓存,当这个RDB文件生成完毕之后会向slave从机发送RDB文件,从机拿到文件之后将其先写入磁盘然后加载进入内存最后master主机会将缓存在内存里面的数据也同时发送给从机。如果在发生主从的网络故障的情况下,有多个slave从机重新连接那么master只会重启一份RDB去服务全部slave。【相关推荐:Redis视频教程】
断点续传:在master和slave里面都有一个replica offset里面还有一个master id ,其中offset就是保持在backlog,当主从机发生网络故障重连时,会去找到对应的上次replica offset的地方进行复制,如果没有找到对应的offset那么触发full resynchronization。
①复制的完整流程
(1)slave node启动,仅仅保存master node的信息,包括master node的host和ip,但是复制流程没开始
master host和ip是从哪儿来的,redis.conf里面的slaveof配置的
(2)slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接
(3)slave node发送ping命令给master node
(4)口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证
(5)master node第一次执行全量复制,将所有数据发给slave node
(6)master node后续持续将写命令,异步复制给slave node
②数据同步相关的核心机制
指的就是第一次slave连接msater的时候,执行的全量复制,那个过程里面你的一些细节的机制
(1)master和slave都会维护一个offset
master会在自身不断累加offset,slave也会在自身不断累加offset
slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset
这个倒不是说特定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况
(2)backlog
master node有一个backlog,默认是1MB大小
master node给slave node复制数据时,也会将数据在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从master node进行复制,psync runid offset
master node会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制
③全量复制
(1)master执行bgsave,在本地生成一份rdb快照文件
(2)master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数
(3)对于千兆网卡的机器,一般每秒传输100MB,6G文件,很可能超过60s
(4)master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node
(5)client-output-buffer-limit slave 256MB 64MB 60,如果在复制期间,内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败
(6)slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务
(7)如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF
rdb生成、rdb通过网络拷贝、slave旧数据的清理、slave aof rewrite,很耗费时间
如果复制的数据量在4G~6G之间,那么很可能全量复制时间消耗到1分半到2分钟
④增量复制
(1)如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制
(2)master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB
(3)msater就是根据slave发送的psync中的offset来从backlog中获取数据的
⑤heartbeat
主从节点互相都会发送heartbeat信息
master默认每隔10秒发送一次heartbeat,salve node每隔1秒发送一个heartbeat
⑥异步复制
master每次接收到写命令之后,现在内部写入数据,然后异步发送给slave node
2.读写分离:master负责写入操作,slave负责帮master减轻访问查询量
二、高可用机制
在高并发的情况下,配备多集群一主多备,虽然可以解决高并发问题,但是主机只有一个,master宕机那么整个无法进行写操作,从机无法同步数据整个系统会处于瘫痪状态,整就一个不可用。redis的高可用机制哨兵机制,哨兵是redis集群里面的重要的组件,他负责集群监控,信息通知,故障转移,配置中心。
(1)集群监控,负责监控redis master和slave进程是否正常工作
(2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
(3)故障转移,如果master node挂掉了,会自动转移到slave node上
(4)配置中心,如果故障转移发生了,通知client客户端新的master地址
哨兵本身是分布式的,是作为一个集群去工作的,需要互相协同工作。
当发现master node 宕机,会需要大部分的哨兵同意才可以,这个涉及到分布式的选举。
哨兵机制需要保证最少3个节点才能保证其健壮性,如果我们在测试时只给出两个节点,一个master node一个为slave node 那么这两个节点里面都有一个哨兵负责监控,当其中的master主机发生宕机,那么需要哨兵来进行选举,那么master node里面那个s1的哨兵已经没办法工作,只能由slave node里面的s2哨兵进行选举,那么进行选举之后要进行故障转移需要一个哨兵进行工作,其majority参数规定了需要哨兵的个数进行故障转移,这时只有一个S2哨兵没有majority可以进行故障转移。所以最少需要3个节点来保证其健壮。
三、高可用与高并发出现的数据丢失问题
(1)异步复制导致的数据丢失
因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就宕机了,此时这些部分数据就丢失了。
(2)脑裂导致的数据丢失
脑裂,也就是说,某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着,
此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master,
这个时候,集群里就会有两个master,也就是所谓的脑裂,
此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master的数据可能也丢失了,
因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据。
解决异步复制和脑裂导致的数据丢失
min-slaves-to-write 1 min-slaves-max-lag 10
要求至少有1个slave,数据复制和同步的延迟不能超过10秒
如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了
上面两个配置可以减少异步复制和脑裂导致的数据丢失
(1)减少异步复制的数据丢失
有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内
(2)减少脑裂的数据丢失
如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求
这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失
上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求
因此在脑裂场景下,最多就丢失10秒的数据
更多编程相关知识,请访问:编程入门!!
以上就是详解Redis的高可用和高并发机制的详细内容,更多请关注https://www.sxiaw.com/其它相关文章!