Redis集群中的 CROSSSLOT Keys Error
场景 Redis单节点没有问题,切换到Redis Cluster后业务上某一功能出错: CROSSSLOT Keys in request don't hash to the same slot 出错的代码: var ctx = context.TODO() _, err := uq.queueImpl.rc.TxPipelined(ctx, func(pip redis.Pipeliner) error { cmd := pip.LPush(ctx, uq.key, dest...) if cmd.Err() != nil { return cmd.Err() } return pip.SAdd(context.Background(), uq.setkey, dest...).Err() }) 这段代码的逻辑是向 list 中push一条数据,再向一个 set 加入数据,两步操作通过 pipline 在同一个事务中完成。 问题分析 错误的大概意思就是: 请求中跨槽的key没有被hash到相同的hash槽中。通过代码分析,事务中的两次操作的key并不相同,他们没有被hash到同一个hash槽从而出现上述错误。 什么是hash槽 Redis Cluster 规范中的 Key distribution model(key分布模型)说明如下: Redis集群中将key的存储空间划分为16384个slot,整个集群可以支持最大16384个主节点,实际上建议不超过1000个节点。每一个主节点又可以处理16384个 hash slot。整个集群将hash slot分布于不同的节点组成高可用集群,单个节点有多个副本以便在节点故障时将重新平衡节点,达到高可用的目的。关于可用性保证,可以看这里。 如下的公式用于计算key的hash slot: HASH_SLOT = CRC16(key) mod 16384 Redis将相同hash值的slot分布到同一个node下,如下图所示:...