集群概念
上一篇我们讲到了哨兵模式,提高了系统的可用性,但是真正用来存储数据的还是master跟slave节点,所有的数据都需要存储在单个的master和slave节点中。
如果数据量很大,超出了节点所在机器的物理内存,就会出现严重问题了。
那如何获得更大的空间呢,加机器就可以,一台机器搞不定,就用多台机器。
Redis集群就是在上述的思路下,引入多组的master跟slave,每组的master跟slave存储数据全集的一部分,从而构成一个更大的集体,称为Redis集群。
假设整个数据全集是1TB,此时引入三组master跟slave,则每组机器只需存储整个数据全集的1/3即可,每个红框部分可以称为一个分片,如果全量数据进一步增加,只要再增加更多的分片就行。
数据分片算法
Redis集群的核心思路就是用多组机器来存数据的每个部分,那么就有一个核心问题:给定一个具体的key,那么整个数据应该存储到哪个分片上?读取的时候又应该去哪个分片读取呢?
针对这个问题,目前有三个比较主流的实现方式:
1.哈希求余
设由N个分片,用【0,N-1】的顺序编号;
针对某个给定的key,先计算hash值,再把得到的结果%N,得到的结果就是分片编号。
如上图所示。
此分片算法的优点:简单搞笑,数据分配均匀。缺点:一旦需要扩容,N改变了,原有的映射规矩就被破坏,就需要让节点之间的数据相互传输重新排序,则此时需要搬运的数据量事比较多的,开销较大。
2.一致性哈希算法
为了降低上述的搬运开销,能够更高效的扩容,所以提出了“一致性哈希算法”。
- 把0-2^32-1这个数据空间映射到一个圆环上,数据按照顺时针方向增长。
- 假设当前存在三个分片,就把分片放到圆环的某个位置上。
- 假定有一个key,计算得到hash值:h,那么整个key就会映射到所属分片上,就是从h所在位置顺时针往下找,找到第一个分片就是key所属的分片。
这就相当于n个分片位置把整个圆环分成了n个管辖区间,key的hash值落入某个区间就归对应区间管理。
此时如果扩容一个分片,就只需原有分片在环上的位置不懂,在环上安排一个新分片即可~
此时只需要把0号分片上的部分数据搬运给3号分片上即可,1号分片和2号分片的管理区间不变。
优点:大大降低了扩容时数据搬运的规模,提高了扩容操作的效率。
缺点:数据分配不均。
3.哈希槽分区算法
为了解决上述问题,redis集群引入了哈希槽算法。
- 节点之间通过⼼跳包通信. ⼼跳包中包含了该节点持有哪些 slots. 这个是使⽤位图这样的数据结构 表⽰的. 表⽰ 16384 (16k) 个 slots, 需要的位图⼤⼩是 2KB. 如果给定的 slots 数更多了, ⽐如 65536 个了, 此时就需要消耗更多的空间, 8 KB 位图表⽰了. 8 KB, 对于内存来说不算什么, 但是在频繁的⽹络⼼跳包中, 还是⼀个不⼩的开销的。
- 另⼀⽅⾯, Redis 集群⼀般不建议超过 1000 个分⽚. 所以 16k 对于最⼤ 1000 个分⽚来说是⾜够⽤ 的, 同时也会使对应的槽位配置位图体积不⾄于很⼤。
故障处理流程
1.故障判定
2.故障迁移
集群扩容
本篇博客只讲述集群扩容的步骤,具体流程暂不详述。
- 把新的主节点加入到集群。
- 重新分配slots,输入响应命令就会进入交互操作:
- 多少个slots要进行分配
- 哪个节点来接受这些slots
- 这些slots从哪些节点搬运过来
3.给新的主节点添加从节点。