Goland中Redis的set求并集的错误处理
一、 文档介绍
今日在项目里写了一份简单的redis两个set类型求并集的操作
不断报错,在网上查到的资料里都简单介绍了自带的API接口,但是这个并不是所有时间都好用的,甚至可以说对分布式而非主机redis来讲基本上都是不好用的
二、网传解决办法
我的代码
func ListUnion2() ([]string, error){ res, err := redisClient.SUnion(DB_SET, List_Only_Dump).Result() DBIgnoreRedisNil(err) return res, err }
三、报错原因
WARN CROSSSLOT Keys in request don't hash to the same slot
报错如上图所示,意思是“无法将请求中的CROSS SLOT密匙哈希写入同一槽中”
首先我们简单理解一下,Key我们称为密匙,我们要对两个不同的密匙进行操作不仅要求两个密匙位于相同的节点上,还要求位于相同的哈希槽中,报错的原因就是因为两个密匙不位于相同的哈希槽中,解决办法见下面👇
四、简单理解Redis Cluster读写过程
redis集群模式下的读写过程中,先对key进行hash找到slot进而找到clusterNode,如果clusterNode不是本节点就返回ASK或者MOVED错误码让客户端向新的节点ip:port发起连接。
也就是按照key->hash值->slot->clusterNode的顺序定位到key保存的clusterNode节点。
在完成clusterNode判断后如果确定是本节点后执行后续的读写操作即可。
也就是按照key->hash值->slot->clusterNode的顺序定位到key保存的clusterNode节点。
在完成clusterNode判断后如果确定是本节点后执行后续的读写操作即可。
五、解决办法
我是采取了比较愚钝的办法,创建了一个SET,将需要合并的两个SET里面的内容取出来之后再add到新的SET里面
这里一个问题就是Goland本身是没有SET结构的,我们如果想要使用的话需要手动实现,我今天先在REDIS上申请了一个SET类型来调试这个bug,在后续调试晚之后再手动实现SET
代码如下:
func ListUnion() ([]string, error){ redisClient.Del(Union_List) res := []string{} dbList, err := redisClient.SMembers(DB_SET).Result() if err != nil{ return res, err } onlyDumpList, err := redisClient.SMembers(List_Only_Dump).Result() if err != nil{ return res, err } for _, dbName := range dbList{ _, err := redisClient.SAdd(Union_List, dbName).Result() if err != nil{ return res, err } } for _, dbName := range onlyDumpList{ _, err := redisClient.SAdd(Union_List, dbName).Result() if err != nil{ return res, err } } res, err = redisClient.SMembers(Union_List).Result() return res, err }