前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Redis设计与实现》读书笔记(二十九) ——Redis集群执行命令与重新分片

《Redis设计与实现》读书笔记(二十九) ——Redis集群执行命令与重新分片

作者头像
用户1327360
发布2018-03-07 16:14:27
9300
发布2018-03-07 16:14:27
举报
文章被收录于专栏:决胜机器学习

《Redis设计与实现》读书笔记(二十九) ——Redis集群执行命令与重新分片

(原创内容,转载请注明来源,谢谢)

一、集群中执行命令

1、节点对命令的判断

当对集群的16384个槽都完成指派后,集群就上线,可以对集群进行操作。当客户端向节点发送数据库键有关的命令,接收命令的节点,会计算命令属于哪个槽,并检查槽是否指派给自己。

如果槽是该节点负责,则执行命令;如果不是,返回一个moved错误,指引客户端对正确的节点执行命令,客户端根据返回结果,会自动连接上相应的节点,再次执行命令。

2、计算键属于哪个槽

假设键名为key,计算方法如下:

crc16(key) & 16383

其中,crc16是一种算法,将key用crc16算法获取的结果,在与16383进行比较,获取一个介于0~16383的整数。

可以采用cluster keyslotkey,查看键属于哪个槽。

3、判断槽是否由当前节点处理

根据上述算法计算出键所述的槽后,节点会与clusterState的slots相应下标的指针比对:

如果指针指向自身则表示该槽由自身负责;

如果指针不是指向自身,而是指向某个节点的clusterNode结构,则从该结构获取ip和端口号,并将ip、端口号、moved错误一并返回给客户端。

4、moved错误介绍

move命令为:moved<slot> <ip> <port>

当客户端收到moved命令,就会解析里面的ip和端口号,并重新连上相应的节点,再执行命令。

不过,由于moved错误的时候,处于集群状态下的redis-cli客户端会自动重定向,显示的也是redirect,因此客户端上看不到报错信息。

但是,如果是单机模式下的redis-cli客户端,则会直接报错,因为其并不知道moved命令的含义,也不会自动连接上新的节点。

5、节点数据的实现

集群节点有个限制,只能用0号数据库。键值对的保存方式和单机一样。另外,节点的clusterState结构,还会保存槽和键的关系。

代码语言:javascript
复制
         typedef structclusterState{
         //….其他内容
         zskiplist*slots_to_keys;

}clusterState;

节点保存槽和键的关系,用的是zskiplist,其分值(score)是槽的编号,每个阶节点成员(member)是数据库的键。如下:

将键这样保存,便于批量操作。例如cluster getkeysinslot <slot> <count>命令(重新分片相关命令),可以返回最多count个,槽是slot的键。

二、重新分片

1、概述

redis集群的重新分片功能,可以将任意数量已经指派给某个节点的槽,修改为指派给另一个节点,且相关槽对应的数据库的键值对数据也迁移到另一个节点。

重新分片工作可以在线进行,集群不需要下线,并且源节点和目标节点都可以正常处理客户端的其他命令。

2、原理

redis重新分片,是由redis集群管理软件redis-trib负责执行的,redis提供了进行重新分配所需的所有命令。而redis-trib软件通过向源节点和目标节点发送命令,来完成重新分片的工作。

对单个槽进行重新分片,步骤如下:

1)redis-trib对目标节点发送命令clustersetslot <slot> importing <source_id>命令,让目标节点准备好从源节点导入编号是slot的槽的键值对。

2)redis-trib对源节点发送命令clustersetslot <slot> migrating <target_id>命令,让源节点准备好将编号是slot的槽的键值对导入到目标节点。

3)redis-trib向源节点发送命令clustergetkeysinslot <slot> <count>命令,获取最多count个属于槽slot的键值对的键。

4)对于第3步的每个键,redis-trib都向源节点发送命令migrate<target_ip> <target_port> <key_name> 0 <timeout>命令,将被选中的键迁移到目标节点。

5)重复3、4步骤,直到所有属于编号slot的槽都完成迁移。

6)redis-trib将命令clustersetsslot <slot> node <target_id>发送给集群中的任一节点,然后命令会在集群中广播,所有节点都会知道槽slot已经归目标节点负责。

如果是多个槽重新分片,则每个槽都会经历上述的步骤进行重新分片。

—written by linhxx 2017.09.15

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 决胜机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档