Redis系列学习笔记20 Redis多机特性工作原理简介

Redis多机特性工作原理简介

  • 复制(replication)
  • Sentinel
  • 集群(cluster)

复制

SLAVEOF

SLAVEOF <ip> <port>
将一个服务器(从服务器)变成为另一个服务器(主服务器)的复制品。

复制的执行步骤

  • 从服务器向主服务器发送SYNC命令
  • 接到SYNC命令的主服务器会调用BGSAVE命令,创建一个RDB文件,并使用缓冲区记录接下来执行的所有写命令。
  • 当主服务器执行完BGSAVE命令时,它会向从服务器发送RDB文件,而从服务器则会接收并载入这个文件。
  • 主服务器将缓冲区储存的所有写命令发送给从服务器执行。
  • 在只从服务器完成同步之后,主服务器每执行一个写命令,它都会将被执行的写命令发送给从服务器执行,这个操作称之为”命令传播”(command propagate)。命令传播,是一个持续的过程

SYNC vs PSYNC

Redis2.8开始使用PSYNC命令代替SYNC命令。PSYNC最大的改进在于PSYNC实现了部分重同步特性:
在主服务器断线并且重新连接的时候,只要条件允许,PSYNC可以让主服务器只向从服务器同步断线期间缺失的数据,而不用重新向从服务器同步整个数据库。

一致性问题

客户端对主服务器发送一个写命令,主服务器向从服务器发送写命令期间,客户端向从服务器发送了读命令,于是读的是老的数据,这就会造成数据不一致。但是最终会一致。

Redis目前的复制实现只保证最终一致性,而不是强一致性。如果有强一致性的需求,那么可以向主服务器读取数据。

Sentinel

Sentinel的构造

Sentinel是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。

发现并连接主服务器

Sentinel通过用户给定的配置文件来发现主服务器。

$ redis-sentinel sentinel.conf

配置示例:

**********master1 configure**********
sentinel monitor master1 127.0.0.1 6379 2
sentinel down-after-milliseconds master1 30000
sentinel parallel-syncs master1 1
sentinel failover-timeout master1 900000

**********master2 configure**********
sentinel monitor master1 127.0.0.1 12345 5
sentinel down-after-milliseconds master2 50000
sentinel parallel-syncs master2 5
sentinel failover-timeout master2 450000

发现并且连接从服务器

Sentinel通过向主服务器发送INFO命令来自动获得所有从服务器的地址

redis>INFO
# other section ...
# Replication
role:master
...
slave0:ip=127.0.0.1,port=11111,state=online,offset=43,lag=0
slave1:ip=127.0.0.1,port=22222,state=online,offset=43,lag=0
slave2:ip=127.0.0.1,port=33333,state=online,offset=43,lag=0
...
# other section ...

发现其他Sentinel

Sentinel会通过命令连接向被监视的主从服务器发送HELLO信息,该消息包含Sentinel的IP、端口号、ID等内容,以此来向其他Sentinel宣告自己的存在。与此同时,Sentinel会通过订阅连接接收其他Sentinel的HELLO信息,以此来发现监视同一个主服务器的其他Sentinel。

连接其他Sentinel

  • Sentinel之间会互相创建命令连接,用于进行通信。
  • 因为已经有主从服务器作为发送和接收HELLO信息的中介,所以Sentinel之间不会创建订阅连接。

Sentinel检测实例的状态

Sentinel使用PING命令检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被Sentinel判断为下线。

Sentinel和从服务器的下线状态

如果Sentinel把一个从服务器或者另一个Sentinel标记为下线,那么:

  • Sentinel不会与下线的Sentinel交换信息。
  • Sentinel也不会将下线的从服务器选为新的主服务器。

主服务器的下线状态

主服务器的下线状态分为PFAIL和FAIL两级:

  • PFAIL状态:单个或者少量Sentinel认为主服务器已下线。
  • FAIL状态:有个Sentinel认为主服务器已经进入PFAIL状态。
  • sentinel monitor
  • 换言之,对于主服务器来说,FAIL才是真正的下线状态。

一旦主服务器被判断为FAIL,Sentinel就会对下线主服务器进行故障转移。
步骤:
- 在下线主服务器的所有从服务器中,选出一个数据状态最接近主服务器的从服务器,选择的条件包括:从服务器未下线、主从之间的链接断开时间最短,等等。
- Sentinel向被选中的从服务器发送SLAVEOF NO ONE,将它升级为主服务器。
- 向其他从服务器发送SLAVEOF命令,让它们复制新的主服务器。

完成了故障转移之后,新的主服务器就可以代替已下线的主服务器,继续执行客户端发送的写命令了。

Sentinel是一个状态机,它监视着多个实例,并根据实例的身份和状态,对实例进行操作。
Sentinel使用PING命令来检测实例是否在线。
Sentinel会对下线的主服务器进行故障转移,步骤主要有三个:1)选出一个从服务器;2)将被选中的从服务器升级为主服务器;3)让其他从服务器复制这个新的主服务器。

集群的构成

一个集群由一个或者多个节点(node)组成,其中主节点(master)负责存储键值对数据,而从节点(slave)则负责复制主节点。
集群中的每个节点相互连接,并通过连接进行通信。

分片(sharding)

  • 集群将整个数据库分为16384(2的14次方)个槽(slot)。
  • 每个主节点可以负责处理0个至16384个槽。
  • 当16384个槽都有主节点负责处理时,集群进入上线状态,可以开始处理数据命令。

槽的计算公式

集群使用公式CRC16(key) & 16383计算键key属于哪个槽。

在集群里面执行命令的两种情况

  • 命令发送到了正确的节点:命令要处理的键所在的槽正好是由接收命令的节点负责,那么该节点执行命令,就像单机Redis服务器一样。
  • 命令发送到了错误的节点:接收到命令的节点并非处理键所在槽的节点,那么节点将向客户端返回一个转向(redirection)错误,告知客户端应该到那个节点去执行这个命令,客户端会根据错误提示的信息,重新向正确的节点发送命令。

转向错误的实现

集群中的节点会相互告知对方,自己负责处理那些槽。

  • 集群中的每个节点都会记录16384个槽分别由哪些节点负责,从而形成一个槽表(slot table)。

  • 节点在接收到命令请求时,会通过槽表检查键所在的槽是否由本节点处理:

    • 如果是的话,那么节点直接执行命令
    • 如果不是的话,那么节点就从槽表里面提取出正确节点的地址信息,然后返回转向错误。

集群节点的复制

集群的复制特性重用了SLAVEOF命令的代码,所以集群节点的复制行为和SLAVEOF命令的复制行为完全相同。

集群主节点的故障转移

  • 在集群里面,节点会对其他节点进行下线检测。
  • 当一个主节点下线时,集群里面的其他主节点负责对下线主节点进行故障转移。
  • 换句话说,集群的节点集成了下线检测和故障转移等类似Sentinel的功能。
  • 因为Sentinel是一个独立运行的监控程序,而集群的下线检测和故障转移等功能是集成在节点里面的,它们的运行模式非常地不同,所以尽管这两者的功能很相似,单集群的实现没有重用Sentinel的代码。

你可能感兴趣的:(redis)