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,这种思想是典型的分而治之。分治,分流,降级。
发布了33 篇原创文章 · 获赞 21 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013356254/article/details/95121853