我们应该在ext3上mount data = writeback和barrier = 0吗?

我们已经在托pipe公司的虚拟机上运行了服务器,并且刚刚注册了一个专用主​​机(AMD Opteron 3250,4核,8GB RAM,2 x 1TB的软件RAID,ext3)。

在运行性能testing时,我们注意到一些SQLite转换(插入,删除和/或更新的组合)比我的2010年MacBook Pro长10倍到15倍。

经过大量的search和阅读,我们看到了挂载选项,它们是:

data=ordered,barrier=1 

我们已经做了一些尝试,并获得了最好的performance

  data=writeback,barrier=0 

我已经阅读了这些内容,了解他们正在做什么的基本知识,但是我对这样的跑步是否是个好主意没有很好的理解/感觉。

问题

上述configuration是否合理考虑托pipe服务?

如果我们发生停电或严重故障,那么最终可能会丢失数据或损坏文件。 如果我们每15分钟拍摄一次数据库快照,这可能会缓解这种情况,但是在拍摄快照时数据库可能不会同步。 我们应该如何(可以)确保这种快照的完整性?

还有其他的select我们应该考虑吗?

谢谢

第一个build议
如果你不能丢失任何数据(我的意思是一旦用户input了新的数据,如果在接下来的几秒内不会丢失的话),而且因为你没有像UPS那样的东西,那么我就不会删除写入屏障,也不会我切换到回写。

消除写入障碍
如果删除了写障碍,那么万一发生崩溃或断电,文件系统将需要执行fsck来修复磁盘结构(请注意,即使在障碍打开的情况下,大多数日志文件系统仍然会执行fsck,即使重放的期刊应该已经足够了)。 删除写障碍时,build议尽可能删除任何磁盘caching(在硬件上),这有助于最大限度地降低风险。 尽pipe如此,你应该将这种变化的影响作为基准。 你可以试试这个命令(如果你的硬件支持的话) hdparm -W0 /dev/<your HDD>
请注意,ext3对元数据更改使用2个屏障,而使用装入选项journal_async_commit时,ext4仅使用一个屏障。

尽pipeTed T'so解释了为什么在ext3早期发生的一些数据损坏(为了内核3.1的默认closures),日志被放置在一个方式,除非发生日志日志回卷(日志是一个循环日志)数据以安全顺序写入磁盘 – 日志第一,数据第二 – 即使硬盘支持重新sorting写入。
基本上,当日志日志包装时,会发生系统崩溃或功率损失,这是不吉利的。 但是,您需要保持data=ordered 。 尝试基准data=ordered,barrier=0另外。

如果你可以承受失去数秒的数据,你可以激活这两个选项data=writeback,barrier=0但是然后尝试尝试commit=<nrsec>参数。 在这里查看这个参数的手册。 基本上你给了几秒钟,这是一个ext3文件系统将同步其数据和元数据的时期。
你也可以尝试去找一些关于脏页面(那些需要写入磁盘的内容)的内核可调参数,这里有一篇很好的文章解释了这些可调参数的一切,以及如何使用它们。

关于障碍的总结
您应该对可调参数的几个组合进行基准testing:

  1. 使用data=writeback,barrier=0hdparm -W0 /dev/<your HDD>结合使用
  2. 使用data=ordered,barrier=0
  3. data=writeback,barrier=0与另一个挂载选项commit=<nrsec>结合使用,并为nrsec尝试不同的值
  4. 使用选项3.并尝试在内核级进一步调整脏页。
  5. 使用safe data=ordered,barrier=1 ,但尝试其他可调参数:特别是文件系统电梯 (CFQ,Deadline或Noop)及其可调参数。

考虑转移到ext4并进行基准testing
正如所说的ext4需要比ext3更less的障碍写作。 此外,ext4支持大文件可能带来更好的性能的范围。 所以这是一个值得探索的解决scheme,特别是因为它很容易从ext3迁移到ext4而无需重新安装: 官方文档 ; 我在一个系统上做了这个,但使用这个Debian指南 。 内核2.6.32以来Ext4非常稳定,所以在生产环境中使用是安全的。

最后的考虑
这个答案远未完成,但它给你足够的材料开始调查。 这很大程度上取决于需求(在用户或系统级),很难有一个直接的答案,对此感到遗憾。

