问题标签 [fsync]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1749 浏览

c# - 寻求的解释/信息:Windows 使用“fsync”写入 I/O 性能 (FlushFileBuffers)

这个问题是我之前发布的一个问题的后续:Windows fsync (FlushFileBuffers) performance with large files。我在哪里找到了可能的解决方案,但也找到了新问题。

在对 fsynced 写入的不同场景进行基准测试时,我发现了许多令人惊讶的结果。我希望有人可以帮助解释或指出我解释这些结果的信息方向。

该基准测试所做的是将随机块(4096 字节大的页面)以 8 页(32 K)的批次顺序写入文件,然后刷新写入。它总共写入 200000 页,总计 800 MB 和 25000 次刷新。在开始写入之前,文件的大小设置为其最终长度。

它总共支持 4 个选项,其中所有组合都运行:

  • 在写入批处理或正常刷新 (NS) 后执行“fsync”/FlushFileBuffers操作 (FS)。
  • 在开始写入之前将单个字节写入文件的最后一个位置 (LB) 或将文件留空 (E)。
  • 使用普通缓冲写入 (B) 或无缓冲/直写 (WT) 写入(使用 FILE_FLAG_NO_BUFFERING 和 FILE_FLAG_WRITE_THROUGH)。
  • 直接写入文件流,即通过文件句柄 (F) 或使用内存映射 (MM) 间接写入文件。

下表总结了我在我的系统(带有慢速主轴磁盘的 64 位 Win 7 笔记本电脑)上对这些选项的所有组合的发现。

所有选项组合的基准测试结果

我发现“fsynced”缓冲写入的性能随着文件的大小呈指数下降到令人难以置信的低吞吐量,这使得在结合大文件时这样做不可行。如果文件的最后一个字节被写入(选项 LB),吞吐量会更低,所以我担心在随机而不是顺序写入场景中,性能会更加显着。

然而,令人惊讶的是,对于无缓冲/直写 I/O,吞吐量保持不变,与文件大小无关。最初(前 100-200 MB)它的吞吐量低于缓冲写入,但之后平均吞吐量迅速赶上,它完成写入 800 MB 的速度大大加快。更令人惊讶的是,如果文件的最后一个字节被写入,吞吐量会增加 2 倍。

当通过内存映射文件写入文件时,性能会出现同样的指数下降,在使用无缓冲/直写标志打开文件的情况下也是如此。同样,如果文件有一个字节写入其最后位置,则性能会更差。

更新 根据霍华德的解释herehere,我在开始写入之前重新运行测试而不创建新文件(即打开现有的、完全写入的文件并覆盖它)。我已经更新了原始问题中的代码,以反映为此测试所做的更改。结果部分符合他对 Linux 的解释和发现。但也有一些值得注意的例外。下表提供了结果,红色突出显示显着变化,蓝色突出显示未发生变化的情况,这令人惊讶(即,如果霍华德解释中提到的影响是唯一起作用的影响,则与预期不符)。

覆盖现有文件时的结果

对于使用“fsync”刷新的缓冲写入文件(即不通过 memmap),性能现在已从指数衰减变为恒定趋势。但是,现在比以前的测试场景需要更长的时间。吞吐量是恒定的 1.5 MB/s,之前它从 20 MB/s 左右开始呈指数衰减到 1.5 MB/s 左右。似乎一种可能的解释是文件元数据在每次刷新时也会被刷新,从而导致整个磁盘旋转以寻找元数据的位置。

对于“直写”到文件的场景,是否写入最后一个字节的结果现在是相同的,这与霍华德解释的预期一致。

然而,除了一个值得注意的例外,对内存映射的写入并没有真正改变,这令人惊讶。它们仍然显示出相同的写入性能指数衰减(从大约 20 MB/s 开始衰减到 1.8 MB/s)。这表明存在不同的机制。一个值得注意的例外是,如果底层文件是在没有 FILE_FLAG_WRITE_THROUGH 的情况下创建的,并且执行了“fsync”刷新。现在,此场景显示了恒定(较差)的性能,吞吐量约为 1.6 MB/s。由于我有一些疑问,我多次重新运行这个场景,每次都给出相同的结果。

为了进一步了解,我还使用一个较小的文件(50000 页,总计 200 MB)重新运行了这个测试,以确认 fsync 性能(对于缓冲 I/O)实际上确实取决于文件大小。结果如下所示,值得特别注意的结果以红色突出显示。

较小文件的结果

这些结果与较大文件的结果非常相关。值得注意的变化是,对于那些突出显示的内容,写入的性能更高一些,它们似乎达到了大约 7 MB/s 的限制。

根据迄今为止对我的系统的观察,总结为高度推测性的结论:

  • 带有缓冲 IO 的文件(即没有 FILE_FLAG_WRITE_THROUGH 标志)在 Windows 上的“fsync”性能随着已写入文件的字节数呈指数下降。原因似乎是每次都需要刷新文件元数据,这会导致磁盘查找到文件的开头。
  • 写入内存映射文件时,Windows 上的“fsync”性能也显示出指数级下降的性能。我目前没有解释导致这种情况的确切机制。

鉴于观察到的性能,至少对于我的用例而言,这两个 I/O 选项并不代表可行的解决方案。

根据Greg 的建议,我将在关闭 Windows 磁盘缓存的情况下重新运行测试,并且我还将运行 Howard 提供的基准代码,以排除由于我自己的错误导致结果出现偏差的可能性。

更新 2 我已经完成了测试,目前正在编译结果。为了不写“完整的历史”,我将用结果、发现和一些结论的总结来替换这个问题的当前内容。Howard 对这个问题的回答,以及在 .NET 代码旁边运行他的 c 基准代码的能力是最有用的。这些结果与应用程序的相关性非常好。Rlb 的回答帮助我更好地了解与磁盘相关的“合理数字”是什么。谢谢。

