Redis集群

目录

引入

数据分片算法  

哈希求余

优点

缺点

一致性hash算法

优点

缺点

哈希槽分区算法(Redis使用)

拓展问题 

Q1:Redis集群最多只有16384个分片吗?

Q2:为什么是16384个槽位?


引入

redis哨兵能够提高系统的可用性,但是真正存储数据的还是master和slave节点,所有的数据都保存在单个master和slave节点中,如果数据量很大,接近超出了master/slave所在的机器的物理内存,就会出现严重问题!

众所周知,redis的数据是保存在内存上的 ,即便现在的大公司的内存已经能够达到TB级别,但是在现在的这种大数据环境下,显然是不够的

Redis集群应运而生,引入多组Master/Slave,每一组Master/Slave存储数据全集的一部分,从而构成一个更大的整体,称为Redis集群(Cluster)

  • 上图三个不同的redis的主从结构分别存储的数据集3TB的1/3  
  • 每一个红框都可以是一个分片(Sharding)

数据分片算法  

Redis cluster 的核心思路是用多组机器来存数据的每个部分,那么接下来的核心问题就是,给定一个数据(一个具体的key),将他分配到应该去到的分片上

哈希求余

设有N个分片[0,N-1] 进行编号 

假设一共有三个分片,那么得到key后将他hash之后%3 得到分片编号

优点

简单高效、分配均匀

缺点

一旦需要进行扩容,N发生了改变,那么原有的映射规则都被破坏了,需要将所有数据进行重新排列,以满足新的映射规则,此时需要搬运的数据量很大

一致性hash算法

 为了降低上述的搬运开销, 能够更⾼效扩容, 业界提出了 "⼀致性哈希算法"

 第一步:把[0,2^32-1] 这个数据空间,映射到一个圆环上,数据按照顺时针方向增长。

第二步:假设当前存在三个分片,就把分片放到圆环的某个位置上 

第三步:假设此时有一个key,那么hash得到的值为H,那么将这个key映射到哪一个分片呢?

即从H位置顺时针往下找,直到找到的第一个分片,就是该key所属的分片

那么在这种一致性hash的情况下,如果扩容一个分片,如何处理呢?

原有分片不动,在环上安排一个新的分片位置即可

此时,只需要把0号分片上的部分数据,搬运给3号分片即可,1号和2号分片管理的区间都是不变的 

优点

大大降低了扩容时数据搬运的规模,提高了扩容操作的效率

缺点

数据分配不均匀(有的多有的少,数据倾斜)

哈希槽分区算法(Redis使用)

为了解决上述问题,Redis cluster引入了哈希槽(hash slots)算法

hash_slot = crc16(key) % 16384
  • | crc16 也是一种hash算法
  • | 16384 其实是16 ^ 1024  = 2 ^ 14

相当于将所有key值映射到 16384 个槽位上,也就是[0,16383]

然后再把这些槽位均匀的分配给每个分片,每个分片的节点都需要记录自己持有哪些分片

假设当前有三个分片,一种可能的分配方式:

  • 0 号分⽚: [0,5461], 共 5462 个槽位
  • 1号分⽚:  [5462,10923],共5462个槽位
  • 2号分⽚:  [10924,16383],共5460个槽位

TIPS:这里的分片规则是很灵活的,每个分片所持有的槽位也不一定连续,每个分片的节点使用位图来记录自己拥有哪些槽位,对于16384的槽位来说,需要2048个字节(2KB)大小的内存空间表示

此时扩容增加了一个3号分片,即可以针对原有的槽位进行重新分配。

即可以把原有分片所持有的槽位分给新的分片。

  • 0 号分⽚:[0,4095],共4096 个槽位
  • 1 号分⽚:[5462,9557],共 4096 个槽位
  • 2 号分⽚:[10924,15019],共 4096 个槽位
  • 3 号分⽚:[4096,5461]+ [9558, 10923] + [15019, 16383], 共 4096 个槽位?

TIPS:实际使用的时候,不需要手动指定哪些槽位分配给某个分片,只需要告诉某个分片应该持有多少槽位即可,Redis会做单完成分配和搬运

拓展问题 

Q1:Redis集群最多只有16384个分片吗?

