2

使用文件进行进程间通信的优缺点是什么?让我介绍一下我提出这个问题的背景。

问题是具有一些约束的经典生产者消费者问题。生产者是一组运行在机器集群上的协作进程,并使用广播相互通信。每个进程都有自己知道的本地用户,并通过上述广播机制让其他进程知道他们。到目前为止,正在广播/共享的状态信息还没有被持久化,但现在它需要被持久化。

该系统已经在生产环境中运行多年,现在支持成千上万的用户,人们可以理解的是,人们非常担心为此添加任何额外的依赖项以增加对持久性的支持。我们选择的路径是在现有进程中生成一个新线程,将本地流量写入文件系统上的文件,然后由新进程读取(我们称之为消费者)并持久化。我们看到这种方法的优点是:

  1. 我们免费获得持久性。如果新进程出现问题,我们在将其写入文件系统时不会丢失任何本地流量。只要消费者知道它在哪里停止,只要它出现,它就可以开始处理数据。
  2. 使用队列库和普通的旧 unix 文件 IO 没有学习曲线。
  3. 最大的优点是我们根本不影响当前的生产者进程,除了文件写入的新线程。

这种方法的一些问题是:

  1. 文件锁定和争用及其对性能的影响。
  2. 确保写入缓冲区已刷新,并且生产者仅在将完整事件写入文件后才释放文件锁。消费者应该阅读不完整的记录。

想法?这种方法是否幼稚,我们是否应该为使用现成的持久队列库的加速时间支付初始成本?这里的要点是我们希望对当前进程产生最小的影响并且不添加任何依赖项。

4

1 回答 1

1

我最近面临这个选择,并考虑充分了解 Berkeley DB 以使用其队列机制。但最终我决定改用 Unix 文件系统并使用Posix 信号量编写我自己的原子队列原语。如果所有进程都在一台机器上,这很容易。atomic put函数大约有十几行代码;原子获取,因为如果队列为空,它必须等待,大约是大小的三倍。

我的建议是你设计一个能隐藏这些细节的原子队列 API 。(遵循 Parnas 的建议,即使用接口隐藏可能更改的设计细节的经典示例。)您可以使用普通 Unix 文件 I/O 执行 API 的第一个版本。然后,您可以尝试诸如锁定、Berkeley DB 或信号量之类的变体——所有这些都具有“对当前进程的最小影响”。

在您尝试某些东西之前,您不会知道性能影响。真实文件系统上的文件锁定非常好;NFS 上的文件锁定是一种负担。

于 2009-05-03T02:34:13.547 回答