redis集群机制
# redis 集群
为了解决保存大量数据,有两种方案
纵向扩展(直接加大服务器的内存):
- 缺点:内存扩展会存在成本或硬件的限制
横向扩展(增加服务器的个数):
- 缺点:部署复杂,会产生新的集群问题
- 优点:节约成本,扩展容易
# redis集群产生的问题?
客户端发送的数据如何分布?
客户端发送消息到哪个实例?
# 客户端发送的数据如何分布?
redis 集群中 一共有16384个hash槽,客户端发送过来命令,会将key进行hash算出一个16 bit的值,然后和16834取模,得到的模数就是数据存在的槽位,而槽位又是与redis实例绑定的(事先会将槽位分配给每个实例,可以使用命令cluster addslots
手动分配,最后需要确保槽位都被分配掉)
# 客户端发送消息到哪个实例?
客户端发送命令时,可以根据命令的key计算出槽位。
而槽位和实例的关系,redis实例之间会扩散自己与槽位的关系,以至于每个redis实例都有一份完整槽位和实例的映射关系,redis实例会发送给客户端,客户端会缓存下来。
这里又会产生一个问题 :集群中的实例个数是可能会变的,那么槽位和映射关系也会随之变,redis可能需要修改数据也会需要一个过程,那么客户端又是如何知道变化之后的实例与槽位的关系呢
最常见的变化有两个:
- 在集群中,实例有新增或删除,Redis 需要重新分配哈希槽;
- 为了负载均衡,Redis 需要把哈希槽在所有实例上重新分布一遍。
Redis Cluster 方案提供了一种重定向机制,所谓的“重定向”,就是指,客户端给一个实例发送数据读写操作时,这个实例上并没有相应的数据,客户端要再给一个新实例发送操作命令。
那客户端又是怎么知道重定向时的新实例的访问地址呢?当客户端把一个键值对的操作请求发给一个实例时,如果这个实例上并没有这个键值对映射的哈希槽,那么,这个实例就会给客户端返回下面的 MOVED 命令响应结果,这个结果中就包含了新实例的访问地址。
GET hello:key
(error) MOVED 13320 172.16.19.5:6379
1
2
2
疑问 redis实例如何,什么时候将槽位和实例的映射关系发送给客户端?
上次更新: 2022/11/06, 20:14:12