redis集群的多key原子性操作如何实现?-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1、背景

在单实例redis中我们知道多key原子性操作可以用lua脚本或者multi命令来实现。
比如说有一个双删场景要保证原子性同时删除k1k2

可以用lua双删

EVAL "redis.call('del', KEYS[1]);redis.call('del', KEYS[2])" 2 k1 k2

也可以用事务双删

MULTI
del k1
del k2
EXEC

但是在redis的集群中key被hash到不同的slotslot又被分配到多个不同redis实例。那么多key原子性操作如何实现呢

2、冲突

在redis集群中执行多key原子性操作意味着要在不用redis实例之间执行多key原子性操作要满足这个诉求我们可以通过探索下面这个疑问来挖掘正确解决方案。

参考单实例的思路用lua脚本、multi能支持吗
引申问题1如果能那么原理是怎样的
引申问题2如果不能那么应该如何实现

3、分析

参考腾讯云的解答

我们业务常用腾讯云所以想到使用指南上一定有关于这个场景的方案。

关于集群版事务的描述

不建议使用事务
Redis 的事务功能较弱不支持回滚而且集群版本要求一次事务操作的 Key 必须在同一个 Slot 上。

这里腾讯云并没有说用了事务会如何是会失效还是会报错我觉得这个可以描述更清晰一些。读者知道可以评论回复。

关于集群版lua的描述

集群版使用 Lua 的特殊要求
所有 Key 都应该由 KEYS 数组来传递。redis.call/pcall 里面调用的 Redis 命令Key 的位置必须是 KEYS array, 否则直接返回如下错误信息error“-ERR bad lua script for redis cluster,all the keys that the script uses should be passed using the KEYS array”
单个 Lua 脚本操作的 Key 必须在同一个节点上否则直接返回如下错误信息error, “-ERR eval/evalsha command keys must in same slotrn”

用lua脚本强调的是key必须都落到同一slot上这里并没有说怎么使key落到同一slot上所以我认为这个答案也并不完美。

总结一下大致就是腾讯云不具备集群多实例间的多key原子性操作能力。
但是可以通过将操作的多key都落到同一slot利用单实例redis的能力来实现

参考redis官方的解答

经过上面的思考后我想看看标准redis集群应该是怎么玩的

关于"能力" 的描述

Redis Cluster implements all the single key commands available in the non-distributed version of Redis. Commands performing complex multi-key operations like set unions and intersections are implemented for cases where all of the keys involved in the operation hash to the same slot.

  • redis 集群实现所有非集群版本的单key操作能力
  • redis 集群复杂的多key操作能力是基于所有key都落在同一slot的原则上实现的

问题一的思考两个命令都属于#2所以官方也是建议多key原子性操作将操作的多key都落到同一slot利用单实例redis的能力来实现

那么怎么使key落到同一slot上

关于多key落同一slot

Redis Cluster implements a concept called hash tags that can be used to force certain keys to be stored in the same hash slot.

redis集群提供了一个叫hash tags的概念利用这个能力可以将多key都落到同一个slot中。

4、解决

解答疑问

综合上面的信息我们可以解答我们的问题了。
参考单实例的思路用lua脚本、multi能支持吗
是可以的。但是有一个前提就是保证多key都落在同一个slot中。其原理是将多key收拢在同一个slot中并利用单实例redis的多key原子性操作能力。

使多key落在同一slot-hash tags

Hash tags
There is an exception for the computation of the hash slot that is used in order to implement hash tags. Hash tags are a way to ensure that multiple keys are allocated in the same hash slot. This is used in order to implement multi-key operations in Redis Cluster.
To implement hash tags, the hash slot for a key is computed in a slightly different way in certain conditions. If the key contains a “{…}” pattern only the substring between { and } is hashed in order to obtain the hash slot.

大概的意思就是原来key落到slot的方式是根据key进行hash的如果我们给key起名的时候带上{x}标志那么进行hash的时候就会以x作为hash key了。

用上述的例子我们可将key名改成{k}1,{k}2,那么就可以使这两个key落在同一slot就可以用起集群版的多key原子性操作能力了。

更好的使用方式

抛开redis集群自身的能力应该还有更好的解决方案比如分布式锁等这里就不再探讨有更好的方式可以评论区交流。

参考
腾讯云-命令使用准则
redis官方关于redis集群的描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis

“redis集群的多key原子性操作如何实现?-CSDN博客” 的相关文章