目录

目录 1

1. 前言 1

2. 槽(slots) 1

3. 路由配置(node.conf) 1

4. 总slots数(cluster.h:16384) 2

5. key的路由 2

6. 将key转成整数值(crc16.c:crc16) 2

7. 计算key所在slot(cluster.c:keyHashSlot)
2

8. Redis Cluster Client实现 3

1. 前言

截至2016/5/16最新版本的redis-3.2.0仍然非强一致性,基于性能考虑master和它的slaves间数据是异步复制的。另外,一个确定的key总是只会落到确定的master,除非使用redis-trib.rb等工具修改slots和master间的绑定关系,目前的redis cluste不支持自动从一个master迁移一个slot到另一个master(slaves对slots来说,可以认为和对应的master相同)。

2. 槽(slots)

Redis cluster将所有存储在其上的key通过一个hash算法划分成若干slots,当前为个slots,值在cluster.h文件中由宏CLUSTER_SLOSTS指定。

3. 路由配置(node.conf)

存储的内容和redis命令“cluster nodes”的输出相同,即存储了master和slave信息,以及各master存储的slots,亦即slots的路由信息存储在node.conf。

同一Redis cluster中的所有节点的node.conf文件内容最终是一致的。

4. 总slots数(cluster.h:16384)

#define CLUSTER_SLOTS  // 等于(0x3FFF + 1)

宏CLUSTER_SLOTS定义了redis cluster的slots数,理论上这个值应当可以修改重编译。其值越大,相对更容易均衡,可支撑更多节点数的集群(实际受限于无中心节点,当然架构的redis cluster节点数不宜过大,否则可能引起网络风暴)。

5. key的路由

-> 将key转成整数值

-> 计算key所在的slot

-> 找到slot所在的master或slaves(redis cluster可配置允许slaves提供读)

-> 转成直接对master或slaves的请求。

由于任何一个redis cluster节点都存储了相同内容的node.conf,所以client可以请求任一节点获得slots的路由数据。

而且由于node.conf中包含了master和slaves信息,因此读写操作可以完美的路由到相应的节点。

6. 将key转成整数值(crc16.c:crc16)

Redis使用crc算法将一个字符串转成整数,宏CLUSTER_SLOTS的值是不能超过CRC返回的最大值。

uint16_t crc16(const char *buf, int len) {

int counter;

uint16_t crc = 0;

for (counter = 0; counter < len; counter++)

crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF];

return crc;

}

7. 计算key所在slot(cluster.c:keyHashSlot)

对于一个redis KEY它归属于哪一个slot,这个可以通过函数keyHashSlot()调用计算出来:

unsigned int keyHashSlot(char *key, int keylen) {

int s, e; /* start-end indexes of { and } */

for (s = 0; s < keylen; s++)

if (key[s] == '{') break;

/* No '{' ? Hash the whole key. This is the base case. */

if (s == keylen) return crc16(key,keylen) & 0x3FFF;

/* '{' found? Check if we have the corresponding '}'. */

for (e = s+1; e < keylen; e++)

if (key[e] == '}') break;

/* No '}' or nothing betweeen {} ? Hash the whole key. */

if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;

/* If we are here there is both a { and a } on its right. Hash

* what is in the middle between { and }. */

return crc16(key+s+1,e-s-1) & 0x3FFF; // 3FFF即为16383

}

8. Redis Cluster Client实现

通过上面的信息,不然发现,Redis Cluster Client只是在原来单机版client基础上多了一层薄的路由逻辑。因此可以基于现有的hiredis等实现支持redis cluster的client库。大致过程如下:

class CRedisClusterClient

{

public:

// nodes Redis集群中的单个或多个节点,格式为:ip1:port1,ip2:port2,如:127.0.0.1:6379,127.0.0.1:6380,192.168.31.11:6379

CRedisClusterClient(const std::string& nodes);

void set(const std::string& key, const std::string& value) const;

void get(const std::string& key, std::string* value);

private:

redisContext* _redis_context; // hiredis

};

set()函数实现:

1) CRedisClusterClient从nodes取任一nodeA,如:127.0.0.1:6380

2) 建立与nodeA的连接

3) 从nodeA取得slots路由数据(实现时可缓存这部分数据,以提升性能)

4) 构造slots路由数据表(由于slots总数有限,可以以slot为下标数组方式组织路由表)

5) 计算key所在的slot

6) 找到slot所在的nodeB(对于写操作,要求nodeB为master,有可能碰巧就是nodeA)