部分问题仍未得到解答。特别与写入内存映射时观察到的性能下降(和文件大小相关)有关。它可能与搜索/元数据刷新有关,但我还不清楚为什么/如何。

0 投票
0 回答
348 浏览

c++ - fclose、fsync 和硬件看门狗

我遇到了一个有趣的问题,对我来说毫无意义。我正在写入文件,2 秒后硬件看门狗被触发,计算机重置。但是,我没有看到我对文件的最后一次写入。我在 fsync 和 fclose 之后放置了一个 print 语句,它正在被打印出来,所以我知道它们被调用时有足够的时间……但它似乎并没有真正写入文件。这是在 C++ 中。我必须延迟 6 秒才能看到写入显示。有什么想法会导致这种行为???

0 投票
1 回答
461 浏览

java - java.io.FileDescriptor.sync() 在 Linux 上 fsync 目录吗?

fsync(2) 手册页告诉同步目录是否明确需要同步文件。

io包中Java的sync方法怎么样?有没有在意?它是否取决于操作系统和/或文件系统?

我在http://docs.oracle.com/javase/7/docs/api/java/io/FileDescriptor.html#sync中发现没有任何帮助...

0 投票
0 回答
101 浏览

linux - 伪造 fsync 调用以提高性能

到目前为止,运行我们使用以下组件构建的软件的所有测试需要一小时:Linux、PostgreSQL、Python、Django

我想如果我们伪造 fsync 调用,性能可能会有所提高。

PostgreSQL 可以选择禁用 fsync,但是告诉整个操作系统尽可能延迟 fsync 不是更好吗?

更新:我知道这是不安全的,服务器崩溃可能会使系统无法恢复。但这是一个不重要的詹金斯奴隶,可以快速重新设置。

Update2:PostgreSQL 只是在该主机上运行的众多服务之一。我在操作系统级别搜索解决方案。

0 投票
1 回答
649 浏览

c++ - Boost 对 fsync() 有什么影响吗?

Boost 库是否提供类似的东西fsync()

动机:可移植到 POSIX 之外 - 例如,在 Windows 上使用类似的功能。

0 投票
2 回答
1482 浏览

linux - 如何安全地在 U 盘上写入数据 - Linux (ARM) - C++

我正在尝试在 USB 记忆棒上复制一些文件夹和文件,并且在一切完成后立即移除 USB 记忆棒。实现是这样的:

  • 使用在 U 盘上创建相应的文件夹结构mkdir
  • fsync在创建文件夹后的每个目录描述符上
  • 复制文件内容(使用 C++ 流)
  • fsync复制每个文件后的每个文件描述符

复制最后一个文件后,我立即移除了 USB 记忆棒(约 500 毫秒 - 1 秒)。但有时会丢失整个文件夹结构。为了避免这种情况,我fsync在复制最后一个文件后再次在每个目录描述符上使用。这次所有文件和文件夹都存在于 U 盘上,但有时我的文件夹结构中有垃圾或 U 盘损坏。U 盘文件系统是 vfat。关于如何正确保存数据的任何想法?

0 投票
1 回答
53 浏览

system-calls - 操作系统是否可以使用 fsync(2) 中断对 write(2) 的调用

我有一个 write(2) 循环,其中包含任意数量的数据 + EOL 和一个 fsync(2) 逐行附加到文件中。

进程崩溃能否让我留下一个文件,该文件将 write(2) 调用中的一半数据写入文件?我的理论是,如果操作系统偶尔调用 fsync,那么在调用 write(2) 时可能会发生巧合,使文件只写了一半的行,而没有结束新行。

0 投票
1 回答
1060 浏览

mongodb - db.fsyncLock() 未经 MongoDB 许可(启用身份验证)

我已将身份验证添加到我的 MongoDB 实例中。我使用以下命令创建了一个用户

我想执行一个db.fsyncLock()它说:

我做错了什么?谢谢!

0 投票
0 回答
676 浏览

mongodb - MongoDB 数据库中的 db.fsyncLock() 和 db.fsyncUnlock()(已启用身份验证)将其阻止

我执行了一个

  1. db.fsyncLock()
  2. 备份订单
  3. db.fsyncUnlock()

后来,我尝试在数据库中做一些常见的操作,比如 find() ,但它被阻止并且不返回任何东西。我必须重新启动 mongodb 才能使其再次工作。

我做错了什么?

0 投票
0 回答
69 浏览

linux - fsync 的性能在 Linux 2.6.32 ext2 文件系统上得到了混合结果

当我在我的 Linux 机器上测试 fsync 的性能时,我发现 fsync 将数据插入到文件中会增加文件时会花费大量时间,但在插入仅覆盖现有内容而不增加文件大小的数据时,它的执行速度要快 100 倍。

环境:2-CPU 12 核 Linux 版本 2.6.32_1-14-0-0 (scmpf@pwd) (gcc 版本 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)) #1 SMP Mon Mar 31 10:42:09 CST 2014 ext2 文件系统

测试代码:

结果:

在 "echo "" >/home/zhangguangzhou/tmp/0" 之后运行上面的 test_fsync 程序,这会清空文件,每个 fsync 平均花费 8ms。但是当重复运行时,平均花费 50 us。在第二次及以后的运行中。当我从文件中间测试插入数据或插入不同大小的数据时,结果几乎没有变化。

问题: 如果写入正在增长文件,那么 fsync 的额外时间是多少?

我想到了fysnc中的inode IO,但是file-growth write和no-file-growth write的inode IO是一样的,因为它们都需要更新文件修改时间的inode元数据。