8.2 Redis集群之数据分布

1.数据分布简介
(1).分布式数据库的数据分区
随着请求量和数据量的增加,一台机器已经无法满足需求,就需要将数据和请求分散到多台机器,这时候就需要引入分布式存储。分布式存储首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集。
在这里插入图片描述

(2).常见的分区规则

  • 节点取余分区
  • 一致性哈希分区
  • 哈希槽分区(Redis Cluster采用的分区规则)

2.节点取余分区
(1).计算公式
节点取余分区使用hash(key)%nodes(使用特定的数据,如Redis的键作为key和节点数量nodes)来计算哈希值,以决定数据映射到哪一个节点上。

(2).存在的问题
当节点数量变化时,如扩容或收缩节点,数据节点映射关系需要重新计算,会导致数据的重新迁移,其示意图如下所示。
在这里插入图片描述
在这里插入图片描述

(3).多倍扩容
在这里插入图片描述

(4).总结

  • 客户端分片:哈希 + 取余
  • 节点伸缩:数据节点关系变化,导致数据迁移
  • 迁移数量和添加节点数量有关:建议翻倍扩容(一般不建议使用,因为这样会降低性能,增加底层数据源的访问压力)

3.一致性哈希分区
(1).什么是一致性哈希
每个节点分配一个token(范围在0~2的32次方),这些token构成一个哈希环。数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。
Redis集群采用哈希槽(slot)的分区算法,并没有采用一致性哈希分区算法,主要原因是一致性哈希算法对于数据分布和节点位置的控制并不是很好。
在这里插入图片描述
(2).扩容
这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其它节点无影响,其数据漂移示意图如下所示。
在这里插入图片描述
在这里插入图片描述

(3).存在的问题
加减节点会造成哈希环中部分数据无法命中,如之前n1-n2之间的4个数据,由于n5节点的加入,当应用读取n5-n2之间的数据时,Redis会先去n5获取,获取不到就只能去存储层去获取,然后回写到n2节点。当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案。
在这里插入图片描述

(4).总结

  • 客户端分片:哈希 + 顺时针
  • 节点伸缩:只影响邻近节点,但还是有数据迁移
  • 翻倍伸缩:保证最小迁移数据和负载均衡

4.哈希槽分区
(1).简介
Redis集群没有单机的那种16个数据库的概念,而是分成了16384个槽,每个节点负责其中一部分槽位,槽位的信息存储于每个节点中。
注意,对于槽位的转移和分派,Redis集群不会自动进行,而是人工配置的,所以Redis集群的高可用依赖于节点的主从复制与主从间的自动故障转移。

(2).槽范围
在这里插入图片描述
槽范围是0~16383,假如现在集群有5个节点,那么每个节点平均大约负责3277个槽。

为什么是16384个槽?
1.如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。
因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽。
2.redis的集群主节点数量基本不可能超过1000个。
集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。
3.槽位越小,节点少的情况下,压缩比高。
Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots/N很高的话(N表示节点数),bitmap的压缩率就很低。如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

(3).哈希槽分配算法在这里插入图片描述
Redis Cluser采用哈希槽分区,所有的键根据哈希函数映射到0~16383内,计算公式为slot=CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。

(4).总结

  • 解耦数据和节点之间的关系,简化了节点扩容和收缩难度。
  • 节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据。
  • 支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Redis集群的数据均衡分布,可以按照以下步骤进行操作: 1. 配置多个Redis节点组成一个集群。每个节点都要打开集群模式。 2. 使用`redis-trib.rb`(Redis官方提供的集群管理工具)或其他支持Redis集群的管理工具,将节点添加到集群中。 3. 将数据根据键进行哈希计算,得到一个槽位编号。 4. 客户端根据槽位编号选择对应的节点来进行读写操作。 具体步骤如下: 1. 启动Redis节点并配置集群模式。可以使用不同的端口启动多个Redis实例。例如,使用端口7000、7001、7002等启动三个Redis实例。 ``` redis-server --port 7000 redis-server --port 7001 redis-server --port 7002 ``` 在每个节点的配置文件中,设置`cluster-enabled yes`以启用集群模式。 2. 使用`redis-trib.rb`或其他管理工具创建Redis集群。在终端中使用以下命令: ``` redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 ``` 这将创建一个由三个主节点和三个从节点组成的Redis集群。`--replicas 1`参数指定每个主节点分配一个从节点。 3. 将数据存储到集群中。通过客户端连接到集群,将数据存储到Redis实例中。客户端会自动将键映射到正确的槽位,并将数据存储在对应的节点上。 ``` redis-cli -c -p 7000 set key1 value1 set key2 value2 ``` `-c`参数表示开启集群模式。 4. 读取数据。客户端连接到集群并读取数据时,它会自动将键映射到正确的槽位,并从相应的节点获取数据。不需要手动指定节点。 ``` redis-cli -c -p 7000 get key1 ``` 通过以上步骤,Redis集群将会自动将数据均衡地分布在各个节点上,实现数据的均衡分布。当有新的节点加入或节点下线时,集群会自动重新分配槽位和数据,保持数据的均衡性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值