在我的应用程序中,有一个批处理机制。它(理论上)在redis列表中累积项目,然后立即处理它们并清理(如果需要)。这是代码:
def with_private_key redis, name
return unless redis.exists name
# atomically rename to a random name, so that the batch isn't appended to.
tmpname = "temp:#{SecureRandom.hex}"
redis.rename name, tmpname
# get batch elements
batch = redis.lrange(tmpname, 0, -1).map{|b| JSON.parse(b) }
begin
# actually do something with the batch
yield batch
rescue => ex
# revert and give up
redis.rename tmpname, name
raise
else
# if there was no exception - drop the temp key, it's not needed anymore
redis.del tmpname
end
end
这是这个实现的一个小问题:有时临时密钥不会被删除并保留在数据库中。当我撰写这个问题时,我意识到反向重命名可能会失败,因为已经使用新批次创建了新密钥。
那么,我该如何改进这个算法?
app_id
,但这可能不重要。)我看到我关于重命名的理论是无效的。 RENAME command:
将键重命名为newkey。当源名称和目标名称相同或者密钥不存在时,它会返回错误。如果newkey已经存在,则会被覆盖。
答案 0 :(得分:0)
我会尝试
batch, _ = redis.multi do |r|
r.lrange name, 0, -1
r.ltrim name, 0, -1
end
如果客户端在获取批次并修剪列表后崩溃,则可能会丢失批次。