警告:下面可能有不准确的地方。 我一直在学习这个东西,所以拿一点盐。 这是相当长的,但是你可以阅读我们正在玩的参数,然后跳到最后的结论。

有几个层可以让你担心SQLite的写入性能:

考虑表现的不同层次

我们看了一下用粗体突出显示的那些。 具体的参数是

  • 磁盘写入caching。 现代磁盘具有RAM高速caching,用于优化与旋转磁盘相关的磁盘写入。 启用此function后,可以将数据写入无序块,因此如果发生崩溃,最终可能会写入部分写入的文件。 使用hdparm -W / dev / …检查设置,并使用hdparm -W1 / dev / …(将其打开,使用-W0将其closures)进行设置。
  • 屏障=(0 | 1)。 网上有很多评论,说“如果你运行障碍= 0,那么没有启用磁盘写入caching”。 你可以在http://lwn.net/Articles/283161/find关于障碍的讨&#x8BBA;
  • data =(journal | ordered | writeback)。 请参阅http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html以获取这些选项的说明&#x3002;
  • 犯= N。 告诉ext3每N秒同步所有数据和元数据(默认为5)。
  • SQLite的杂注同步= ON | closures。 当打开时,SQLite将确保事务“写入磁盘”,然后继续。 closures本质使得其他设置在很大程度上不相关。
  • SQLite的杂注cache_size。 控制SQLite将为内存caching使用多less内存。 我尝试了两种尺寸:一种是整个数据库适合caching,另一种caching是最大数据库大小的一半。

阅读更多关于ext3文档中的ext3选项。

我运行了一些这些参数组合的性能testing。 ID是一个场景编号,下面提到。

我试过的场景

我以我的机器上的默认configuration作为scheme1开始。scheme2是我认为是“最安全”的,然后在适当/提示的情况下尝试各种组合。 这可能是我最终使用的地图最容易理解的:

将场景与参数相关联

我写了一个testing脚本,它运行了大量的事务,插入,更新和删除,所有表都只有INTEGER,仅TEXT(带有id列),或者是混合的。 我在上面的每个configuration上运行了很多次:

阴谋显示情景的时间

底部的两个场景是#6和#17,它们有“杂注同步=closures”,所以他们是最快的并不奇怪。 下一个三个是#7,#11和#19。 这三个在上面的“configuration图”上以蓝色突出显示。 基本上configuration是磁盘写入caching,屏障= 0,数据设置为'日志'以外的东西。 在5秒(#7)和60秒(#11)之间改变提交似乎没有什么区别。 在这些testing中,如果data = ordered和data = writeback之间有任何差异,这似乎没有太大的差别,这让我很吃惊。

混合更新testing是中等高峰。 在这个testing中,有一组场景更明显地慢一些。 这些都是与数据=杂志的 。 否则,其他情况之间没有太大的区别。

我有另外一个时间testing,在不同types的组合上做了插入,更新和删除的更多异构混合。 这些花了很长时间,这就是为什么我没有把它包括在上面的情节:

混合类型和插入/更新/删除

在这里你可以看到写回configuration(#19)比有序的configuration(#7和#11)慢一点。 我希望回写速度稍微快一点,但也许这取决于你的写作模式,或者我只是没有足够的ext3读取:-)

各种情况有点代表我们的应用程序完成的操作。 select一个场景的候选名单后,我们用我们的一些自动化testing套件进行时序testing。 他们符合上述结果。

结论

  • 提交参数似乎没什么区别,所以我们在5秒后离开。
  • 我们打开磁盘写入caching, barrier = 0data = ordered 。 我在网上阅读了一些认为这是一个糟糕的设置的东西,其他人似乎认为这应该是在很多情况下的默认设置。 我想最重要的是你做出明智的决定,知道你正在做什么权衡。
  • 我们不打算在SQLite中使用同步编译指示。
  • 如我们所料,设置SQLite cache_size编译指示使数据库适合内存可以提高某些操作的性能。
  • 上述configuration意味着我们正在承担更多的风险。 我们将使用SQLite备份API将部分写入时的磁盘故障风险降至最低:每N分钟拍摄一次快照,并保留最后一个M。 我在运行性能testing时testing了这个API,这让我们有信心走这条路。
  • 如果我们还想要更多的东西,我们可以看看内核,但我们没有去那里足够的东西改善了。

感谢@惠更斯的各种提示和指针。