lua在redis集群中的解决方案-- command keys must in same slot

Posted 「已注销」

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua在redis集群中的解决方案-- command keys must in same slot相关的知识,希望对你有一定的参考价值。

上一篇文章基于lua-redis实现榜单类服务的数据一致性提到lua脚本的使用。
但是测试环境的redis是单机版的,而线上服务器确是集群版。导致同样的代码在线上服务器一直报错,经过测试发现集群版lua脚本的使用并不同于单机版。

command keys must in same slot

为了保持事务,同一个lua脚本访问应该访问同一个slot,但是redis集群会根据KEY进行hash并取模,因此如果采用默认hash的话,那么就会产生下面的错误。


解决方案,redis支持写法,可以实现对KEY的部分字符串进行hash,这样就能保证同一个lua脚本被同一个slot执行,从而保持事务的一致性。

 
 EVAL ' local res =  if ARGV[5] == "0" then res[1] = redis.call("ZCARD", KEYS[1]) end local data=nil if ARGV[6] == "2" then data = redis.call("ZREVRANGEBYSCORE", KEYS[1], ARGV[3], ARGV[2],"LIMIT", ARGV[4], ARGV[1]) else data = redis.call("ZRANGEBYSCORE", KEYS[1], ARGV[2], ARGV[3],"LIMIT",ARGV[4], ARGV[1]) end if (ARGV[5] > "0") then local temp= local rankDatas = redis.call("ZRANGEBYSCORE", KEYS[2],  "-inf", "+inf","LIMIT",0,ARGV[5]) for k,v in pairs(data) do for k1,v1 in pairs(rankDatas) do if v == v1 then table.insert(temp,v) end end end data = temp res[1] = table.getn(data) end if table.getn(data)>0 then res[2] = redis.call("HMGET", KEYS[3], unpack(data)) end return res ' 3 top_turnover_rate top_rank coin_top_coin 5000 -inf +inf 0 1 1

总结
  • redis集群版的lua脚本,可以通过key的部分字符串hash来解决
  • redis集群版的分布式是会根据KEY进行hash取模然后打到不同的slot,这种思想是典型的分而治之。分治,分流,降级。

以上是关于lua在redis集群中的解决方案-- command keys must in same slot的主要内容,如果未能解决你的问题,请参考以下文章

hiredis 能用在3.0版本 redis集群吗

redis集群lua脚本遇到的问题

lua连接redis集群

Redis集群 Lua Java 随机编号 用户编号

hiredis 能用在3.0版本 redis集群吗

基于Redis和Lua的分布式限流