首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Redis事务与redlock解决丢失的更新问题

使用Redis事务与redlock解决丢失的更新问题
EN

Stack Overflow用户
提问于 2020-12-08 17:51:49
回答 1查看 1.3K关注 0票数 0

我正在使用一个具有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);}}

我在上面看到的不好的事情是:

  • 试接块
  • 在redis集群上,使用带有多个键的事务的可能性受到限制。

选项2. Redlock

,试图锁定已经锁定的资源不会立即导致失败吗?所以红锁在错误前尝试了N次?

如果是真的,那么这里是我的伪代码:

代码语言:javascript
复制
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绝对是一种更强大的技术。如果我在上述假设中错了,请纠正我。如果有人提供了一个代码解决类似问题的示例,因为我找不到类似的问题,那也是非常棒的。

EN

回答 1

Stack Overflow用户

发布于 2020-12-09 13:05:21

当您有一组要协调以创建原子操作的分布式组件集时,Redlock就是有用

您不会将其用于影响单个Redis节点的操作。这是因为Redis已经有了更简单、更可靠的方法来确保使用其单线程服务器的命令的原子性:事务或脚本。(您没有提到Lua脚本,但这是创建自定义原子命令的最强大方法)。

由于INCR在一个键上操作,因此在一个节点上操作,所以最好的实现方法是使用一个简单的Lua脚本。

现在,如果您想要使用跨越多个节点的一系列命令,那么无论是事务还是脚本都无法工作。在这种情况下,您可以使用Redlock或类似的分布式锁。但是,在Redis的设计中,您通常会尽量避免这种情况。具体来说,您可以使用散列标签强制某些键驻留在同一个节点上:

散列标记是一种确保在同一个散列槽中分配多个键的方法。这是用来在Redis集群中实现多键操作的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65204187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档