Redis:原子获取和条件集
Redis: Atomic get and conditional set
我想在 Redis 中执行原子操作 GET
,如果返回值等于某个预期值,我想执行 SET
,但我想将所有这些链接在一起作为一个原子操作。 (我正在尝试设置一个标志,指示是否有任何进程正在将数据写入磁盘,因为可能只允许一个进程这样做。)
是否可以使用 Redis 来完成此操作?
我看过有关 MULTI
操作的文档,但我还没有看到 MULTI
操作中的条件操作。其他人可以为此提供的任何建议将不胜感激!
您可以使用 Lua scripts 在 redis 服务器本身上执行 GET 和 set 操作。它们是原子的,也允许您添加逻辑。
我最终使用了 redlock-py, an implementation of the redlock algorithm that the Redis docs recommend for creating write locks: https://redis.io/topics/distlock。对于希望在 Redis 中创建类似写锁的任何人来说,链接的文章都是很棒的读物。
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' ]
]
}))
使用此脚本,我们从项目中删除了所有自定义脚本。
我遇到这个 post 寻找类似类型的功能,但我没有看到任何吸引我的选项。我选择用 Rust 编写一个小模块来提供这种确切类型的操作:
https://github.com/KennethWilke/redis-setif
使用此模块,您可以通过以下方式执行此操作:
SETIF <key> <expected> <new>
HSETIF <key> <field> <expected> <new>
我想在 Redis 中执行原子操作 GET
,如果返回值等于某个预期值,我想执行 SET
,但我想将所有这些链接在一起作为一个原子操作。 (我正在尝试设置一个标志,指示是否有任何进程正在将数据写入磁盘,因为可能只允许一个进程这样做。)
是否可以使用 Redis 来完成此操作?
我看过有关 MULTI
操作的文档,但我还没有看到 MULTI
操作中的条件操作。其他人可以为此提供的任何建议将不胜感激!
您可以使用 Lua scripts 在 redis 服务器本身上执行 GET 和 set 操作。它们是原子的,也允许您添加逻辑。
我最终使用了 redlock-py, an implementation of the redlock algorithm that the Redis docs recommend for creating write locks: https://redis.io/topics/distlock。对于希望在 Redis 中创建类似写锁的任何人来说,链接的文章都是很棒的读物。
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' ]
]
}))
使用此脚本,我们从项目中删除了所有自定义脚本。
我遇到这个 post 寻找类似类型的功能,但我没有看到任何吸引我的选项。我选择用 Rust 编写一个小模块来提供这种确切类型的操作:
https://github.com/KennethWilke/redis-setif
使用此模块,您可以通过以下方式执行此操作:
SETIF <key> <expected> <new>
HSETIF <key> <field> <expected> <new>