我正在使用一个具有2+节点的Redis集群。我试图找出哪种工具最适合处理并发事务或锁定。事务是有据可查,但我没有找到一个好的最佳实践-在红锁上的例子。我还想知道为什么存在两个工具,以及每个工具的用例是什么。
为了简单起见,让我们假设我想做一个并发的增量,并且Redis中没有INCR命令。
选项1.使用事务
如果我正确理解,NodeJS伪代码将如下所示:
transactIncrement =redisClient.watch(键) => { redisClient.watch (key);let value = redisClient.get(key);value = value + 1;const multi = redisClient.multi();尝试{等待redisClient.set(键,值,多);等待redisClient.exec(多);} catch (e) { //很可能是由于事务失败// TODO引发的错误:如果在每种情况下重新启动都是一个好主意,引入一个潜在的无限循环//任何东西,重新启动等待transactIncrement(key);}}
我在上面看到的不好的事情是:
选项2. Redlock
,试图锁定已经锁定的资源不会立即导致失败吗?所以红锁在错误前尝试了N次?
如果是真的,那么这里是我的伪代码:
redlockIncrement = async (key) => {
await redlock.lock(key, 1);
// below this line it's guaranteed that other "threads" are put on hold
// and cannot access the key, right?
let value = await redisClient.get(key);
value = value + 1;
await redisClient.set(key, value);
await redlock.unlock(key);
}摘要
如果我做得对,那么redlock绝对是一种更强大的技术。如果我在上述假设中错了,请纠正我。如果有人提供了一个代码解决类似问题的示例,因为我找不到类似的问题,那也是非常棒的。
发布于 2020-12-09 13:05:21
当您有一组要协调以创建原子操作的分布式组件集时,Redlock就是有用。
您不会将其用于影响单个Redis节点的操作。这是因为Redis已经有了更简单、更可靠的方法来确保使用其单线程服务器的命令的原子性:事务或脚本。(您没有提到Lua脚本,但这是创建自定义原子命令的最强大方法)。
由于INCR在一个键上操作,因此在一个节点上操作,所以最好的实现方法是使用一个简单的Lua脚本。
现在,如果您想要使用跨越多个节点的一系列命令,那么无论是事务还是脚本都无法工作。在这种情况下,您可以使用Redlock或类似的分布式锁。但是,在Redis的设计中,您通常会尽量避免这种情况。具体来说,您可以使用散列标签强制某些键驻留在同一个节点上:
散列标记是一种确保在同一个散列槽中分配多个键的方法。这是用来在Redis集群中实现多键操作的。
https://stackoverflow.com/questions/65204187
复制相似问题