我想在Redis中执行一个原子GET,如果返回的值等于某个期望值,我想执行一个SET,但是我想把所有这些操作链接在一起作为一个原子操作(我试图设置一个标志来指示是否有进程正在向磁盘写入数据,因为只有一个进程可以这样做)。有可能在Redis上实现这一点吗?我看过关于MULTI操作的文档,但是我还没有看过MULTI操作的条件操作。其他人能提供的任何建议都将非常感谢!
GET
SET
MULTI
voj3qocg1#
你可以使用Lua scripts在redis服务器上执行GET和set操作,它们是原子的,也允许你添加逻辑。
guykilcj2#
最后我使用了redlock-py,Redis文档推荐用于创建写锁的redlock算法的实现:链接的文章对于任何希望在Redis中创建类似写锁的人来说都是非常棒的阅读。
kyxcudwk3#
“条件事务”的lua脚本。比WATCH + MULTY更方便。您可以将条件和遵循的命令的任意组合作为json对象传递:
const Redis = require('ioredis') const redis = new Redis() redis.defineCommand('transaction', { lua: require('redis-if').script, numberOfKeys: 0 }) await redis.set('custom-state', 'initialized') await redis.set('custom-counter', 0) // this call will change state and do another unrelated operation (increment) atomically let success = await redis.transaction(JSON.stringify({ if: [ // apply changes only if this process has acquired a lock [ 'initialized', '==', [ 'sget', 'custom-state' ] ] ], exec: [ [ 'set', 'custom-state', 'finished' ], [ 'incr', 'custom-counter' ] ] }))
有了这个脚本,我们从项目中删除了所有自定义脚本。
w3nuxt5m4#
我偶然看到这篇文章,想找一个类似的函数,但是我没有看到任何吸引我的选项,于是我选择用Rust编写一个小模块,提供这种类型的操作:https://github.com/KennethWilke/redis-setif在本模块中,您可以通过以下方式执行此操作:
SETIF <key> <expected> <new> HSETIF <key> <field> <expected> <new>
eqoofvh95#
您可以通过SET命令,使用这2个参数,根据文档here:GET -返回存储在key中的旧字符串,如果key不存在则返回nil.NX -仅在密钥不存在时设置密钥。由于Redis不会在另一个命令运行时执行任何命令--这两个操作以原子的方式进行。
5条答案
按热度按时间voj3qocg1#
你可以使用Lua scripts在redis服务器上执行GET和set操作,它们是原子的,也允许你添加逻辑。
guykilcj2#
最后我使用了redlock-py,Redis文档推荐用于创建写锁的redlock算法的实现:链接的文章对于任何希望在Redis中创建类似写锁的人来说都是非常棒的阅读。
kyxcudwk3#
“条件事务”的lua脚本。比WATCH + MULTY更方便。
您可以将条件和遵循的命令的任意组合作为json对象传递:
有了这个脚本,我们从项目中删除了所有自定义脚本。
w3nuxt5m4#
我偶然看到这篇文章,想找一个类似的函数,但是我没有看到任何吸引我的选项,于是我选择用Rust编写一个小模块,提供这种类型的操作:
https://github.com/KennethWilke/redis-setif
在本模块中,您可以通过以下方式执行此操作:
eqoofvh95#
您可以通过SET命令,使用这2个参数,根据文档here:
GET -返回存储在key中的旧字符串,如果key不存在则返回nil.
NX -仅在密钥不存在时设置密钥。
由于Redis不会在另一个命令运行时执行任何命令--这两个操作以原子的方式进行。