Redis集群

什么是集群?

广义的集群,只要你是多个机器,构成了分布式系统,都可以称为是一个集群 主从结构,哨兵模式 也可以称之为广义的 集群

狭义的集群,redis提供的 集群模式,这个集群模式下,主要是解决存储空间不足的问题(拓展存储空间)

哨兵系统提高了系统的可用性

但系统本质上还是主从节点负责存储数据,就要求一个主从节点存储整个数据

内存存储数据是有上限的 此处关键问题就是 引入多台机器,每台机器存储一部分数据

随着机器数目的增加,每个机器存储的数据就减少了

不是光搞机器 仍要搭配从节点(防止机器挂掉数据丢失)

每个红框部分就叫分片

把数据分成多份 怎么分?

三种主流分片方式

1.哈希求余

借助哈希函数,把一个key映射到整数,在针对数组的长度求余,就可以得到一个数组下标

针对要插入数据的key计算hash值,比如md5,再把这个hash值余上分片个数

hash(key)%N=》下标

但这种方式存在弊端,分片的主要目的是能提高存储能力

可分片越多,能存的数据越多,成本也就越高

一般都是先少搞几个分片 但随着业务逐渐增长,数据变多了,分片不足以保存了

就需要"扩容" 当引入其他的机器时 N会发生改变 ,整体的结果都需要进行数据搬运

我们会发现绝大多数的数据都需要搬运 这样的成本是非常高的 而且容易出现问题

因此我们引入了第二种方式来解决这样的问题

2.一致性哈希算法

不再是简单的哈希求余方式来存放

而是划分区域 以顺时针

圆环上密密麻麻的点就代表数据的存放位置

假定有一个key根据hash算法得到一个值 在图标中找到该值的位置,从此处顺时针寻找 找到的第一个分片位置是哪个 该数据所属分片就是它

在一致性哈希下就改进了,哈希求余下数据的交替性,变成连续性

在添加新分片 时 搬运的成本仍然是有的 但比起哈希求余的那种方式大大降低了

但当我们这样添加分片之后 发现数据分布不均匀,就是发生了数据倾斜3号和0号分片的数据量比其他分片的少

3.哈希槽分区算法

Redis采用的就是 这种模式进行扩容

hash_slot 代表哈希槽 crc16 是一种求哈希值的算法

得到 这些哈希槽 后 会进一步将这些哈希槽分配给不同的分片

哈希槽的分配是非常灵活的可以是连续的 也可以是 不连续的

每个分片会用位图的数据结构来表示是否持有某个槽位

扩容时 呢就如下图所示

针对某个分片,上面的槽位号,不一定非得是连续的区间

在上述过程 中只有被移动的槽位,对应 的数据才需要搬运

redis中当前某个分片包含哪些槽位 都是可以手动配置的

注意

问题一 Redis集群最多有16384个分片ma

key是先映射到槽位上 然后槽位再映射到分片

如果每个分片包含的槽位比较少,那么槽位个数不一定能直观的反映到key的数目 (因为按照哈希 求余的方式理解 很有可能 0上有很多数据,而1上没有数据)此时呢就很难保证各个分片上数据的均衡性

Redis的作者建议集群分片数不应该超过1000

问题二 为什么是16384个槽位

因为槽位数不应过多 16384(16k)用位图表示大小是2KB,槽位数过多就会消耗更大的空间了

节点之间通过 心跳包来周期性通信 会消耗网络带宽

心跳包中包含了该节点持有哪些槽位

2kb这个值基本上够用了,同时占用的硬件资源不是 很大

集群模式的创建 是在多台主机上进行的在此就不做演示 主要进行原理的解释以及理解功能作用

集群机制 故障转移

集群机制 也能处理故障转移

当主节点挂了时,集群机制也会选出一个旗下的从节点成为主节点 当原先的主节点上线后会变为从节点加入

此处故障转移,具体 处理流程,和哨兵这块的 处理流程 不太一样

Redis Cluster 模式 下,当某个主节点发生故障时,集群具备自动故障转移能力,可以将对应的从节点提升为主节点,从而保证服务的连续性与数据可用性。

故障转移流程

  1. 故障检测: 节点间通过 Gossip 协议 定期发送 PING/PONG 心跳包。 若在 cluster-node-timeout(默认15秒)内未收到响应,会先标记为 PFAIL(可能下线)。 当超过半数主节点确认该节点不可达时,升级为 FAIL(确定下线),并广播给全网节点。

  2. 从节点选举: 故障主节点的从节点会根据复制偏移量排名,数据最新的优先发起选举。 从节点向其他主节点发送 FAILOVER_AUTH_REQUEST 请求投票,获得多数票后晋升为新主节点。

  3. 槽(slot)接管与广播: 新主节点接管原主节点的哈希槽,并通过 Gossip 广播更新。 客户端收到 MOVED/ASK 重定向后更新路由表,继续访问新主节点。

  4. 原主节点恢复: 恢复上线后会自动降级为从节点,重新加入复制链。

    注意:在集群模式下的从节点选举与哨兵模式下的选举有不同

    哨兵模式下是哨兵节点群推举出 一个哨兵节点作为leader来进行新主节点的选择

    集群模式是从故障节点的所属从节点中选出offset值最大也就是 数据同步化最高的那个从节点 进行投票(只有主节点可以投票 )

    从而选出一个新的主节点

    集群模式宕机

    1.某个分片所属的主节点和从节点都挂了

    2.分片所属主节点挂了 且没有从节点

    3.一半的主节点挂了

    集群扩容

    集群操作是一件风险较高,成本较大的 操作

    1.新的节点加入到集群中

    2.重新分配slots(槽位)

    此处会先打印出当前集群每个机器的情况

    并且要求用户输入移动多少个槽位

输入要从哪些 节点 来移动slots

1)all 表示从其他每个持有slots的master都拿过来点

2)手动指定,从某一个或者 某几个节点来移动slots (以done为结尾 )

输入上面之后 会给出搬运的计划(还没真正搬运)

当 输入yes之后

搬运才真正开始,此时不仅是slots重新划分,也会把 slots上对应的数据,也搬运到新的主机上

如果在搬运slots/key的过程中,此时客户端能否访问咱们 redis集群呢?

搬运key时 大部分数据是 不需要 搬运的 这些数据仍可 进行访问

但搬运的数据 可能会 出现问题 比如 key映射到slots,重定向到所属分片 在 重定向的过程中 该槽位发生了移动,所属分片重定向就会出错

3.把从节点也添加到集群中

相关推荐
r_oo_ki_e_2 小时前
java23--异常
java·开发语言
qq_12498707532 小时前
基于Spring Boot的“味蕾探索”线上零食购物平台的设计与实现(源码+论文+部署+安装)
java·前端·数据库·spring boot·后端·小程序
爬山算法2 小时前
Hibernate(38)如何在Hibernate中配置乐观锁?
android·java·hibernate
江上月5132 小时前
JMeter中级指南:从数据提取到断言校验全流程掌握
java·前端·数据库
晨旭缘2 小时前
零基础后端入门:JDK21 + PostgreSQL+Java项目
java·数据库·postgresql
萧曵 丶2 小时前
MySQL InnoDB 实现 MVCC 原理
数据库·mysql·mvcc
BullSmall2 小时前
SpringBoot 项目日志规范(企业级标准 + 最佳实践)
java·spring boot·spring
better_liang2 小时前
每日Java面试场景题知识点之-线程池
java·线程池·并发编程·juc·企业级开发
一直都在5722 小时前
SpringBoot:自动配置原理
java·spring boot·spring