redis cluster集群 slot 计算方法

一条 redis 命令或一个 lua 脚本发送到 redis 集群后,如何计算具体在哪一台 redis 实例去执行命令,以及如何指定在某一台 redis 去执行呢?

答案是slot(槽),每个 redis 集群都会有 16384 个slot,这些 slot 会分布在所有 master 节点中。

一、如何计算 slot ?

对键通过 执行 crc16 算法,再对 16384 取余,即可得到一个小于 16384 的数,该结果就是 slot,哪个 slot 由哪个 redis 节点管理,是在集群启动后就已经确定了的(集群启动后也能进行槽迁移,如线上动态横向扩展 redis 节点的时候,槽迁移完毕后也确定了 slot 和 redis 的映射)。

在 Java 中,可通过以下算法计算出slot:

import io.lettuce.core.codec.CRC16;

public class Test {
    public static void main(String[] args){
        String str = "test";
        int slot = CRC16.crc16(str.getBytes()) % 16384;
        System.out.println("slot = " + slot);
    }
}

输出结果:

slot = 6918

在 redis 集群验证:

访问 key 为 test 的键,定位到槽 [6918] 所在的节点 7001,并转到该节点执行命令,返回OK

二、如何指定在某一台 redis 去执行命令?

与其说指定在某一台 redis 去执行命令,不如说是如何指定 redis 键的slot。

这里用到了 redis 的键哈希标签原理,redis 在计算 slot 的时候,有以下代码:

如果有完整的 {},则只会将 {} 内部的字符串进行 slot 的计算

unsigned int keyHashSlot(char *key, int keylen) {

    int s, e;

    for (s = 0; s < keylen; s++)

        if (key[s] == '{') break;

        if (s == keylen) return crc16(key,keylen) & 0x3FFF;

    for (e = s+1; e < keylen; e++)

        if (key[e] == '}') break;

        if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;

    return crc16(key+s+1,e-s-1) & 0x3FFF;

}

验证:

计算 {test}stra 和 {sest}strb 两个不同字符串的 slot,结果都是 6918

 

结尾:关于 lua 脚本,由于现阶段 redis (当前最高版本6.2.1)执行命令或 lua 脚本都是通过单线程执行,因此 lua 脚本的执行可以保证原子性,不存在并发。正是这个原因,对 lua 脚本的要求就是,所有 key 都必须映射到当前节点,否则会抛出 RedisCommandExecutionException 异常。

io.lettuce.core.RedisCommandExecutionException: CROSSSLOT Keys in request don't hash to the same slot

ps:以后 redis 可能会并发执行命令,且关注吧,毕竟多线程执行的效率比单线程高得多。当前 redis 执行命令是单线程,但是其他操作基本都是多线程的。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wf13265

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

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

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

打赏作者

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

抵扣说明:

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

余额充值