【问题标题】:Synchronise redis read and write with multiple threads in my node application在我的节点应用程序中使用多个线程同步redis读写
【发布时间】:2022-09-27 19:38:41
【问题描述】:

我有一个 nodejs 应用程序正在运行(haraka smtp 服务器),有 1 个主线程和 7 个工作线程。我正在使用 redis 读取一些计数器,并在一些操作后更新这些计数器。

我面临竞争条件的问题,其中一些线程在其他线程实际更新计数器之前读取计数器,因此计数器不匹配。理想情况下,它应该像一个线程对该特定键进行读写操作,然后其他线程应该继续进行操作。

我目前正在运行一个 redis 实例。是否可以通过多个线程和单个 redis 实例来避免这种竞争条件?

我读过有关 redlock 的信息,但 redis 网站说最好将 redlock 与至少 3 个 redis 实例一起使用。

  • 你考虑过使用 redis pub/sub 吗?这样您就可以触发从其他节点读取节点。
  • 嗨@JeanJacquesGourdin 我是 redis 新手,你能指导我完成它吗?
  • 我已经完成了 redis pub/sub,但我不知道如何在每个节点既是发布者又是订阅者的特定用例中使用它。在我的情况下,实际发生的是我将 ip 地址和一些计数器存储到 redis,以便将这些 ip 的使用限制为特定计数。现在,当收到电子邮件请求时,它会检查当前计数并在使用 ip 时增加计数,但如果多个线程同时读取计数可能会导致计数不匹配。
  • 我想我误解了你想要的。如何触发电子邮件请求?此事件是否触发只能由多个工作人员完成的流程?计数的目的是什么?
  • 嗨@JeanJacquesGourdin 我正在运行一个 haraka 邮件服务器,它将侦听任何电子邮件请求并将其发送到特定域,如 gmail 或 yahoo,在服务器中我绑定我的自定义 IP 并将其发送到它目的地,所以现在我只想绑定一个特定的 IP 固定次数

标签: node.js multithreading redis node-redis redlock


【解决方案1】:

对于您的用例,我认为没有办法完全排除读取冲突,但是您可以通过在执行实际过程之前对计数器进行读/写来减少数据不一致的时间窗口,您可以使用 redis 流确保每个请求都被处理,只处理一次,并减少不一致的时间窗口。

它可以这样工作:

  1. 收到一封电子邮件请求
  2. workerINCRkey,它返回counter的新值
  3. 如果计数器太大,请自行处理
  4. 否则,工作人员将事件及其计数器推送到 redis 流上
  5. redis 流通过消费者组向工作人员分发(扇出)事件
  6. 工作人员(可能是同一个工作人员,也可能是另一个工作人员)收到事件并必须对其进行处理
  7. 一旦处理完毕,它会将XACK 告知redis 流以确保事件已被处理

    编辑:

    再次阅读这种方式,在我看来,重要的部分是使用INCR 作为获得新价值的一种方式。它确保每个请求都得到不同的计数器处理。如果您想轻松地做到这一点,redis 流很好,而且几乎没有必要。

【讨论】:

    猜你喜欢
    • 2015-02-06
    • 2018-12-17
    • 2012-10-22
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 2018-03-01
    相关资源
    最近更新 更多