Skip to main content

Cluster:数据分片

David LiuAbout 5 min

Cluster:数据分片

Redis Cluster 通过 分片(Sharding) 来进行数据管理,提供 主从复制(Master-Slave Replication)、故障转移(Failover) 等开箱即用的功能,可以非常方便地帮助我们解决 Redis 大数据量缓存以及 Redis 服务高可用的问题。

虽说 Redis Cluster 可以扩展到 1000 个节点,但强烈不推荐这样做,应尽量避免集群中的节点过多。这是因为 Redis Cluster 中的各个节点基于 Gossip 协议 来进行通信共享信息,当节点过多时,Gossip 协议的效率会显著下降,通信成本剧增。

节点建议最多1000个节点

16384

  • Redis集群支持多个Master,每个Master.又可以挂载多个Slave
  • 由于Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能
  • 客户端与Redis的节点连接,♪不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可
  • 槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系

集群算法

  • redis 集群的槽位 slot
  • redis 集群的分片
  • 他两的优势
  • slot 槽位映射,一般业界有 3 种解决方案
  • 经典面试题
  • 为什么 redis 集群的最大槽数是 16384 个?
  • Redis:集群不保证强一致性,这意味着在特定的条件下,Redis 集群
  • 可能会丢掉一些被系统收到的写入请求命令
  • 集群的密钥空间被分成 16384 个槽,有效地设置了 16384 个主节点
  • 的集群大小上限(但是,建议的最大节点大小约为 1000 个节点)。

哈希槽,CRC16 校验对 16384 取模

这种结构很容易添加或者删除节点.比如如果我想新添加个节点 D,我需要从节点 A,B,C 中得部分槽到 D 上.如果我想移除节点 A,需要将 A 中的槽移到 B 和 C 节点上,然后将没有任何槽的 A 节点从集群中移除即可.由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态

哈希分区

哈希取余分区

如果数量变动,就会故障不可用

一致性哈希算法分区

步骤

构建一致性哈希环:0-2^32-1

节点映射:redis 服务器 ip 节点映射

落键规则:当我们需要存储一个 kv 键值对时,首先计算 key 的 hash 值,hash(key),将这个 key 使用相同的函数 Hash 计算出哈希值并确定此数据在环上的位置从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储在该节点上。

优点

容错性:只影响宕机的这一台的数据,且这些数据将来也会转移到下一台去存储

扩展性:增加节点不需要哈希重新计算

缺点

Hash 环的数据倾斜问题:一致性 Hsh 算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题

哈希槽分区

哈希槽实质就是一个数组,数组[0,2^14-1]形成 hash slot 空间。

能干什么

解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

Redis Cluster 通常有 16384 个哈希槽 ,要计算给定 key 应该分布到哪个哈希槽中,我们只需要先对每个 key 计算 CRC-16(XMODEM) 校验码,然后再对这个校验码对 16384(哈希槽的总数) 取模,得到的值即是 key 对应的哈希槽。

在消息头中最占空间的是 myslots[CLUSTER SLOTS/8]。当槽位为 65536 时,这块的大小是:65536÷8÷1024=8kb

在消息头中最占空间的是 myslots[CLUSTER SLOTS/8]。当槽位为 16384 时,这块的大小是:16384÷8÷1024=2kb

因为每秒钟,redis 节点需要发送一定数量的 ping 消息作为心跳包,如果槽位为 65536,这个 ping 消息的消息头太大了,浪费带宽。

(2)redis 的集群主节点数量基本不可能超过 1000 个。

集群节点越多,心跳包的消息体内携带的数据越多。如果节点过 1000 个,也会导致网络拥堵。因此 redis 作者不建议 redis cluster 节点数量超过 1000 个。那么,对于节点数在 1000 以内的 redis cluster 集群,16384 个槽位够用了。没有必要拓展到 65536 个。

(3)槽位越小,节点少的情况下,压缩比高,容易传输

Redis 主节点的配置信息中它所负责的哈希槽是通过一张 bitmap 的形式来保存的,在传输过程中会对 bitmap 进行压缩,但是如果 bitmap 的填充率
slots/N 很高的话(N 表示节点数),bitmap 的压缩率就很低。如果节点数很少,而哈希槽数量很多的话,bitmap 的压缩率就很低。

不保证强一致性

节点挂了会写丢失