rediscluster lua使用

redis中文网官方案例

redis 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

这在在单个redis中是可以成功的,在rediscluster中执行情况如下

redis 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
(error) CROSSSLOT Keys in request don't hash to the same slot

会出现 CROSSSLOT Keys in request don’t hash to the same slot。
原因是因为:Redis cluster对多key操作有限,要求命令中所有的key都属于一个slot,才可以被执行。
想看jediscluster.eval()方法中获取getSlot()的实现

public T run(int keyCount, String... keys) {
    if (keys == null || keys.length == 0) {
      throw new JedisClusterException("No way to dispatch this command to Redis Cluster.");
    }

    // For multiple keys, only execute if they all share the
    // same connection slot.
    if (keys.length > 1) {
      int slot = JedisClusterCRC16.getSlot(keys[0]);
      for (int i = 1; i < keyCount; i++) {
        int nextSlot = JedisClusterCRC16.getSlot(keys[i]);
        if (slot != nextSlot) {
          throw new JedisClusterException("No way to dispatch this command to Redis Cluster "
              + "because keys have different slots.");
        }
      }
    }

如果solt不一样会跑出异常,看获取getSolt()实现

public static int getSlot(String key) {  
  int s = key.indexOf("{");  
  if (s > -1) {  
    int e = key.indexOf("}", s + 1);  
    if (e > -1 && e != s + 1) {  
      key = key.substring(s + 1, e);  
    }  
  }  
  // optimization with modulo operator with power of 2  
  // equivalent to getCRC16(key) % 16384  
  return getCRC16(key) & (16384 - 1);  
}

可以看出,keySlot算法中,如果key包含{},就会使用第一个{}内部的字符串作为hash key,这样就可以保证拥有同样{}内部字符串的key就会拥有相同slot。

综上所述脚本改成

redis 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 {key}1 {key}2 first second
1) "{key}1"
2) "{key}2"
3) "first"
4) "second"

执行成功。

lua使用:> http://www.oschina.net/translate/intro-to-lua-for-redis-programmers

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值