一、基本原理
1. 主从架构的核心原理
当启动一个slave node的时候,它会发送一个PSYNC命令给master node
如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization
开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。
slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。
2. 主从复制的断点续传
从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份
master node会在内存中创建一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制
但是如果没有找到对应的offset,那么就会执行一次resynchronization
3. 无磁盘化复制
master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了
repl-diskless-sync
repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来
4. 过期key处理
slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。
二、 主从使用不当会导致什么问题?
1. 老生常谈的大key可能造成的雪崩
如果从节点比较多的话,向master写入大key的时候就很可能把master节点的带宽占满,进而导致master不可用,更可怕的是如果此时master高并发写入slave就会落后master很多,需要进行full replication,此时slave也不可用,但是这个时候master的带宽已经被拉满了,重启master、slave都于事无补~~~ game over
2. 怎么办?
- 要对redis使用的key进行审查,杜绝大key的写入;可以在公司内封装的redis-client上进行拦截,dba那边也需要有监控审查,定时通报整改
- master-slave的部署进行调整,slave个数不要过多, 或者用树形的部署结构,不要让所有的slave都直接从master复制
master
/ | \ \
slave slave slave ...
master
/ \
slave slave
/ \
slave slave
3. 那如果由于历史原因已经这样了,好死不死线上真发生故障了,咋办?
前面提到,master带宽拉满,而所有的slave落后太多又要进行 full replication进一步导致 master带宽不可恢复;此时重启 master或者重启slave都没有用,重启后带宽立马又会被拉满
这个时候可以,先把所有slave节点都摘掉,然后重新一个个慢慢重新建立从节点关系(不要一起拉入,又把master的带宽给打爆了) 我们之前线上 1 master、10+slave 真实案例就是这么恢复的(一把泪啊)。。。重新建立主从关系的时候,可以考虑直接弄成树形结构了
网友评论