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

《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结构,还会保存槽和键的关系。

         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

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏决胜机器学习

《Redis设计与实现》读书笔记(二十六) ——Redis哨兵(sentinel)启动与建立监听机制

《Redis设计与实现》读书笔记(二十六) ——Redis哨兵(sentinel)启动与建立监听机制 (原创内容,转载请注明来源,谢谢) 一、概述 哨兵(Sen...

3347
来自专栏码神联盟

分布式服务集群下实现session共享解决方案

随着互联网的日益壮大,网站的pv和uv成线性或者指数倍的增加.单服务器单数据库早已经不能满足实际需求。目前大多数大型网站的服务器都采用了分布式服务集群...

2938
来自专栏架构师之路

数据库中间件mysql-proxy细节【mysql官方的中间件】

一、mysql-proxy简介 mysql-proxy是mysql官方提供的mysql中间件服务,上游可接入若干个mysql-client,后端可连接若干个my...

3714
来自专栏xiaoheike

Elasticsearch Network Settings

Elasticsearch 缺省情况下是绑定 localhost。对于本地开发服务是足够的(如果你在相同机子上启动多个节点,它还可以形成一个集群),但是你需要配...

572
来自专栏转载gongluck的CSDN博客

UNPv13:#第4章#基于TCP套接字编程

概述 ? socket函数 #inlcude <sys/socket.h> int socket(int family, int type, int prot...

3408
来自专栏zcqshine's blog

PHP 下载文件

3735
来自专栏西安-晁州

oAuth2.0及jwt介绍

oAuth2.0流程示意如下: ? 关于jwt介绍: ? 说明: 关于jwt简单说明一下,jwt即为json web token,是用来和服务端建立加密通信所使...

1760
来自专栏顶级程序员

记一次惊心的网站TCP队列问题排查经历

此时问题已经影响到整个网站的正常业务,我的那个心惊的呀,最主要报警系统没有任何报警,服务运行一切正常,瞬时背上的汗已经出来了。但还是要静心,来仔细寻找蛛丝马迹,...

562
来自专栏性能与架构

linux防火墙iptables工作原理

防火墙对于系统安全至关重要,iptables则是防火墙的管理工具 iptables帮助我们定义各种验证规则,实现对网络的验证控制 数据包的传输过程 数据包...

3139
来自专栏Java帮帮-微信公众号-技术文章全总结

day03.集群部署zookeeper【大数据教程】

day03.集群部署zookeeper【大数据教程】 一、Nginx/keepalived/lvs的介绍 1. nginx 1.1. nginx简介 Ngin...

3888

扫描关注云+社区