为了解决Redis单机的内存流量瓶颈,出现了Redis Cluster分布式解决方案
同时也引入了两个问题
1. 数据分区规则制定
2. 集群扩容&集群收缩解决
常见的分区规则有哈希分区和顺序分区。Redis Cluster采用了哈希分区。
![](https://box.kancloud.cn/85e79a24b7160077357f7cd7d59b65c5_650x467.png)
常见的哈希分区规则有 **节点取余分区**,**一致性哈希分区**,**虚拟槽分区**
## 节点取余分区
> 计算公式:hash(key) % N
优点是使用方便,缺点是扩容或者收缩节点时,需要重新生成节点数据。
![](https://box.kancloud.cn/cb4100337748fcdc74ef15ed13787596_710x730.png)
## 一致性哈希分区
> 给每个节点分配一个token,取值范围在1~2^32,这些token构成了一个哈希圆环。进行数据读写时,根据key计算hash值,顺时针查找第一个大于该hash值的token节点。
* 相比节点取余分区,一致性哈希分区在添加删除节点时,只会影响指定节点的相邻节点。
* 当哈希圆环中的节点数量过少时,节点数量变化影响的数据面更广。
* 想要在节点数量变化的同时保证负载均衡,需要增加或者减少一倍的节点数。
![](https://box.kancloud.cn/74a414d5dbc3381311ab13353a7cdb08_687x557.png)
## 虚拟槽分区
通过哈希算法将key均匀的映射到指定范围的整数,整数定位为槽(slots)。每个节点负责指定数量的槽。比如Redis Cluster的槽范围时0~16383。
计算公式:slot = CRC16(key)&16383 。
> 在key和节点之间新增了一层代理(slot),节点数量发生变化时,只对槽和节点的映射关系做变更,实现了跟客户端的解耦。
![](https://box.kancloud.cn/c4c46b0af3e8f216decbf182368aa7a6_720x525.png)
## 分布式方案突破了单机的内存CPU限制的同时,也带来了一些问题
* mget,mset命令只支持具有相同slot值的key。
* 事务操作只支持处于同一节点上的key
*