Redis学习16-Redis集群概念、分片

Redis集群 (Cluster)

基本概念

哨兵模式,提高了系统的可用性。但是真正用来存储数据的还是 master 和 slave 节点。所有的数据都需要存储在单个 master 和 slave 节点中。

如果数据量很大,接近超出了 master / slave 所在机器的物理内存,就可能会有严重问题。

大量数据一台机器搞不定了,用多台机器来搞。

Redis 的集群就是在上述的思路之下,引入多组 Master / Slave,每一组 Master / Slave存储数据全集的一部分 ,从而构成一个更大的整体,称为 Redis 集群 (Cluster)。

假定整个数据全集是 1 TB,引入三组 Master / Slave 来存储。那么每一组机器只需要存储整个数据全集的 1/3 即可。
在这里插入图片描述

Master1 和 Slave11 和 Slave12 保存的是同样的数据,占总数据的 1/3

Master2 和 Slave21 和 Slave22 保存的是同样的数据,占总数据的 1/3

Master3 和 Slave31 和 Slave32 保存的是同样的数据,占总数据的 1/3

这三组机器存储的数据都是不同的

每个 Slave 都是对应 Master 的备份(当 Master 挂了,对应的 Slave 会补位成 Master)。

每组都可以称为是一个分片 (Sharding)

如果全量数据进一步增加,再增加更多的分片,就可解决。

数据分片算法

Redis cluster 的核心思路是用多组机器来存数据的每个部分。那么接下来的核心问题就是,给定一个数据(一个具体的 key),那么这个数据应该存储在哪个分片上?读取的时候又应该去哪个分片读取?

1) 哈希求余

设有 N 个分片,使用 [0, N-1] 这样序号进行编号。

针对某个给定的 key,先计算 hash 值,再把得到的结果 % N,得到的结果即为分片编号。

例如,N 为 3。给定 key 为 hello,对 hello 计算 hash 值(比如使用 md5 算法),得到的结果为 bc4b2a76b9719d91 ,再把这个结果 % 3,结果为 0,那么就把 hello 这个 key 放到 0 号分片上。

后续如果要取某个 key 的记录,也是针对 key 计算 hash ,再对 N 求余,就可以找到对应的分片编号

优缺点:

优点:简单高效,数据分配均匀。

缺点:一旦需要进行扩容,N 改变了,原有的映射规则被破坏,就需要让节点之间的数据相互传输,重新排列,以满足新的映射规则。需要搬运的数据量多,开销大。

2) 一致性哈希算法

为了降低上述的搬运开销,能够更高效扩容

key 映射到分片序号的过程不再是简单求余了,而是如下:

第一步,把 0 -> 2^32-1 这个数据空间,映射到一个圆环上。数据按照顺时针方向增长。
在这里插入图片描述

第二步,假设当前存在三个分片,就把分片放到圆环的某个位置上。
在这里插入图片描述

第三步,假定有一个 key,计算得到 hash 值 H,那么这个 key 映射到哪个分片呢?规则很简单,就是从 H 所在位置,顺时针往下找,找到的第一个分片,即为该 key 所从属分片。
在这里插入图片描述

这就相当于,N 个分片的位置,把整个圆环分成了 N 个管辖区间。Key 的 hash 值落在某个区间内,就归对应区间管理。
在这里插入图片描述

扩容处理

如果扩容一个分片。只需要把 0 号分片上的部分数据,搬运给 3 号分片即可。1 号分片和 2 号分片管理的区间都是不变的

优缺点:

优点:降低了扩容时数据搬运的规模,提高了扩容操作的效率

缺点:数据分配不均匀

3) 哈希槽分区算法 (Redis 使用)

解决了开销大 和 数据分配不均匀的一种算法(hash slots)

hash_slot = crc16(key) % 16384

crc16 是一种 hash 算法

16384 其实是 16 * 1024,也就是 2^14。

相当于是把整个哈希值,映射到 16384 个槽位上,也就是 [0, 16383]。

然后再把这些槽位比较均匀的分配给每个分片。每个分片的节点都需要记录自己持有哪些分片。

假设当前有三个分片,一种可能的分配方式:

  • 0 号分片:[0, 5461],共 5462 个槽位

  • 1 号分片:[5462, 10923],共 5462 个槽位

  • 2 号分片:[10924, 16383],共 5460 个槽位

这里的分片规则是很灵活的。每个分片持有的槽位也不一定连续。
每个分片的节点使用 位图 来表示自己持有哪些槽位。对于 16384 个槽位来说,需要 2048 个字节(2KB)大小的内存空间表示。

如果需要进行扩容,比如新增一个 3 号分片,就可以针对原有的槽位进行重新分配。

比如可以把之前每个分片持有的槽位,各拿出一点,分给新分片。

一种可能的分配方式:

  • 0 号分片:[0, 4095],共 4096 个槽位

  • 1 号分片:[5462, 9557],共 4096 个槽位

  • 2 号分片:[10924, 15019],共 4096 个槽位

  • 3 号分片:[4096, 5461] + [9558, 10923] + [15019, 16383],共 4096 个槽位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值