A1:nonono,实际上redis作者建议集群分片不要超过1000. 更何况如果你是用16000以上的那么大个规模的集群,本身的可用性也是一大问题

Q2:为什么是16384个槽位?

A2:这里直接翻译Redis原作者的话,大致是如下。

  • 节点之间的通讯是通过心跳包机制的,而心跳包是频繁的发送,心跳包又包含了该节点的各种信息包括所持有的槽。当槽的个数是16384的时候,位图的大小为2kb,但如果槽的个数是65535的时候,此时的位图大小将来到恐怖的8kb,虽然这对于内存不算什么,但是在网络中,仍然是一个不晓得开销
  • 另一方面,Redis集群一般不会超过1000个分片,所以16k对于最大1000个分片的下的情景是足够使用的,同时对应的槽的体积也不会很大
### Redis 集群的搭建与配置 #### 一、Redis 集群简介 Redis 是一种高性能的键值存储系统,支持多种数据结构操作。通过集群模式可以实现分布式存储和高可用性。Redis 集群允许多个 Redis 实例协同工作,提供更高的吞吐量和更强的数据持久化能力。 --- #### 二、环境准备 在开始之前,需确认以下条件已满足: - 所有服务器的操作系统版本一致(如 CentOS 7 或 Windows),并安装了相同版本的 Redis 软件。 - 已关闭防火墙或开放必要的端口(默认 Redis 使用 6379 及其衍生端口)。 - 每台服务器上至少有两个 Redis 实例运行,分别作为主节点和从节点[^1]。 --- #### 三、具体步骤 ##### 1. 下载并解压 Redis 文件 下载指定版本的 Redis 压缩包(如 Redis 6.2.5 或更高版本),将其解压到目标路径下。例如,在 Linux 中执行以下命令: ```bash wget http://download.redis.io/releases/redis-6.2.5.tar.gz tar -zxvf redis-6.2.5.tar.gz cd redis-6.2.5 make ``` ##### 2. 创建多个实例目录 为每个 Redis 实例创建独立的工作目录,并复制 `redis.conf` 至对应文件夹中。例如: ```bash mkdir -p /service/redis/{6379,6380} cp redis.conf /service/redis/6379/ cp redis.conf /service/redis/6380/ ``` ##### 3. 修改配置文件 编辑每个实例下的 `redis.conf` 文件,设置不同的监听端口号和其他必要参数。以下是关键配置项: - 设置绑定 IP 地址:`bind 0.0.0.0` - 关闭保护模式:`protected-mode no` - 开启集群功能:`cluster-enabled yes` - 指定集群配置文件位置:`cluster-config-file nodes-{port}.conf` - 设定日志级别:`loglevel notice` ##### 4. 启动 Redis 实例 依次启动各个 Redis 实例。例如: ```bash redis-server /service/redis/6379/redis.conf redis-server /service/redis/6380/redis.conf ``` 如果是在多台物理机上部署,则需要远程登录每台机器重复上述过程[^2]。 ##### 5. 构建集群拓扑 利用 `redis-cli` 的集群管理工具完成初始化操作。假设当前存在六个节点分布在三台主机上,则可输入如下指令构建集群关系: ```bash redis-cli --cluster create \ 192.168.x.y:6379 192.168.x.z:6379 ... \ --replicas 1 ``` 其中 `--replicas` 参数表示每个主节点分配几个副本[^4]。 ##### 6. 验证集群状态 最后可以通过以下方式验证集群是否正常运作: ```bash redis-cli -c -h {任意IP} -p {任一口号} CLUSTER INFO CLUSTER NODES PING SET key value GET key ``` --- #### 四、注意事项 - 如果使用 Docker 容器来部署 Redis 集群,请确保容器间网络互通良好。 - 对于 Windows 平台上的开发测试场景,可通过批处理脚本来简化服务启动流程[^3]。 --- #### 五、示例代码片段 下面展示了一个简单的 Python 程序用于连接至 Redis 集群并向其中写入一条记录: ```python import redis r = redis.StrictRedisCluster(startup_nodes=[{"host": "127.0.0.1", "port": "6379"}], decode_responses=True) r.set('foo', 'bar') print(r.get('foo')) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pythoncjavac++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值