redis集群 第三节 在集群中执行命令

在对数据库中的16384个槽都进行了指派之后,集群就会进入上线状态,这时客户端就可以向集群中的节点发送数据命令了。
当客户端向节点发送与数据库键有关的命令时,接收命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己:

  • 如果键所在的槽正好就指派给了当前节点,那么节点直接执行这个命令
  • 如果将所在的槽并没有指派给当前节点,那么节点会向客户端返回一个MOVED错误,指引客户端转向(redirect)至正确的节点,并在此发送之前想要执行的命令。

本节接下来的内容将介绍计算键所属槽的方法,节点判断某个槽是否由自己负责的方法,以及MOVED错误的实现方法,最后,本节还会介绍节点和单机Redis服务器保存键值对的相同和不同之处。

3.1 计算键属于哪个槽

节点使用以下算法来计算给定键key属于哪个槽:

def slot_number(key):
return CRC16(key) & 16383

其中CRC16(key)语句用于计算键key的CRC-16校验和,而&16383语句则用于计算出一个介于0至16383之间的整数作为键key的槽号。
使用CLUSTER KEYSLOT <key>命令可以查看一个给定键属于哪个槽,以下是该命令的伪代码实现:

def CLUSTER_KEYSLOT(key):
# 计算槽号
slot = slot_number(key)
# 将槽号返回给客户端
reply_client(slot)

3.2 判断槽是否由当前节点负责处理

当节点计算出键所属的槽i之后,节点就会检查自己在clusterState.slots数组中的项i,判断键所在的槽是否由自己负责:

  • 如果clusterState.slots[i]等于clusterState.myself,那么说明槽i由当前节点负责,节点可以执行客户端发送的命令。
  • 如果clusterState.slots[i]不等于clusterState.myself,那么说明槽i并非由当前节点负责,节点会根据clusterState.slots[i]指向的clusterNode结构所记录的节点IP和端口号,向客户端返回MOVED错误,指引客户端转向至正在处理槽i的节点。

3.3 MOVED错误

当节点发现键所在的槽并非由自己负责处理的时候,节点就会向客户端返回一个MOVED错误,指引客户端转向至正在负责槽的节点。

MOVED错误的格式为:

MOVED <slot> <ip>:<port>

其中slot为键所在的槽,而ip和port则是负责处理槽slot的节点的IP地址和端口号
当客户端接收到节点返回的MOVED错误时,客户端会根据MOVED错误中提供的IP地址和端口号,转向至负责处理槽slot的节点,并向该节点重新发送之前想要执行的命令。
一个集群客户端通常会与集群中的多个节点创建套接字连接,而所谓的节点转向实际上就是换一个套接字来发送命令。
如果客户端尚未与想要转向的节点创建套接字连接,那么客户端会现根据MOVED错误提供的IP地址和端口号来连接节点,然后再进行转向。

3.4 节点数据库的实现

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文档翻译自 http://redis.io/topics/cluster-tutorial 。 本文档是 Red...
    会跳舞的机器人阅读 67,024评论 2 21
  • Redis Cluster原理分析 文章较长,如需转载可分段。转载请标明作者以及文章来源,谢谢! 作者介绍 姓名:...
    lihanglucien阅读 20,661评论 3 30
  • 1 Redis介绍1.1 什么是NoSql为了解决高并发、高可扩展、高可用、大数据存储问题而产生的数据库解决方...
    克鲁德李阅读 10,801评论 0 36
  • 基本目标与设计基本思想 Redis cluster 目标 高性能,并且能线性扩展到1000个节点。不需要代理,使用...
    tafeng阅读 7,760评论 0 0
  • 过了十一,一切都不想去做,一直有愿望去四川看大熊猫,能日复一日的陪伴熊宝宝也是一种幸福吧? 如果有一天自己养的宝宝...
    Wanda_ff08阅读 1,527评论 0 0