在节点子进程之间共享数据

时间:2016-06-24 00:02:33

标签: node.js concurrency

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

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

我能想到的唯一解决方案是使用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的空列表。

2 个答案:

答案 0 :(得分:2)

您需要解决两个问题:

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

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

    该文件可能是JSON格式的,如下所示:

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

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

    你的app应该:

    GetAccountData()

    1. 打开文件
    2. 将文件读入内存
    3. 迭代数组
    4. 找到第一个可用的userAccount
    5. accountUsed标志设置为true
    6. 将更新后的数组写回文件
    7. 关闭文件。
    8. 有多个进程读取和写入单个资源是一个很好理解的并发问题,称为Readers-Writers Problem.

      如何确保所有共享流程中的数据一致。

      为确保数据一致,您需要确保一次只能有一个进程从头到尾运行算法。

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

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

      获得锁定:

      1. 检查锁文件是否存在。
      2. 如果存在lockfile
      3. 设置计时器(setInterval)以获取锁定
      4. 如果锁文件不存在
      5. 创建锁文件
      6. 如果锁文件创建失败(因为它存在 - 与另一个进程竞争条件)
      7. 设置计时器(setInterval)以获取锁定
      8. 如果锁文件创建成功
      9. GetAccountData();
      10. 删除lockfile
      11. 这个解决方案应该可行,但它并非没有kludge。使用像锁一样的初始化可能会导致应用程序死锁。使用计时器定期获取锁定也是浪费,如果没有正确检查锁定,可能会导致竞争状态。

        如果您的应用在删除锁定文件之前崩溃,那么您可能会创建死锁情况。为了防范这种情况,您可能希望放置一个最终未处理的异常处理程序,以便在该进程创建时删除该锁定文件。

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

答案 1 :(得分:0)

我宁愿让每个进程都有自己的平面文件,他们可以编写。并且每个进程将能够同时读取所有进程写入的所有文件,否则将不需要锁定文件。 尽管您将不得不弄清楚每个进程如何仅写入自己的文件的逻辑,但是将所有这些文件一起读取将带出事实的真相