RedisCluster路由

文章介绍了RedisCluster的路由方式,包括redis-cli客户端如何处理MOVED重定向以及Smart客户端如Redission的内部机制。在RedisCluster中,键通过CRC16计算映射到槽,客户端在接收到MOVED或ASK重定向时会调整请求节点。ASK错误发生在slot迁移中,而MOVED错误发生在迁移完成后或初始分配时。
摘要由CSDN通过智能技术生成

又是美好的一天呀~
个人博客地址: huanghong.top

本文预估阅读时长为10分钟左右~

RedisCluster路由

redis-cli客户端

  • 根据key的有效部分使用CRC16函数计算出散列值,在对16383取余,得到slot编号。这样的key都会映射到0~16383槽范围内;
  • 根据MOVED重定向机制,Redis客户端可以随机连接集群内任一redis节点(主从节点均可)获取其slot所在的node;
  • 发送redis指令
    • 如果指令在这个node上,则处理指令;
    • 如果不在这个node上,则redis会返回给客户端MOVED重定向错误,通知客户端重新请求正确的node, 这个过程称为MOVED重定向。

使用redis-cli客户端普通连接redis主节点,来存取键值会返回MOVED重定向错误,键值并不能存取成功。

重定向信息中包含了slot和node的地址,根据重定向信息可以手动去请求正确的node。

image-20230308204547173

使用redis-cli客户端集群模式连接(redis-cli -c)连接redis主节点,存取键值时redis-cli同样也会接收到MOVED重定向错误,但是会自动根据重定向信息来切换节点重新发起请求。

image-20230308204807851

Smart客户端

基于Redission分析

  1. 根据配置文件获取RedisCluster集群节点信息

  2. org.redisson.cluster.ClusterConnectionManager#scheduleClusterChangeCheck定时检测集群节点状态

  3. org.redisson.cluster.ClusterConnectionManager#checkMasterNodesChange检测主节点状态

  4. org.redisson.cluster.ClusterConnectionManager#addMasterEntry初始化slot和node的映射关系存储在

    private final AtomicReferenceArray slot2entry = new AtomicReferenceArray<>(MAX_SLOT)中

  5. redission客户端执行命令

    //org.redisson.command.CommandAsyncService#writeAsync(java.lang.String, org.redisson.client.codec.Codec, org.redisson.client.protocol.RedisCommand<T>, java.lang.Object...)
    public <T, R> RFuture<R> writeAsync(String key, Codec codec, RedisCommand<T> command, Object... params) {
        RPromise<R> mainPromise = createPromise();
        //解析key对应的slot
        NodeSource source = getNodeSource(key);
        async(false, source, codec, command, params, mainPromise, false, false);
        return mainPromise;
    }
    
    //org.redisson.cluster.ClusterConnectionManager#calcSlot(java.lang.String)
    public int calcSlot(String key) {
        if (key == null) {
            return 0;
        }
    
        int start = key.indexOf('{');
        if (start != -1) {
            int end = key.indexOf('}');
            if (end != -1 && start + 1 < end) {
                key = key.substring(start + 1, end);
            }
        }
    	//使用CRC16算法计算出散列值,对16384取余
        int result = CRC16.crc16(key.getBytes()) % MAX_SLOT;
        log.debug("slot {} for {}", result, key);
        return result;
    }
    
  6. 在ClusterConnectionManager中的slot2entry中, 根据key所对应的slot获取对应的节点信息

  7. 向节点发送请求命令

注:

  1. 期间redis客户端会以ping信号来关注集群节点信息,发现节点信息(节点状态、槽位信息等)改变后会变更本地缓存中的值;
  2. RedisCluster客户端接收到MOVED重定向后,会执行刷新缓存slot–>node映射表。

ASK重定向

当slot中的数据从源节点到目标节点迁移过程中,客户端需要保证key的命令可正常执行。

  1. 在进行重新分片期间,源节点向目标节点迁移一个槽的过程中,可能会出现这样一种情况:属于被迁移槽的一部分键值对保存在源节点里面,而另一部分键值对则保存在目标节点里面。
  2. 当客户端向源节点发送一个与数据库键有关的命令,并且命令要处理的数据库键恰好就属于正在被迁移的槽时。源节点会先在自己的数据库里面査找指定的键,如果找到的话,就直接执行客户端发送的命令。
  3. 否则,这个键有可能已经被迁移到了目标节点,源节点将向客户端返回一个 ASK 错误,指引客户端转向正在导入槽的目标节点,并再次发送之前想要执行的命令,从而获取到结果。

ASK与MOVED错误区别

  1. ASK错误发生在slot迁移过程中;
  2. MOVED错误发生在slot迁移完成或slot初始分配完成。

感谢阅读完本篇文章!!!
个人博客地址: huanghong.top

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

喜欢正常冰的冰美式

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

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

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

打赏作者

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

抵扣说明:

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

余额充值