文章目录
Redis学习笔记-切片集群Redis Cluster
之前学习了 Redis
哨兵机制和 Redis
哨兵集群建立过程,当主库发生故障时,Redis
哨兵可以将合适的从库切换成主库,这样就可以保证 Redis
的高可用了,但如果 Redis
数据量变大了就会面临扩容的问题,集群的实例增减,或为了实现负载均衡进行数据重新分布,会导致哈希槽和实例的映射关系发生变化,客户端发送请求时,会收到命令执行报错信息,如果了解 MOVED
和 ASK
命令,遇到类似报错信息就很容易理解了,这篇文章就来学习下 Redis Cluster
集群。
1.笔记图
2.Redis 扩容方式
- 纵向扩展:升级单个
Redis
实例的资源配置,包括增加内存容量、增加磁盘容量、使用更高配置的CPU
,其特点就是实施简单、直接,但会受到硬件和成本的限制 - 横向扩展:增加与当前
Redis
实例配置相同的实例,在面向百万、千万级别的用户规模时,横向扩展的Redis
切片集群会是一个非常好的选择
3.切片集群需要思考
- 数据切片后,在多个实例之间如何分布?
- 客户端怎么确定想要访问的数据在哪个实例上?
4.哈希槽(Hash Slot)
- 一个切片集群共有
16384
个哈希槽,这些哈希槽类似于数据分区,每个键值对都会根据它的key
,被映射到一个哈希槽中 - 首先根据键值对的
key
,按照CRC16
算法计算一个16 bit
的值 - 用这个
16bit
值对16384
取模,得到0~16383
范围内的模数,每个模数代表一个相应编号的哈希槽
5.相关命令
-
cluster create 命令:
Redis
会自动把这些槽平均分布在集群实例上,如N
个实例,每个实例槽的个数16384/N
个 -
cluster meet 命令:手动建立实例间的连接,形成集群
-
cluster addslots 命令:
-
指定每个实例上的哈希槽个数,如各个实例配置不一样,需要手动分配哈希槽
-
如上图所示一共有
3
个实例,同时假设有5
个哈希槽,实例1
保存哈希槽0
和1
,实例2
保存哈希槽2
和3
,实例3
保存哈希槽4
redis-cli -h 172.16.19.3 –p 6379 cluster addslots 0,1
redis-cli -h 172.16.19.4 –p 6379 cluster addslots 2,3
redis-cli -h 172.16.19.5 –p 6379 cluster addslots 4
6.客户端定位数据
- 在定位键值对数据时,它所处的哈希槽是可以通过计算得到的,这个计算可以在客户端发送请求时来执行,
- 客户端和集群实例建立连接后,实例就会把哈希槽的分配信息发给客户端
Redis
实例会把自己的哈希槽信息发给和它相连接的其它实例,来完成哈希槽分配信息的扩散- 客户端收到哈希槽信息后,会把哈希槽信息缓存在本地
7.Redis Cluster重定向机制
- 哈希槽变化:如在集群中,实例有新增或删除,
Redis
需要重新分配哈希槽,为了负载均衡,Redis
需要把哈希槽在所有实例上重新分布一遍 - 客户端给一个实例发送数据读写操作时,这个实例上并没有相应的数据,客户端要再给一个新实例发送操作命令
- MOVED 命令:
- 如果这个实例上并没有这个键值对映射的哈希槽,就会给客户端返回
MOVED
命令响应结果,包含了新实例的访问地址
# 13320 哈希槽 172.16.19.5 新地址 6379 新实例端口号
GET hello:key
(error) MOVED 13320 172.16.19.5:6379
-
如
Slot 2
中的数据已从实例2
迁到实例3
,客户端仍然记录着原Slot 2
信息,所以会给实例2
发送命令 -
实例
2
给客户端返一条MOVED
命令,把Slot 2
的最新位置(实例3
上)返给客户端,客户端会向实例3
发送请求并更新本地缓存 -
ASK 命令:
-
如果
Slot 2
中的数据只有一部分迁移到了实例3
,还有部分数据没有迁移,客户端就会收到一条ASK
报错信息
GET hello:key
(error) ASK 13320 172.16.19.5:6379
ASK
命令并不会更新客户端缓存的哈希槽分配信息
扫码关注