当前位置: 首页 > news >正文

redis的集群中的简单问题

前面讲的无论是主从复制,还是哨兵+主从模式,其中要求一个主节点,就得储存整个数据的“全集”。假如有1TB的数据需要储存,我们可以用多台机器来存,随着机器数目的增加,每个机器储存的数据量就减少了。

集群把数据分成多份,有三种分法:

1.哈希求余:

这是最简单直接的分片算法,借鉴了哈希表的基本思想,借助hash函数,把一个key映射到整数,再针对数组的长度求余,就可以得到一个数组下标。

步骤1:计算数据键key的hash值,比如用MD5,SHA等哈希函数。

步骤2:对hash值取模(hash(key)%n,其中n是节点数量),结果是数据应分配的节点索引。

比如有0,1,2三个节点。假如有哈希值100-120

但如果需要扩容时,hash(key)%n(n是节点数量)的结果会发生剧烈改变,基本上大部分的节点都会发生改变。如下图:

一共二十个数据,只有三个数据不需要搬运。如果是20亿的数据,那就要搬动17亿的数据,这是一个非常恐怖的数据。

哈希求余的优点和缺点:

优点:

实现简单:靠hash+取模,逻辑直观。

均衡性好:如果hash函数分配均匀,那么每个节点所分配的数据也是很均衡的。

缺点:

当节点n变化,hash%n的结果也会发生剧烈的改变,那么在扩容的时候,就会有大量数据迁移。服务暂时不可用。

2.一致性哈希算法:

为了避免大量数据的迁移,这就有了一致哈希算法。核心是将数据和节点映射到环形的空间中,最小化节点变动的影响。

基本原理:

1.构建哈希环:

将0-2^32-1想象成一个闭合的圆环(哈希环)

2.将节点映射到哈希环中:

3.将数据映射到环上,并找到归属节点:

数据通过hash函数映射到环上的具体位置,然后根据顺时针查找遇到的第一个分片,就是归属节点。

4.扩容时,再增加一个分片:

最开始,红色区域的包含的数据都归于0号分片,但是当扩容后,新增了3号分片之后,就不会迁移大量数据,只需要迁移绿色区域的数据给3号分片即可。

一致性哈希算法的优点和缺点:

优点:

节点变动影响小:仅影响新增节点前后的数据,无需移动全量数据。

支持动态扩容:可以按需增加节点数量。

缺点:

最大的问题就是哈希环上节点分配不均问题,导致部分节点负载过高。

3.哈希槽分区算法(redis采用的方法):

核心原理“哈希槽”:

redis集群将所有数据划分为16384个槽,然后每个键值对都会根据键名映射到对应的哈希槽上。每个哈希槽由集群中的主节点进行管理和储存。

哈希映射规则:

1.先对键使用CRC16算法计算哈希值(CRC16(key))

2.将哈希值对16384取模,(CRC16(key)%16384),得到的结果就是该键所属的哈希槽。

哈希槽和节点的关系:

集群中的每个主节点都会负责一部分哈希槽的管理和储存。

例如:

0号分片:负责【0,5461】这部分的哈希槽,总共5462个槽

1号分片:负责【5462,10923】这部分哈希槽,总共5462个槽

3号分片:负责【10924,16383】这部分哈希槽,总共5462个槽。

注意:每个分片都通过“位图”这样的数据结构,表示当前分片有什么槽位。用0/1来区分这个分片是否拥有该槽位。大概每个分片只需要2kb就够了。

扩容时:

当新增一个分片后

0号分片:【0,4095】,共4096个槽位

1号分片;【5462,9557】,共4096个槽位

2号分片:【10924,15019】,共4096个槽位

3号分片:【4096,5461】+【9558,10923】+【15019,16383】,共4096个槽位。

在上述过程中,也只有被移动的槽位对应的数据需要搬动,这样的迁移的数据不会很多。redis可以手动配置,当前某个分片包含哪些槽位。

问题1:Redis集群中最多有16384个分片吗?

极端的情况,如果每个分片只管理一个槽,那最多支持16383个分片

但实际情况中,是不会用这么多分片的,因为管理成本高,性能瓶颈,资源浪费。

