【问题标题】:Share data between node child processes在节点子进程之间共享数据
【发布时间】:2016-06-24 00:02:32
【问题描述】:

我有一个在多个节点子进程中运行的小节点脚本,但我无权访问父进程。

脚本的目标很简单,从数组中随机返回一个元素。但是,返回的元素不能被任何其他子进程使用。

我能想到的唯一解决方案是使用 redis 或数据库,因为这是一个非常小的脚本,我想避免这种情况。

这是我希望我的代码看起来像的示例:

var accounts = [acc1, acc2, acc3]
function() {
  var usedAccounts = sharedStore.get('usedAccounts')
  var unusedAccounts = filter(accounts, usedAccounts)
  var account = getRandomAccount(unusedAccounts)
  usedAccounts.push(account)
  sharedStore.set('usedAccounts', usedAccounts)
  return account
}

到目前为止,我想到的解决方案都行不通,因为兄弟进程最初都得到一个分配给 usedAccounts 的空列表。

【问题讨论】:

  • 必须在节点中吗?
  • 同一台机器?如果是这样,计时器、“锁定文件”和共享文件的组合将起作用。尽管作为kludge。使用 Timer 获取共享文件上的锁,编辑共享文件,然后释放锁。你必须防止你的进程死亡而不释放锁。
  • 我以前从未做过这样的事情。计时器究竟是如何使用的?

标签: node.js concurrency


【解决方案1】:

有两个问题需要解决:

  1. 如何在多个节点进程之间共享数据,而不使用父进程在它们之间编组数据。
  2. 如何确保数据在所有共享进程中保持一致。

如何在多个节点进程之间共享数据。

鉴于您不想使用外部服务(如 Redis 或其他数据库服务)的限制,并且 nodejs 没有简单的方法来使用共享内存之类的东西,一个可能的解决方案是在两者之间使用共享文件所有的过程。每个进程都可以读取和写入共享文件,并使用它来获取它的userAccount 数据。

文件可以是 JSON 格式,看起来像这样:

[
      {
       "accountName":"bob",
       "accountUsed":false
      },
      {
       "accountName":"alice",
       "accountUsed":true
      }
]

这只是一个 userAccount 对象数组,还有一个标志,指示是否正在读取数据。

您的应用会:

GetAccountData()

  1. 打开文件
  2. 将文件读入内存
  3. 遍历数组
  4. 找到第一个可用的 userAccount
  5. accountUsed 标志设置为 true
  6. 将更新后的数组写回文件
  7. 关闭文件。

让多个进程读取和写入单个资源是一个众所周知的并发问题,称为Readers-Writers Problem.

如何确保数据在所有共享进程中保持一致。

为了保证数据的一致性,你需要保证每次只有一个进程可以从头到尾运行上面的算法。

操作系统可能提供文件的独占锁定,但我 nodejs 对此没有原生支持。

一种常见的机制是使用锁定文件,并使用它的存在来保护对上述数据文件的访问。如果它不能获取锁,它应该等待一段时间,然后尝试重新获取锁。

获取锁:

  1. 检查锁定文件是否存在。
  2. 如果存在锁定文件
  3. 设置定时器 (setInterval) 来获取锁
  4. 如果锁定文件不存在
  5. 创建锁定文件
  6. 如果锁文件创建失败(因为它存在--与另一个进程竞争)
  7. 设置一个定时器 (setInterval) 来获取锁
  8. 如果锁定文件创建成功
  9. GetAccountData();
  10. 删除锁定文件

这个解决方案应该可行,但并非没有杂乱无章。使用像锁这样的同步原语可能会导致您的应用程序死锁。此外,使用计时器定期获取锁是一种浪费,如果没有正确检查锁的创建,可能会导致竞争条件。

如果您的应用在删除锁定文件之前崩溃,那么您可能会造成死锁情况。为了防止这种情况发生,您可能需要放置一个最终未处理的异常处理程序来删除锁定文件(如果它是由进程创建的)。

您还需要确保您只持有足够长的时间来完成您的连续工作。持有锁的时间越长,会导致性能问题,并增加死锁的可能性。

【讨论】:

    【解决方案2】:

    我宁愿让每个进程都有自己可以编写的平面文件。并且每个进程将能够同时读取所有进程写入的所有文件,否则就不需要锁定文件。 尽管您必须弄清楚每个进程如何只写入自己的文件的逻辑,但是将所有这些文件一起读取会发现真相

    【讨论】:

      猜你喜欢
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2013-12-24
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      相关资源
      最近更新 更多