在Linux上使用O_DIRECT


23

如果这个问题太面向程序员,请告诉我。我想知道是否有人熟悉Linux 2.6上的open()系统调用的O_DIRECT标志?Linus贬低了它的使用,但是高性能文件写入似乎表明了它的使用。我想知道任何现实世界的经验和建议。

更多信息:我正在使用的应用程序确实维护了自己的缓存,并且这样做的速度平均提高了5倍或更多。写入文件时,必须将高速缓存的内容写出到文件系统高速缓存中,这似乎是多余的,并且会影响性​​能。

Answers:


17

好的,您要求获得经验,这使问题有些主观和争论,但可以通过。

Linus说,提到人们通常归因于O_DIRECT的用途,对于这些用途,IMO Linus基本上是正确的。即使执行直接I / O操作,也无法将数据直接从设备传输到设备或从设备直接传输到程序语句,您需要一个缓冲区(由程序或设备填充)并通过系统调用传输到另一端。同样,为了使其高效,您将不想重新阅读刚刚阅读的内容,以防万一您再次需要它。因此,您需要某种类型的缓存...而正是内核提供了这种缓存,而没有O_DIRECT,即页面缓存!为什么不使用它?如果更多的进程想要同时访问同一文件,它也会带来好处,而使用O_DIRECT将会是一场灾难。

话虽如此,O_DIRECT的用途是:如果出于某种原因,您需要直接从块设备获取数据。它与性能无关。

使用O_DIRECT来提高性能的人们通常来自具有错误页面缓存算法的系统,或者没有POSIX建议机制的系统,甚至来自无意识地重复别人所说的话的人。为了避免这些问题,O_DIRECT是一种解决方案。Linux(OTOH)的理念是,您应该解决真正的根本问题,而根本问题是操作系统在页面缓存方面做得不好。

我将O_DIRECT用于cat的简单实现,以在机器中查找内存错误。这是O_DIRECT的一种有效用法。这与性能无关。


感谢您的信息,不胜感激。我已根据提示此问题的应用程序的特定条件更新了问题。如果您有关于POSIX建议机制的更多详细信息来编写文件,也将不胜感激。
Casualunixer

4
o_direct在开发人员想要在应用程序层(例如数据库)提供缓存机制的系统中也可能有用。
Jmoney38

它与性能无关。并非总是如此,特别是对于访问IO可以与内存带宽相媲美甚至是很大一部分内存带宽的高速设备而言。在这种情况下,跳过额外的副本到页面缓存中或从页面缓存中删除多余的副本会带来明显的性能优势。
安德鲁·亨利

13

其实,O_DIRECT 需要避免任何的

  • 缓存污染 -有时您会知道缓存没有任何开销,例如,在处理非常大的文件时,如果RAM只有2 GiB,则说64 GiB。用户决定验证的32 GiB种子文件似乎不太适合缓存。这只是额外的活动,并有其自身的开销。这可能会导致从缓存中删除一些非常有用的数据。
  • 双重缓存 -例如,某些RDBMS(例如MySQL)允许定义其自己的缓存。据称,数据库比不了解SQL规划等知识的内核虚拟内存更好地知道如何缓存以及缓存什么。

-看起来似乎不好。而且O_DIRECT并不意味着要更快,通常不是


10
posix_fadvise可以解决缓存污染问题。
psusi 2012年

我不认为虚拟内存与它有任何关系,它只是映射内存地址。缓冲区高速缓存/页面高速缓存就是您的意思。
ArekBulski

据我所知,缓存/缓存是UNIX中VM子系统的一部分,这就是为什么我使用此术语。感谢您的编辑。:)
poige

6

请注意,O_DIRECT在具有较新文件系统的较新内核中,使用可能会失败。例如,请参见此错误报告。因此,使用不仅经常令人怀疑,而且在下一代Linux发行版中可能根本无法使用。因此,即使您碰巧能够证明它可能有好处,我也不会打赌我的代码性能会很高。


1
错误报告实际上讨论了启用journal = data选项的文件系统的使用。该选项实际上与O_DIRECT标志相反。大多数ext3和ext4文件系统都没有设置此标志,如果已设置,则将其关闭将允许使用O_DIRECT打开文件。
Casualunixer 2011年

3

它与性能有很大关系。

一个有趣的例子是在mongodb中使用mmap引擎。正如其他人所述,最好使用O_DIRECT,在一段时间内不太可能读取数据。在mongodb中,数据库日志是使用O_DIRECT编写的,而数据和索引的写操作则是由页面缓存机制(pdflush)处理的,因为尽管O_DIRECT提供的带宽较小,但也意味着较小的延迟,因此减少了发生数据丢失的情况。意外中断(内核崩溃,磁盘或电源故障)。请注意,在将O_DIRECT写入提交到非易失性存储之前,仍然存在缓冲,这只会减少数据丢失。

O_DIRECT的另一个重要功能是,它提供了对写入顺序的更多控制。同样,它不能保证写入的顺序(除非您具有非易失性高速缓存磁盘控制器并且正在使用fifo调度程序,但是这些操作都有其自身的复杂性)。因此,尽管mysql将O_DIRECT用于其数据/索引以及日志,但可以预期后者通常将首先提交。

但重要的是要记住O_DIRECT破坏了资源分配的公平性。您的应用程序加速的原因之一是它减慢了其他工作。


您说它与性能有很大关系,但是,您提供了一个示例,其中将其用于减少延迟或订单写入。但是我确实同意它会影响性能。关于公平的公平点。
ArekBulski 2015年

您可以提供更多参考资料来解释什么时候不公平吗?
ACyclic

3

关于@Juliano已经说过的话。

检查posix_fadvise是否真正的问题是底层文件系统的缓存算法的不当行为,您可以尝试向其提供建议,如何使用文件系统。对于良好实现的fs,应该可以提高性能。(这里是指向涉及类似注意事项的另一个主题的链接/programming//a/3755818/544721


1
看起来posix_fadvise更改了内核使用的预读算法。问题中代码的关键因素是写入性能。问题在于写出缓冲区会先填充Linux缓存,然后内核在内存不足时必须转储。这是浪费时间,在这种情况下,输出应在到达磁盘的途中最少缓冲。
Casualunixer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.