Redis官方建议分片数不能超过1000个。

问题2:Redis为什么是16384个槽:

因为16384个槽的位图足够小,既能满足分片需求,又能最小化内存和网络开销。

集群故障判定:

故障判定有三个阶段:

1.疑似下线:

单个节点通过心跳包检测,发现其他节点疑似故障。

检测机制:集群中所有节点通过Gossip协议互相发送心跳消息,包含自身状态和对其他节点的感知

触发条件:当节点A超过配置时间,还未收到来自节点B的心跳响应,则节点A会将节点B标记为“疑似下线(PFAIL)”,更新本地状态,这只是主观下线,并没有客观下线。

2.故障报告:

疑似下线的状态通过Gossip协议在集群中传播,让其他节点知晓。其他节点收到消息后,若自身也疑似B节点下线,然后也会更新本地状态。若未发现异常,暂不做处理。

3.确认下线:

触发条件:如果其中一个主节点X发现,超过集群中一半以上的主节点都将节点B标记为PFAIL,则节点X会将节点B的PFAIL状态升级为FAIL。这时代表节点B客观下线。

广播通知:节点X会向所有节点广播一条“节点B已经下线(FAIL)”,然后所有节点就会改变本地的状态为FAIL。

故障迁移:

如果下线的是从节点,就不需要故障的迁移。

如果下线的是主节点,此时就由B的从节点C和D触发故障迁移了。

1.从节点会先判断自己是否有资格参选主节点。如果从节点和主节点已经太久没有通信了(此时认为从节点的数据和主节点的数据差异太大了),时间超过阈值,就会失去参选资格。

2.具有资格的节点C和D,先会休眠一段时间(500ms的挤出时间+【0,500ms】的随机时间+排名*1000ms),offset越大,排名越靠前(越小)。

3.比如节点C的休眠时间到了,C就会给其他所有集群中的节点,进行拉票操作(只有主节点才有投票资格)。

4.主节点会把自己的票投给节点C,当节点C的票数超过主节点的数目一半,节点C就会晋升成为主节点。

5.C自己负责自己的slaveof no one,节点D执行slaveof C,同时C还会把自己成为主节点的消息,同步给其他的节点,大家也会更新自己保存的集群结构信息。

http://www.dtcms.com/a/457428.html

相关文章:

  • 托福阅读+听力【2】
  • 技术与情感交织的一生 (十四)
  • Linux 高手进阶:Vim 核心模式与分屏操作详解
  • 计组2.2.0——逻辑门电路,多路选择器,三态门
  • intellij 网站开发公司网页制作哪家比较好
  • 基于GD32的RT-Thread移植(邪修版)
  • 如何让百度口碑收录自己的网站怎么用vs2015做网站
  • 2017优秀网站设计案例个人域名备案有什么风险
  • [论文阅读] AI+软件工程(需求工程)| 告别需求混乱!AI-native时代,需求工程的5大痛点与3大破局方向
  • WPF基本布局容器与控件
  • 临时需电子印章?无需下载注册生成高清印章
  • Qt基础之五十:Qt设置样式的几种方式
  • 理解Roo Code的速率限制与成本优化
  • 农村建设集团有限公司网站重庆南川网站制作价格
  • 爬虫调试技巧:常用工具与日志分析,快速定位问题
  • 反向代理和负载均衡
  • 水果网站设计论文网页传奇游戏中心
  • 兰州网站建设lst0931wordpress调用函数大全
  • JavaScript核心构成与基础语法详解1
  • Redission分布式锁、WatchDog续约、布隆过滤器
  • 《jQuery 捕获》
  • 【开题答辩全过程】以 阿歹果园养鸡场管理系统为例,包含答辩的问题和答案
  • 【数据结构】考研数据结构核心考点:二叉排序树(BST)全方位详解与代码实现
  • 河北做网站哪家公司好广州市网站建设公
  • AI学习日记——卷积神经网络(CNN):卷积层与池化层的概念
  • JavaScript中的axios
  • 我们提供的网站建设响应式网站 尺寸
  • Robotframework 并发执行
  • 兰州拼团网站建设网站建设知识点的总结
  • 做门窗的建网站怎么赚钱网页设计图片怎么变小