3.1 有备无患——主从同步

3.1.1 CAP原理

3.1.2 最终一致

Redis的主从架构是AP的。主从节点数据是异步复制的,复制过程中主从节点均可对外提供服务。Redis只保证最终一致性。

3.1.3 主从同步与从从同步

减轻主节点同步压力。

3.1.4 增量同步

正常情况下,Redis同步的是指令流,主节点会将那些对自己的状态产生修改的指令记录在本地的内存buffer中,然后异步地将buffer中的指令同步到从节点。从节点一边执行同步的指令流来追赶主节点的状态,一边向主节点反馈自己同步到哪里了(偏移量)。
指令buffer大小是有限的,所以Redis主节点不能将所有指令都记录在内存buffer中。指令buffer是一个定长的环形数组,如果数组内容满了,后续指令会从头开始覆盖之前的指令。
如果因为网络状态不好,从节点短时间内无法和主节点同步,指令buffer中就会累积越来越多未同步指令,直到覆盖掉一些未同步指令。待网络恢复时,被覆盖掉的指令再也无法执行,再执行增量同步会导致主从节点数据不一致。因此此时需要进行快照同步。

3.1.5 快照同步

快照同步是一个非常耗费资源的操作。其原理是先在主节点上执行一次bgsave,创建一个rdb文件,然后将该文件传递给从节点。从节点清空现有数据,再利用rdb文件进行一次全量加载。加载完成后,再通知主节点继续进行增量同步。
不过要注意,在快照同步执行期间,主节点依然在不断执行指令。如果此时又发生了buffer溢出,那么就又会触发快照同步,这可能导致死循环。
因此,务必设置一个足够大的指令buffer。

3.1.6 增加从节点

当从节点刚刚加入到集群中时,它必须先进行一次快照同步,同步完成后再继续进行增量同步。

3.1.7 无盘复制

所谓无盘复制,是指主节点直接通过套接字将快照内容发送到从节点。从节点先将接收到的内容存储到磁盘上,再进行加载。这样可以节省主节点写硬盘的消耗。

3.1.8 wait指令

默认Redis的复制是异步进行的,wait指令可以让异步复制变成同步复制,确保系统的强一致性。
wait提供两个参数,第一个参数是从节点的数量N,第二个参数是时间t,以毫秒为单位。两个参数的含义是:等待wait指令之前的所有写操作同步到N个从节点,最多等待t。如果t=0,表示无限等待。
假设此时从节点不可达,wait指令将永远阻塞,Redis服务器丧失可用性。


3.2 李代桃僵——Sentinel

Redis Sentinel是一套高可用方案,可以在故障发生时自动进行主从切换,从而让服务尽快恢复。
Sentinel本身也会构成一个集群,通常包含3~5个节点,从而保证自身的高可用。
Sentinel负责持续监控主从节点的健康,当主节点挂掉时,自动选择一个最优的从节点切换称为主节点。客户端来连接集群时,会首先连接Sentinel,通过Sentinel来查询主节点的地址,然后再连接主节点进行数据交互。当主节点发生故障时,客户端会重新向Sentinel要地址,Sentinel会将最新的主节点地址高速客户端。如此应用程序无需重启即可自动完成节点切换。

3.2.1 消息丢失

主从复制是存在延迟的,当主节点挂掉时,未同步的消息就丢失了。Sentinel无法保证消息完全不丢失,但可以尽量保证消息少丢失。
它有两个选项可以限制主从延迟过大:

min-slaves-to-write 1 min-slaves-max-lag 10

第一个参数参数表示主节点必须至少有一个从节点在进行正常的复制,否则就停止对外写服务,丧失可用性。
何为正常复制?由第二个参数控制,它的单位是秒,表示如果10s内没有收到从节点的反馈,就意味着从节点同步不正常。

3.2.2 Sentinel基本用法


3.3 分而治之——Codis


3.4 众志成城——Cluster