内存映射文件:优缺点?

7
我需要在同一台机器上的两个Java应用程序之间共享数据(两个不同的JVM)。我需要分享的数据很大(约7 GB)。这些应用程序必须非常快地访问数据,因为它们必须以非常高的速率响应传入的查询。我不希望这些应用程序各自拥有数据的副本。
我发现其中一个选项是使用内存映射文件。应用程序A从某个地方获取数据(比如数据库),并将其存储在文件中。然后应用程序B可以使用java.nio访问这些文件。我不知道内存映射文件的确切工作原理,我只知道数据存储在文件中,而该文件(或其中的一部分)被映射到内存区域(虚拟内存?)。所以,这两个应用程序可以在内存中读写数据,并且更改会自动提交到文件中(我猜是这样?)。我也不知道完全映射在内存中的文件是否有最大大小限制。
我的第一个问题是在这种情况下两个应用程序分享数据的不同可能性是什么(我是指考虑到数据量非常大,对此数据的访问必须非常快)?我在这里强调这个问题与内存映射I/O无关,它只是为了了解解决相同问题的其他方法。
我的第二个问题是使用内存映射文件的利弊是什么?
谢谢

你能否提供更多细节,关于你如何使用内存映射文件? - DarthVader
我看到这个问题不是关于在其他程序中触发某些操作。如果是这样,为什么不使用一个共同的数据库来共享数据呢? - Aravind Yarram
@Pangea 我有时间访问限制,应用程序必须快速访问数据。 - manash
1
“我猜可能有一些解决方案不适用于我的情况?”这并不是真的。维基百科文章中的所有IPC通信技术都适用于您的情况。您选择了其中之一。该文章非常清楚地描述了它们中的所有内容。不清楚什么让您感到困惑,或者您需要了解更多信息。您能否扩展或澄清您的问题?您能引用维基百科文章中让您感到困惑或不完整的具体部分吗? - S.Lott
1
有很多解决方案,但某些方案不符合我的要求。错误。文件并不慢,它们非常快速。你可以快速共享物理文件。套接字也很快,并且可以处理大量数据。共享内存实际上就是内存映射文件。其余的值得研究。你想知道什么?能具体点吗? - S.Lott
显示剩余11条评论
2个回答

12

我的第一个问题是,两个应用程序共享数据的不同可能性有哪些?

正如S.Lott指出的那样,有很多机制:

我的第二个问题是使用内存映射文件的优缺点是什么?
优点:
- 非常快 - 取决于你如何访问数据,可能可以使用zero-copy机制直接操作数据而不会有速度惩罚。必须注意以一种一致的方式更新对象。 - 应该非常可移植 - 在 Unix 系统上可能已经有了 25 年(左右),显然 Windows 也有相应的机制
缺点:
  • 单系统共享。如果您想在多台机器上分发应用程序,则共享内存不是一个很好的选择。分布式共享内存系统可用, 但我认为它们非常像错误的接口。
  • 即使在单个系统上,如果内存位于单个NUMA节点上,但需要由来自多个节点的处理器访问,则节点间请求可能会显着减慢处理速度,与给每个节点提供其自己的内存段相比。
  • 您不能只存储指针--一切都必须存储为基地址的偏移量,因为内存在不同进程中可能映射到不同的位置。我不知道这对Java对象意味着什么,尽管聪明人可能已经尽力使其对Java程序员透明。如果您没有使用他们提供的机制,则可能必须自行完成工作。(在Java中没有实际的指针,因此这可能不是很繁琐。)
  • 一致地更新对象被证明非常困难。在消息传递系统中传递不可变对象通常会导致具有更少并发错误的程序。(在Erlang中进行并发编程感觉非常自然和简单。在更命令式语言中进行并发编程往往会引入大量新的并发控制:信号量互斥锁自旋锁监视器。)

感谢sarnold提供详细的答案。那么操作系统级别的解决方案和可移植性呢?当你说应用程序级别时,你是指它由JVM处理并且具有可移植性吗? - manash
@MickaelMarrache:所谓“应用级别”,是指您作为应用程序作者必须提供基础设施,无论是运行RabbitMQ、Linda、Memcached、CORBA还是RESTful Web服务。 (它们是否可以在同一个JVM中运行是另一回事。)所有操作系统级别的服务都由操作系统提供-这可能意味着您需要使用[额外的模块](http://bmsi.com/java/posix/index.html)才能本地使用它们。 - sarnold

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接