我有多个编写器在redis中覆盖相同的密钥。我如何保证只选择一个写入最后?
我可以在Redis中执行写同步吗?首先同步编写器吗?
背景: 在我的系统中,一个独特的调度程序发送工作对各种工作人员。然后每个工作人员在Redis中写入结果覆盖相同的密钥。我需要确保只有最后一位接收调度员工作的工作人员才能在Redis中写道。
答案 0 :(得分:2)
使用有序集( ZSET ):添加等于unix时间戳的分数,然后删除除最高等级以外的所有分数。
Redis Ordered set是一个集合,其中每个条目还有得分。该集合根据分数排序,有序集合中元素的位置称为排名。
按顺序:
python中的示例:
# timestamp contains the time when the dispatcher sent a message to this worker
key = "key_zset:%s"%id
pipeline = self._redis_connection.db.pipeline(transaction=True)
pipeline.zremrangebyscore(key, 0, t) # Avoid duplicate Scores and identical data
pipeline.zadd(key, t, "value")
pipeline.zremrangebyrank(key, 0, -2)
pipeline.execute(raise_on_error=True)
答案 1 :(得分:0)
如果我是你,我会使用redlock。
在您写入该密钥之前,您获取该密钥,然后更新它,然后释放锁。
我使用Node.js所以它看起来像这样,实际上不是正确的代码,但你明白了。
Promise.all(startPromises)
.bind(this)
.then(acquireLock)
.then(withLock)
.then(releaseLock)
.catch(handleErr)
function acquireLock(key) {
return redis.rl.lock(`locks:${key}`, 3000)
}
function withLock(lock) {
this.lock = lock
// do stuff here after get the lock
}
function releaseLock() {
this.lock.unlock()
}
答案 2 :(得分:0)
您可以将redis管道与Transaction一起使用。
Redis是单线程服务器。服务器将同步执行命令。当使用带有事务的Pipeline时,服务器将以原子方式执行管道中的所有命令。
<强>交易强>
MULTI,EXEC,DISCARD和WATCH是Redis交易的基础。它们允许在一个步骤中执行一组命令,具有两个重要保证: 事务中的所有命令都被序列化并按顺序执行。在执行Redis事务的过程中,永远不会发生由另一个客户端发出的请求。这可以保证命令作为单个隔离操作执行。
python
中的一个简单示例with redis_client.pipeline(transaction=True) as pipe:
val = int(pipe.get("mykey"))
val = val*val%10
pipe.set("mykey",val)
pipe.execute()