因为 Redis Cluster 中,数据会被分片到多个节点上,跨节点的 lua 脚本是不支持的,所以就会失败。但是Cluster 是很常见的场景,lua(以及事务)也是一个非常重要的用法,这个问题怎么解决呢?
Hash Tag
在 Redis 的官方中,提到了一个 hash tags的功能:
如果我们想要执行 lua 脚本或者事务的时候,就需要确保多个相关的键应该存储在同一个节点上以便执行原子操作,默认情况下,Redis 使用键的哈希值来决定将数据存储在哪个节点。而Redis 中的 hashtag 就是一种可以让我们干预 hash 结果的机制。
Redis 中的 hashtag 是键名中用大括号。包裹的部分。Redis 对大括号内的字符串计算哈希值,并基于这个哈希值将键分配到特定的节点。只有键名中包含大括号,且大括号内有内容时,大括号内的部分才会被用来计算哈希值。如果大括号为空或不包含任何字符,Redis 将整个键名用于哈希计算。
有了这个特性,我们就可以在设计键名时,可以将共享相同逻辑或数据集的键包含相同的 hashtag。就和我们在MySOL的分库分表中的基因法其实是类似的概念。
例如,如果你有多个与用户ID 相关的键,可以使用 user:(12345}:profile 和 user:{12345}:settings 这样的命名方式,确保它们都位于同一个节点。这样他只会用(12345}进行 hash 算法,这样虽然他们是不同的key,但是分片之后的结果就可以在同一个节点上。这样就能执行事务或者lua 脚本了。
其他方案
除了使用 Hash Tag 以外,还有一些其他的方案,也能实现,比如:
1.应用层处理:如果跨节点操作不可避免,可以在应用层通过分布式事务管理器或其他机制来协调多个节点的数据一致性。这通常需要复杂的逻辑和额外的开发工作。
2.拆分操作:尽量将需要事务处理的逻辑拆分成多个独立的、可以在单个节点上执行的小操作,从而避免跨节点事务的需求。