什么是集群
官网地址
由于数据量过大,单个Master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展。每个数据集只负责存储整个数据集的一部分,这就是Redis的集群,其作用是提供在多个Redis节点间共享数据的程序集。
Redis集群可以支持多个Master,从哨兵到集群
哨兵
集群
能做啥
- Redis集群支持多个Master,每个Master又可以挂载多个Slave
-
- 读写分离
- 支持数据的高可用
- 支持海量数据的读写存储操作
- 由于Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能
- 客户端与Redis的节点连接,不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可
- 槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系
集群算法
槽位slot
Redis集群没有使用一致性hash,而是引入了哈希槽的概念。
集群的有16384个槽,有效地设置了16384个主节点的集群大小上限(但是官网建议的最大节点大小约为1000个节点),每个key通过CRC16 校验后对16384取模(HASH_SLOT = CRC16(key) mod 16384)来决定放置在哪个槽,集群的每个节点负责一部分hash槽(数据分片)。
当没有集群重新配置正在进行时(即哈希槽从一个节点移动到另一个节点),集群是稳定的。
当集群稳定时,单个哈希槽将由单个节点提供服务(但是,服务节点可以有一个或多个副本,在网络分裂或故障的情况下替换它,并目可以用于扩展读取陈旧数据是可接受的操作)
分片
使用Redis集群时,我们会将存储的数据分散到多台Redis机器上,这就是分片。换句话说,就是集群中的每个Redis实例都被认为是整个数据的一个分片。
那么如何找到给定key的分片呢?
即对key进行CRC16(key)算法处理并通过总分片数量取模,然后,使用确定性哈希函数,这意味着给定的key将始终映射到同一个分片,因此可以推断将来读取特定key的位置
使用槽位+分片的优势
最大优势:方便扩缩容 和数据分派查找
这种结构很容易添加或者删除节点。
举个例子🌰:
如果我想新添加个节点D,就需要从节点A、B、C中得部分槽到D上
如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可
由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态
槽位的映射方案
slot槽位映射,一般业界有3种解决方案:哈希取余分区、一致性哈希算法分区和哈希槽分区,我们一一来介绍下他们。
哈希取余分区
公式 hash(key)%n
- n 为机器台数
缺点
原来规划好的节点,进行扩容或者缩容就比较麻烦。不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化。
举个例子,2亿条记录就是2亿个k,v,单机不行就要考虑分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式hash(key)%N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。
如果原来有3台,增加了1台,就会从Hash(key)%3变成Hash(key)%4。
此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。即某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。
一个词总结 -> 不一致
于是我们有了👇 ------ 一致性哈希算法分区,敬请期待~~~