集群架构中Lua脚本的限制以及出现的报错
🚀 博主介绍:大家好,我是无休居士!一枚任职于一线Top3互联网大厂的Java开发工程师! 🚀
🌟 在这里,你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人,我不仅热衷于探索一些框架源码和算法技巧奥秘,还乐于分享这些宝贵的知识和经验。
💡 无论你是刚刚踏入编程世界的新人,还是希望进一步提升自己的资深开发者,在这里都能找到适合你的内容。我们共同探讨技术难题,一起进步,携手度过互联网行业的每一个挑战。
📣 如果你觉得我的文章对你有帮助,请不要吝啬你的点赞👍分享💕和评论哦! 让我们一起打造一个充满正能量的技术社区吧!
目录标题
- 集群架构中Lua脚本的限制
- Redis Cluster 架构限制具体错误码和原因请参见下表
- 错误码分类
- 具体示例
- 1. 必须带有至少一个键
- 2. 多个键必须属于同一个槽位
- 总结
集群架构中Lua脚本的限制
- 为了保证Lua执行的原子性,Lua命令不可拆分,只能在集群架构的一个DB分片上执行。通常会根据Key来决定路由到哪个DB分片执行,所以在集群架构中执行Lua命令时至少需要指定一个Key。如果读写多个Key,则同一个Lua脚本中的Key必须属于同一个Slot,否则会导致执行结果异常。对于KEYS、SCAN、FLUSHDB等无Key的命令,虽然能正常执行,但返回结果只包含单个分片的数据。上述限制由Redis Cluster架构导致。
- 对单个节点执行SCRIPT LOAD命令时,不保证将该Lua脚本存入至其他节点中。
Redis Cluster 架构限制具体错误码和原因请参见下表
错误码分类
错误码 | 说明 |
---|---|
-ERR for redis cluster, eval/evalsha number of keys can't be negative or zero\r\n | 执行 Lua 脚本时必须带有至少一个键,代理会根据键决定将 Lua 脚本转发到哪个 DB 分片上执行。 |
-ERR 'xxx' command keys must in same slot | Lua 脚本中的多个键必须属于同一个槽位。 |
具体示例
1. 必须带有至少一个键
错误示例:
EVAL "return redis.call('get', 'foo')" 0
错误码:
-ERR for redis cluster, eval/evalsha number of keys can't be negative or zero\r\n
说明:
执行 Lua 脚本时必须带有至少一个键,代理会根据键决定将 Lua 脚本转发到哪个 DB 分片上执行。
正确示例:
EVAL "return redis.call('get', KEYS[1])" 1 fooeval
说明:
这里指定了一个键 fooeval
,代理会根据这个键将 Lua 脚本转发到相应的 DB 分片上执行。
2. 多个键必须属于同一个槽位
错误示例:
EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo foobar
错误码:
-ERR 'mget' command keys must in same slot
说明:
Lua 脚本中的多个键必须属于同一个槽位。在这个示例中,foo
和 foobar
可能不在同一个槽位上,因此会报错。
正确示例:
EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo {foo}bar
说明:
这里使用了哈希标签 {foo}
,确保 foo
和 {foo}bar
都属于同一个槽位,从而避免跨槽位操作。
总结
通过上述表格和示例,你应该能够更好地理解在 Redis Cluster 模式下使用 Lua 脚本时需要注意的事项。特别是:
- 必须带有至少一个键:确保 Lua 脚本中至少有一个键,以便代理可以根据键将脚本转发到正确的 DB 分片。
- 多个键必须属于同一个槽位:使用哈希标签确保多个键属于同一个槽位,避免跨槽位操作。
乐于分享和输出干货的WXGZG:JavaPersons