Redis:原子get和条件集

lnlaulya  于 2023-02-11  发布在  Redis
关注(0)|答案(5)|浏览(106)

我想在Redis中执行一个原子GET,如果返回的值等于某个期望值,我想执行一个SET,但是我想把所有这些操作链接在一起作为一个原子操作(我试图设置一个标志来指示是否有进程正在向磁盘写入数据,因为只有一个进程可以这样做)。
有可能在Redis上实现这一点吗?
我看过关于MULTI操作的文档,但是我还没有看过MULTI操作的条件操作。其他人能提供的任何建议都将非常感谢!

voj3qocg

voj3qocg1#

你可以使用Lua scripts在redis服务器上执行GET和set操作,它们是原子的,也允许你添加逻辑。

guykilcj

guykilcj2#

最后我使用了redlock-py,Redis文档推荐用于创建写锁的redlock算法的实现:链接的文章对于任何希望在Redis中创建类似写锁的人来说都是非常棒的阅读。

kyxcudwk

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' ]
  ]
}))

有了这个脚本,我们从项目中删除了所有自定义脚本。

w3nuxt5m

w3nuxt5m4#

我偶然看到这篇文章,想找一个类似的函数,但是我没有看到任何吸引我的选项,于是我选择用Rust编写一个小模块,提供这种类型的操作:
https://github.com/KennethWilke/redis-setif
在本模块中,您可以通过以下方式执行此操作:

SETIF <key> <expected> <new>
HSETIF <key> <field> <expected> <new>
eqoofvh9

eqoofvh95#

您可以通过SET命令,使用这2个参数,根据文档here
GET -返回存储在key中的旧字符串,如果key不存在则返回nil.
NX -仅在密钥不存在时设置密钥。
由于Redis不会在另一个命令运行时执行任何命令--这两个操作以原子的方式进行。

相关问题