Redis:原子获取和条件设置

时间:2018-05-12 17:59:48

标签: lua redis conditional atomic

我想在Redis中执行原子GET,如果返回的值等于某个预期值,我想要SET,但我希望将所有这些链接在一起作为一个原子操作。 (我试图设置一个标志,指示是否有任何进程正在将数据写入磁盘,因为只允许一个进程这样做。)

是否可以使用Redis完成此操作?

我看过有关MULTI操作的文档,但我还没有看到MULTI操作的条件操作。任何其他人可以提供的建议将非常感谢!

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我最终使用了redlock-py,这是Redis文档建议用于创建写锁的redlock算法的实现:https://redis.io/topics/distlock。对于想要在Redis中创建类似写锁的人来说,链接的文章非常精彩。

答案 2 :(得分:0)

redis-if - 用于“条件交易”的 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' ]
  ]
}))

使用此脚本,我们从项目中删除了所有自定义脚本。