集群结构
特点:
1 所有 Redis 节点 (包括主和从) 彼此互联(两两通信), 底层使用内部的二进制传输协议, 优化传输速度;(所有功能特点的基础)
2 集群中也有主从, 也有高可用的逻辑, 但是没有哨兵进程, 整合到主节点的功能里了; 集群中的事件被主节点(大部分主节点); 通过主节点的过半选举实现哨兵以前的逻辑;
3 客户端与 Redis-cluster 连接, 无需关心分片的计算, 客户端不在关心分片的计算逻辑, 内部分发分布式数据(内部有分片计算逻辑), 客户端将 key 交给 Redis 节点后, 集群内部判断 key 值的正确存储位置, 转发存储;
4 Redis-cluster 把所有的主节点对应到 [0-16383] 整数区间 -- 槽道 slot; 各自的主节点维护一批槽道号(0-5000,5001-10000,10001-16383); 在分片计算时, 对 key 值做 hash 取模运算(就是取余, 不在使用 hashCode,CRC16);key 值对应的取模运算结果, 将会判断由哪个节点维护; 将 key--slot--node, 如果我们想要迁移某个 key 值, 必须将对应的 slot 一并迁移;
核心概念操作的工作原理
存储获取值时的转发逻辑
槽道迁移, 数据 key 迁移
Redis 的集群槽道原理
槽道原理抛 2 个问题:
1 节点接收数据计算槽道号后, 如何判断当前槽道号是否归我管?
2 判断不归本节点管理时, 如何获取正确管理者信息
槽道逻辑结构
槽道是一种计算逻辑
计算逻辑:
○ 二进制 16384 位的位序列可以实现当前节点判断槽道号管理权的逻辑;(16384 位二进制就是 2048 个元素的 byte 数组)
计算二进制, 获取人为定义的二进制下标号(人为定义, 计算位移计算), 每一位的下标号对应二进制(1/0), 与下标号一直的槽道号到底归不归当前节点管理, 是通过下标对应的二进制值判断 1 表示管理 true,0 表示不管理 false;
特点:
1 每个主节点都管理一批槽道, 每个主节点的 16384 位的二进制不一样
2 从节点和没有槽道管理权的主节点的二进制是全是 0
模拟获取二进制下标和对应二进制值的代码(byte):
- @Test
- public void test(){
- byte a=55;
- // 假设, 这个 byte 二进制代表位序列中第一个 byte
- System.out.println(Integer.toBinaryString(a));
- // 获取定义的 0 号下标对应的二进制
- for(int i=0;i<8;i++){
- // 第一次移动 7 位, 第二次移动 6, 第三次移动 5
- int move=8-i-1;
- int result=(a>>move)&1;
- System.out.println("当前"+i+"号下标对应的二进制"+result);
- }
- }
○ 索引数组
16384 个元素的数组, 下标 0-16383, 每个下标对应的元素引用的变量, 指向内存中一个保存下标对应槽道号管理者的索引节点信息;
总结: 存入数据时, 首先对存入的 key 值进行取模运算, 通过计算, 得到 key 值对应的槽道(16384 个槽道, 其实是一个 16389 个元素索引数组, 每个数组元素变量保存着相对应槽道号管理者的节点信息), 获取槽道信息, 根据对应槽道号数组元素变量的信息找到对应的主节点, 并将数据存入主节点;
如何找到槽道号相对应的主节点??? 底层是根据二进制计算得出, 是由 16384 个二进制位找到主节点的槽道号, 并将主节点的相关信息保存在槽道号对应数组元素的变量中. 当有数据存入或者取出时, 计算 key 值得槽道号, 找到对应的数组元素, 通过这个数组元素中节点的信息, 找到节点, 进行存取操作.
Redis 集群的命令
集群
cluster info : 打印集群的信息
cluster nodes : 列出集群当前已知的所有节点( node), 以及这些节点的相关信息.
节点
cluster meet <ip> <port> : 将 ip 和 port 所指定的节点添加到集群当中, 让它成为集群的一份子.
cluster forget <node_id> : 从集群中移除 node_id 指定的节点(保证空槽道).
cluster replicate <node_id> : 将当前节点设置为 node_id 指定的节点的从节点.
cluster saveconfig : 将节点的配置文件保存到硬盘里面.
槽(slot)
cluster addslots <slot> [slot ...] : 将一个或多个槽 ( slot) 指派 ( assign) 给当前节点.
cluster delslots <slot> [slot ...] : 移除一个或多个槽对当前节点的指派.
cluster flushslots : 移除指派给当前节点的所有槽, 让当前节点变成一个没有指派任何槽的节点.
cluster setslot <slot> node <node_id> : 将槽 slot 指派给 node_id 指定的节点, 如果槽已经指派给
另一个节点, 那么先让另一个节点删除该槽>, 然后再进行指派.
cluster setslot <slot> migrating <node_id> : 将本节点的槽 slot 迁移到 node_id 指定的节点中.
cluster setslot <slot> importing <node_id> : 从 node_id 指定的节点中导入槽 slot 到本节点.
cluster setslot <slot> stable : 取消对槽 slot 的导入 ( import) 或者迁移( migrate).
键
cluster keyslot <key> : 计算键 key 应该被放置在哪个槽上.
cluster countkeysinslot <slot> : 返回槽 slot 目前包含的键值对数量.
cluster getkeysinslot <slot> <count> : 返回 count 个 slot 槽中的键
来源: https://www.cnblogs.com/nanlinghan/p/9939161.html