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 个槽位


3231

被折叠的 条评论
为什么被折叠?



