我应该为我的简单流程使用内存映射文件吗?

Posted

技术标签:

【中文标题】我应该为我的简单流程使用内存映射文件吗?【英文标题】:Should I use memory mapped files for my simple flow? 【发布时间】:2013-09-08 13:55:01 【问题描述】:

我有兴趣实现以下简单流程: 客户端向服务器进程发送一条服务器存储的简单消息。由于消息没有任何层次结构 IMO,因此最好的方法是将其保存在文件中而不是 rdb 中。 但我想弄清楚如何优化它,因为我认为有两种选择:

    服务器向客户端发送 200 OK,然后 然后 存储消息,以便 客户没有注意到任何延迟 服务器保存消息并然后发送 200OK 但随后 客户端注意到文件 I/O 的开销。

我更喜欢 (1) 的性能,但这可能会导致客户认为一切正常,而实际上从未保存过 msg(对于各种错误情况)。 所以我在考虑是否可以使用 nio 和内存映射文件。 但我想知道这是使用 mem 映射文件的好选择吗?将使用内存映射文件保证例如如果进程崩溃了,消息会被保存吗? 在我看来,流程将创建/打开和关闭许多文件,所以这是内存映射文件的良好候选者吗?

【问题讨论】:

文件 I/O 非常快,因为数据缓存在磁盘缓存 RAM 中。在测量之前我不会打扰;解决方案 1 不安全! @BasileStarynkevitch:如果 I/O 如此之快,那么为什么我们有内存映射选项? mmap 可用于大量 I/O - 但如果它有用,您必须进行基准测试(有时mmap 可能会减慢速度)。在你的情况下,网络也可能是一个瓶颈...... @BasileStarynkevitch:为什么我需要在这里进行基准测试?对我来说,很明显访问 HD 本身就很慢。除非我们使用我不使用的 SSD。 因为如果数据留在缓存中,文件 I/O 不需要做实际的磁盘 IO。见linuxatemyram.com等... 【参考方案1】:

服务器保存消息然后发送 200OK 但随后客户端注意到文件 I/O 的开销。

我建议你测试一下。我怀疑人类会注意到 10 毫秒的延迟,我希望您在处理较小的消息时会得到比这更好的结果。

所以我在考虑是否可以使用 nio 和内存映射文件。

我使用内存映射,因为它可以将每次写入的开销减少多达 5 微秒。这对你很重要吗?如果没有,我会坚持最简单的方法。

将使用内存映射文件保证例如如果进程崩溃了,消息会被保存吗?

只要操作系统不崩溃,就可以。

在我看来,流程会创建/打开和关闭许多文件,所以这是内存映射文件的好候选吗?

打开和关闭文件可能比写入数据更快更昂贵。 (按数量级)我建议将此类操作保持在最低限度。

你可能会觉得我的这个图书馆很有趣。 https://github.com/peter-lawrey/Java-Chronicle 它允许您以单位数微秒的顺序保存消息,对于文本,以亚微秒的顺序保存小二进制消息。

【讨论】:

我从未说过客户端会是人类。客户端将是客户端应用程序 我一定会检查你的图书馆。这个描述persisted, messaging and event driven in memory database 似乎是矛盾的。它是内存中的还是持久的? I use memory mapping as it can reduce the overhead per write by up to 5 micro-second。好处是只快了 5 毫秒还是总开销只有 5 毫秒? @Cratylus 5 微秒是 0.005 毫秒。 ;) 好处通常要小得多。更接近 2 微秒或 0.002 毫秒。 @Cratylus 它是“在内存中”和“持久化”的,即它具有内存中的性能,但也被操作系统持久化。

以上是关于我应该为我的简单流程使用内存映射文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用内存映射文件传递指针吗?

映射GPU内存时应该使用volatile吗?

有没有一种简单的方法可以将 CSV 文件中记录的行号映射到 POCO?

linux中匿名内存映射映射到哪个文件?

我最好为我的进程保留内存吗?

使用 mmap() 为 2D 数组初始化共享内存,是不是还需要为后续指针映射内存?我应该改用 shm 吗?