[Golang 修仙之路] Redis:Redis集群如何处理MSET?

138 阅读1分钟

问题

MSET命令本身是对多个key的操作,如何保证集群模式下对多个key的操作同时成功,同时失败?

结论

redis 集群 对于mset这类的一次操作多个key的命令,会严格限制这些key必须都映射到同一个slot上,否则会报错。

想不到,redis说,我不保证,而是直接不允许你这么干。

而且不只是mset,像set的union等只要涉及多个key的操作,在集群模式下都不能成功。

解释

  • Redis Cluster 按 key 的哈希槽(hash slot)分片:16384 个槽,分布在不同节点上。
  • 一个命令中涉及多个 key 时,Redis 要求 所有 key 必须在同一个 slot,否则会报错:
(error) CROSSSLOT Keys in request don't hash to the same slot

哪怕是多个key,槽位不同,但是映射到了同一个node上,都不行。

image.png

如何让不同的key一定映射到同一个哈希槽?

Redis Cluster 提供了 hash tag 机制:

  • 在 key 里用花括号 {} 包住一部分作为哈希基准。
  • 例如:
MSET user:{1001}:name Tom user:{1001}:age 18

这里两个 key 的哈希都是根据 {1001} 计算的 → 它们就会被分配到同一个槽,可以在集群里原子执行。

参考

  1. stack over flow:stackoverflow.com/questions/3…

碎碎念

跟着Godis敲了一遍,看了Godis有篇博客说用TCC实现了集群场景下MSET操作的原子性,结果这个点在面试的过程中经常被拷打。

所以来探究这个事情。也算是缘分吧。