SLAVEOF
SLAVEOF <ip> <port>
将一个服务器(从服务器)变成为另一个服务器(主服务器)的复制品。
复制的执行步骤
Redis2.8开始使用PSYNC命令代替SYNC命令。PSYNC最大的改进在于PSYNC实现了部分重同步特性:
在主服务器断线并且重新连接的时候,只要条件允许,PSYNC可以让主服务器只向从服务器同步断线期间缺失的数据,而不用重新向从服务器同步整个数据库。
客户端对主服务器发送一个写命令,主服务器向从服务器发送写命令期间,客户端向从服务器发送了读命令,于是读的是老的数据,这就会造成数据不一致。但是最终会一致。
Redis目前的复制实现只保证最终一致性,而不是强一致性。如果有强一致性的需求,那么可以向主服务器读取数据。
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会通过命令连接向被监视的主从服务器发送HELLO信息,该消息包含Sentinel的IP、端口号、ID等内容,以此来向其他Sentinel宣告自己的存在。与此同时,Sentinel会通过订阅连接接收其他Sentinel的HELLO信息,以此来发现监视同一个主服务器的其他Sentinel。
Sentinel使用PING命令检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被Sentinel判断为下线。
如果Sentinel把一个从服务器或者另一个Sentinel标记为下线,那么:
主服务器的下线状态分为PFAIL和FAIL两级:
一旦主服务器被判断为FAIL,Sentinel就会对下线主服务器进行故障转移。
步骤:
- 在下线主服务器的所有从服务器中,选出一个数据状态最接近主服务器的从服务器,选择的条件包括:从服务器未下线、主从之间的链接断开时间最短,等等。
- Sentinel向被选中的从服务器发送SLAVEOF NO ONE,将它升级为主服务器。
- 向其他从服务器发送SLAVEOF命令,让它们复制新的主服务器。
完成了故障转移之后,新的主服务器就可以代替已下线的主服务器,继续执行客户端发送的写命令了。
Sentinel是一个状态机,它监视着多个实例,并根据实例的身份和状态,对实例进行操作。
Sentinel使用PING命令来检测实例是否在线。
Sentinel会对下线的主服务器进行故障转移,步骤主要有三个:1)选出一个从服务器;2)将被选中的从服务器升级为主服务器;3)让其他从服务器复制这个新的主服务器。
一个集群由一个或者多个节点(node)组成,其中主节点(master)负责存储键值对数据,而从节点(slave)则负责复制主节点。
集群中的每个节点相互连接,并通过连接进行通信。
集群使用公式CRC16(key) & 16383计算键key属于哪个槽。
在集群里面执行命令的两种情况
转向错误的实现
集群中的节点会相互告知对方,自己负责处理那些槽。
集群中的每个节点都会记录16384个槽分别由哪些节点负责,从而形成一个槽表(slot table)。
节点在接收到命令请求时,会通过槽表检查键所在的槽是否由本节点处理:
集群的复制特性重用了SLAVEOF命令的代码,所以集群节点的复制行为和SLAVEOF命令的复制行为完全相同。