Redis 切片集群
本文将介绍 Redis 中的切片集群。
一、为什么要切片?
当 Redis 中存储的数据非常多时,会有以下两个问题:
- 内存占用过大:当数据过多时,内存占用可能会非常大,而大内存的服务器一般成本会更高
- RDB 持久化时间过长:
- 如果堵塞式 RDB 持久化,则内存越大,持久化时间越长
- 如果非堵塞式 RDB 持久化,创建子线程时需要执行
fork()
操作,该操作会堵塞父线程,且内存占用越大执行时间越长
可以通过切片集群解决这一问题,多个 Redis 实例组成一个集群,按照一定的规则将数据划分,每个实例保存一部分数据,从而避免单一实例存储过多数据。
二、Redis Cluster
1. 什么是 Redis Cluster ?
Redis Cluster 是从 Redis 3.0 开始官方提供的切片集群的解决方案。
2. 映射关系
Redis Cluster 采用哈希槽的方式来处理数据和实例之间的映射关系,具体步骤为:
- 一个切片集群共有 16384 个哈希槽,每个哈希槽就是一个数据分区,哈希槽可以均匀分布在每个实例上,也可以手动分配
- 根据 key,按照 CRC16 算法计算一个 16bit 的值
- 将 16bit 的值对 16384 取模,放入对应的哈希槽中
3. 映射关系的维护 - 实例之间
- 初始状态下:集群实例会将自己的哈希槽信息发给集群中的其它实例,当集群互相连接完成后,每个实例都将拥有所有 “哈希槽 - 实例” 的映射关系
- 映射关系改变时:实例之间相互传递消息,更新 “哈希槽 - 实例” 的映射关系
4. 映射关系的维护 - 客户端
初始状态下:客户端与集群实例建立连接之后,实例就会将 “哈希槽 - 实例” 的映射关系发送给客户端,客户端可以自行计算哈希槽,向对应的实例发送请求
映射关系改变时:
如果数据的迁移已完成,实例会向客户端发送
MOVED
指令,让客户端更新映射关系,以便向新的实例获取数据1
2GET hello:key
(error) MOVED 13320 172.16.19.5:6379如果数据的迁移未完成,实例会向客户端发送
ASK
指令,让客户端向新的实例请求是否可以获取数据1
2GET hello:key
(error) ASK 13320 172.16.19.5:6379
参考
- Redis
- Redis 教程 | 菜鸟教程
- Redis数据库学习教程(快速入门版)
- Redis 核心技术与实战