• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

redis集群之基础概念

redis 海叔叔 3小时前 2次浏览 已收录 0个评论

redis集群是redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能

节点

一个redis集群通常由多个节点组成,在刚开始的时候,每个节点都是相互独立的,它们都处于一个只包含自己的集群当中,可以通过在配置选项中指定cluster-enabled来在启动的时候将一台单独服务器开启服务器的集群模式,也可以在启动之后,通过CLUSTER MEET 命令来开启服务器的集群模式。

集群的数据结构保存在clusterNode结构里面,代码如下:

每个节点都会使用一个clusterNode结构来记录自己的状态,并为集群中的所有其他节点都创建一个相应的clusterNode结构,以此来记录其他节点状态;
其中的link字段是一个clusterLink结构,该结构保存了连接节点所需的有关信息,

最后,每个节点都保存着一个clusterState结构,这个结构记录了在当前节点的视角下,集群目前所处的状态

CLUSTER MEET命令的实现模式跟tcp的三次握手有点像,来回发PING,PONG命令,然后在成功的情况下各自节点都为对方创建一个clusterNode结构。初次握手完成之后,发送CLUSTER MEET的节点会通过gossip协议将接收命令的节点信息传送给集群内其他的节点,然后其他节点与接收命令的节点握手,最终达成一致状态

槽指派

redis集群通过分片的方式来保存数据库中的键值对:集群的整个数据库被分成了16384个槽,数据库中的每个键都属于这16384个槽中的一个,集群中的每个节点可以处理0个或最多16384个槽
当数据库中的16384个槽都有节点在处理时,集群处于上线状态;如果数据库中有任何一个槽没有得到处理,那么集群处于下线状态。
通过向加点发送CLUSTER ADDSLOTS [slot …] 命令,我们可以将一个或多个槽指派给节点负责,clusterNode结构的slots(二进制位数组)属性和numbslot属性记录了节点负责哪些槽。
一个节点除了会将自己负责处理的槽记录在clusterNode结构的slots属性和numslots属性之外,它还会将自己的slots数组通过消息发送给集群中的其他节点,以此来告知其他节点自己目前负责处理哪些槽。而clusterState结构中的slots数组记录了集群中所有16384个槽的指派信息,每个槽只能属于一个clusterNode所处理

在集群中执行命令

对所有的槽都进行了指派之后,集群就会进入上线状态,这时,客户端就可以向集群中的节点发送数据命令了。当客户端向节点发送与数据库键有关的命令时,接收命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己:如果键所在的槽正好就指派给了当前节点,那么节点直接执行;如果键所在的槽并没有指派给当前节点,那么节点会向客户端返回一个MOVED :错误,指引客户端转向正确的节点
节点和单机服务器在数据库方面的一个区别是,节点只能使用0号数据库,而单机redis没有这一限制。另外,除了将键值对保存在数据库里面之外,节点还会用clusterState结构中的slots_to_keys跳跃表来保存槽和键之间的关系,跳跃表每个节点的分值是一个槽号,而每个节点的成员都是一个数据库键,这个结构会随着数据库键的变化而变化

重新分片

redis集群的重新分片操作可以将任意数量已经指派给某个节点的槽改为指派给另一个节点,并且相关槽所属的键值对也会从源节点移动到目标节点。
重新分片的操作是由redis的集群管理软件redis-trib负责执行的,其对集群的单个槽slot进行重新分片的步骤如下:
1. redis-trib对目标节点发送CLUSTER SETSLOT IMPORTING 命令,让目标节点准备好从源节点导入属于槽slot的键值对,底层由clusterState 结构当中的importing_slots_from字段表示
2. redis-trib对源节点发送 CLUSTER SETSLOG MIGRATING 命令,让源节点准备好将属于槽slot的键值对迁移至目标节点,底层由clusterState结构当中的migrating_slots_to字段表示
3. redis-trib向源节点发送CLUSTER GETKEYSINSLOT 命令,获得最多count个属于槽slot的键值对的键名
4. 对于步骤3获得的每个键名,redis-trib都向源节点发送一个MIGRATE 0 命令,将被选中的键原子的从源节点迁移至目标节点
5. 重复执行步骤3和步骤4,直到源节点中保存的所有属于槽slot的键值对都被迁移到目标节点位置
6. redis-trib向集群中的任意一个节点发送CLUSTER SETSLOT NODE 命令,将槽slot指派给指定目标节点,这一指派信息会通过消息发送至整个集群,最终集群中的所有节点都会知道slot已经指派给了目标节点
在迁移的过程中,当客户端向源节点发送一个与数据库键有关的命令,并且命令要处理的数据库键恰好就位于正在被迁移的槽时:如果源节点有,直接返回,如果没有,返回ASK错误,让客户端去目标节点操作,个人觉得这个跟redis的rehash比较像


喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址