7) 使用hiredis访问nodeB(从这步开始和原使用hiredis相同)

8) 取得hiredis返回的结果

如果使用hiredis发生网络异常,对于写操作从第3步开始重执行,对于读操作从第6步重选一个node重执行。

Redis Cluster原理初步的更多相关文章

  1. 全面剖析Redis Cluster原理和应用

    全面剖析Redis Cluster原理和应用 1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最 ...

  2. Redis Cluster 原理相关说明

    背景 之前写的 Redis Cluster部署.管理和测试 和 Redis 5.0 redis-cli --cluster help说明 已经比较详细的介绍了如何安装和维护Cluster.但关于Clu ...

  3. Redis Cluster 原理说的头头是道,这些配置不懂就是纸上谈兵

    Redis Cluster 原理说的头头是道,这些配置不懂就是纸上谈兵 Redis Cluster 集群相关配置,使用集群方式的你必须重视和知晓.别嘴上原理说的头头是道,而集群有哪些配置?如何配置让集 ...

  4. 全面剖析Redis Cluster原理和应用 (转)

    1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最核心的目标有三个: 性能:这是Redis赖以生 ...

  5. 全面剖析Redis Cluster原理和应用 (good)

    redis redis cluster注意的问题 : 1.‘cluster-require-full-coverage’参数的设置.该参数是redis配置文件中cluster模式的一个参数,从字面上基 ...

  6. 深度图解Redis Cluster原理

    不想谈好吉他的撸铁狗,不是好的程序员,欢迎微信关注「SH的全栈笔记」 前言 上文我们聊了基于Sentinel的Redis高可用架构,了解了Redis基于读写分离的主从架构,同时也知道当Redis的ma ...

  7. Redis Cluster原理

    Redis Cluster 是Redis的集群实现,内置数据自动分片机制,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写. ...

  8. Redis Cluster部署、管理和测试

    背景: Redis 3.0之后支持了Cluster,大大增强了Redis水平扩展的能力.Redis Cluster是Redis官方的集群实现方案,在此之前已经有第三方Redis集群解决方案,如Twen ...

  9. Redis Cluster架构优化

    Redis Cluster架构优化 在<全面剖析Redis Cluster原理和应用>中,我们已经详细剖析了现阶段Redis Cluster的缺点: 无中心化架构 Gossip消息的开销 ...

随机推荐

  1. ubuntu 16.04 install wine

    from: https://wiki.winehq.org/Ubuntu If your system is 64 bit, enable 32 bit architecture (if you ha ...

  2. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 规范与部署

    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923889450 规范与部署 懒人推动社会进步. 本篇中,我们会讲述三个知识点 定制书写规范 开发环境运行 如何 ...

  3. [转载]百分之百自动登录2345王牌技术员联盟源代码(delphi)

    资源地址:http://download.csdn.net/detail/softlib/9670613

  4. SQL 数据库主键 ,外键

    主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通过定义 PRIMARY KEY约束来创建主键.一个 ...

  5. Android Studio 连接天天、海马、逍遥模拟器

    adb connect 127.0.0.1:6555 取消连接 adb disconnect 127.0.0.1:6555 连接海马模拟器(未测试)  adb connect 127.0.0.1:26 ...

  6. select 1 与 select null (转)

    1.Select 1 在这里我主要讨论的有以下几个select 语句: table表是一个数据表,假设表的行数为10行,以下同. 1:select  1 from table 2:select cou ...

  7. jquery读取本地文件,Windows上报错。XMLHttpRequest cannot load xxx. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.k.cors.a.c

    问题: 测试报告,使用本地的json.txt文件,结果文件读取失败,报错如下: XMLHttpRequest cannot load xxx. Cross origin requests are on ...

  8. webpack 构建同时适用于手机和电脑的调试服务器

    plugins plugins: [ new HtmlWebpackPlugin({ // 使用模板同时生成 pc.html和mobile.html title: 'pc', filename: 'p ...

  9. C#aspx页面前台使用<%=%>无法取到后台的值

    检查是不是有拼接问题,正常public和protected修饰的字段或属性均可使用<%=%>.另外,加载(Page_Load)时有没有给它们赋初始值? 答 1)前台页面只能调用本后置代码的 ...

  10. Linux Shell 文本处理工具集锦(转载)

    内容目录: find 文件查找 grep 文本搜索 xargs 命令行参数转换 sort 排序 uniq 消除重复行 用tr进行转换 cut 按列切分文本 paste 按列拼接文本 wc 统计行和字符 ...