redis学习笔记-复制、sentinel与集群

复制

咱们能够执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另外一个服务器,复制数据的服务器会变成另外一台服务器的从服务器,两者保持相同的数据。之后在主服务器上设置键值会自动同步数据到从服务器上。node

复制功能的实现

同步

将从服务器的数据库状态更新至主服务器当前所处的数据库状态。redis

clipboard.png

命令传播

当主服务器的数据库状态被修改,致使主从服务器的数据库状态出现不一致时,让主从服务器的数据库从新回到一致状态。
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:数据库

REPLICATION ACK <replication_offset>

主要用于检测主从服务器的网络链接状态和命令丢失。服务器

sentinel(redis高可用解决方案)

由一个或多个sentinel实例组成的sentinel系统能够监视任意多个主服务器,以及这些主服务器属下的全部从服务器;并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,而后由新的主服务器代替已下线的主服务器继续处理命令请求。如图所示:网络

clipboard.png

它是如何工做的?

启动

redis-sentinel sentinel.conf 或者
redis-server sentinel.conf --sentinel

初始化服务器

sentinel本质上只是一个运行在特殊模式下的redis服务器,但它不使用数据库,因此并不会载入RDB文件或者AOF文件来还原数据库状态。初始化过程:异步

  • 使用sentinel专用代码初始化sentinel状态分布式

  • 建立连向主服务器的网络链接spa

链接创建以后,sentinel将成为主服务器的客户端,它能够向主服务器发送命令,并从命令回复中获取相关的信息。对于每一个被sentinel监视的主服务器来讲,sentinel会建立两个连向主服务器的异步网络链接:设计

  • 命令链接,向主服务发送命令,并接收命令回复code

  • 订阅链接,订阅主服务器的__sentinel__:hello频道

注:若是发现主服务器下有从服务器,也会为从服务器建立命令链接和订阅链接。而sentinel与sentinel之间则只建立命令链接。

获取服务器信息

sentinel默认会以每十秒一次的频率,经过命令链接向被监视的主从服务器发送INFO命令,并经过分析INFO命令的回复来获取主服务器的当前信息。

发送和接收消息

在默认状况下,sentinel会以每两秒一次的频率,经过命令链接向全部被监视的主服务器和从服务器发送如下格式的命令:

PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

当sentinel与一个主服务器或者从服务器创建起订阅链接以后,sentinel就会经过订阅链接,向服务器发送如下命令:

SUBSCRIBE __sentinel__:hello

sentinel对__sentinel__:hello频道的订阅会一直持续到sentinel与服务器的链接断开为止。

也就是说,对于每一个与sentinel链接的服务器,既经过命令链接向服务器的__sentinel__:hello频道发送信息,又经过订阅链接从服务器的__sentinel__:hello频道接收信息。对于监视同一个服务器的多个sentinel来讲,一个sentinel发送的信息会被其余sentinel接收到,这些信息会被用于更新其余sentinel对发送信息sentinel的认知,也会被用于更新其余sentinel对被监视服务器的认知。

检测服务器状态

检测主观下线状态

sentinel以每秒一次的频率向实例(包括主服务器、从服务器、其余sentinel)发送PING命令,并根据实例对PING命令的回复来判断实例是否在线,当一个实例在指定的时长中连续向sentinel发送无效回复时,sentinel会将这个实例判断为主观下线。

检测客观下线状态,进行故障转移

当sentinel将一个主服务器判断为主观下线时,它会向一样监视这个主服务器的其余sentinel进行询问,看它们是否赞成这个主服务器已经进入主观下线状态;当sentinel收集到足够多的主观下线投票以后,它会将主服务器判断为客观下线,并选取一个领头sentinel发起一次针对主服务器的故障转移操做。
注:更多细节请查阅<<redis设计与实现>> 第16章内容...

集群

redis集群是redis提供的分布式数据库方案,集群经过分片(sharding)来进行数据共享,并提供复制和故障转移功能(redis3.0以前须要依靠client端作sharding,3.0以后,开始支持server端的集群)。

节点

一个redis集群由多个节点(node)组成,使用cluster meet ip port链接各个节点(握手),而后经过cluster nodes查看集群节点信息。

  • 启动服务器的时候会判断cluster-enabled值:若是为yes,开启服务器的集群模式成为一个节点。

  • 节点分为主节点和从节点,主节点用于处理槽(有关槽的介绍见下一小节),而从节点用于复制某个主节点,并在被复制的主节点下线时,代替下线主节点继续处理命令请求(集群中的每一个节点都会按期地向集群中其余节点发送PING消息,以此来检测对方是否在线)。

注:节点和单机服务器在数据库方面的一个区别是,节点只能使用0号数据库,而单机redis服务器则没有这一限制。

槽指派

redis集群经过分片的方式来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),数据库中的每一个键都属于这16384个槽的其中一个,集群中的每一个节点能够处理0个或最多16384个槽。

  1. 经过向节点发送CLUSTER ADD SLOTS命令, 咱们能够将一个或多个槽指派(assign)给某个节点负责,好比将槽0至5000指派给节点7000负责:
    127.0.0.1:7000> CLUSTER ADDSLOTS 0 1 2 3 4 ... 5000

  2. 每一个节点都会记录哪些槽指派给了本身,而哪些槽又被指派给了其余节点。当数据库中的16384个槽都有节点在处理时,集群处于上线状态(ok);相反地,若是数据库中有任何一个槽没有获得处理,那么集群处于下线状态(fail)。

分片:将你的数据拆分到多个redis实例的过程,这样每一个实例将只包含全部键的子集。经过多台服务器实现分片,能够再也不局限于单机所能支持的内存容量,利于扩展。另外,因为每一个key最终只会存储到一个特定的redis实例的一个slot中,若是要实现高可用,最好至少保证双写,一个key要存储到两个redis实例中(对应两台服务器),读取的时候能够随机读。

在集群中执行命令过程

clipboard.png

从新分片

redis集群的从新分片操做能够将任意数量已经指派给某个节点(源节点)的槽改成指派给另外一个节点(目标节点),而且相关槽所属的键值对也会从源节点被移动到目标节点。从新分片操做能够在线(online) 进行,在从新分片的过程当中,集群不须要下线,而且源节点和目标节点均可以继续处理命令请求。对集群中单个槽从新分片须要执行以下命令:

目标节点:CLUSTER SETSLOT <slot> IMPORTING <source_id> ①
源节点:CLUSTER SETSLOT <slot> MIGRATING <target_id> ②
源节点:CLUSTER GETKEYSINSLOT <slot> <count> ③
源节点:MIGRATE <target_ip> <target_port> <key_name> 0 <timeout> ④
任意节点:CLUSTER SETSLOT <slot> NODE <target_id> 通知其它节点该槽指派给了target_id节点

注:从新分片是基于键值对维度的,每一个槽中的n个键须要执行n次③和④的操做。

相关文章
相关标签/搜索