随机更新磁盘是否主要在标准中绑定并仅附加数据库?

时间:2011-02-05 00:26:12

标签: algorithm database-design data-structures

如果我有大型数据集并进行随机更新,那么我认为更新主要是磁盘限制的(如果仅附加数据库,那么不是关于搜索而是关于带宽我认为)。当我稍微更新记录时,必须更新一个数据页面,所以如果我的磁盘可以写入10MB / s的数据并且页面大小是16KB,那么我每秒最多可以有640个随机更新。仅附加数据库apout 320每秒,因为一个更新可能需要两个页面 - 索引和数据。在其他数据库中,由于ranom寻求更新页面的位置可能更糟,如每秒100次更新。

我假设缓存中的一个页面在写入之前只有一个更新(随机更新)。对于所有数据页周围的随机插入(例如,不是按时间排序的UUID),甚至是最差的,都会向前推进。

我指的是必须将脏页(更新后)刷新到磁盘并同步(不能再保留在缓存中)的情况。那么每秒更新次数是否在这种情况下磁盘带宽有限?我的计算可能是每秒320次更新吗?也许我错过了什么?

1 个答案:

答案 0 :(得分:2)

“这取决于。”

要完成,还有其他事情需要考虑。

首先,区分随机更新和追加的唯一方法是涉及头部搜索。随机更新将使头部在整个盘子上跳舞,而追加将理想地跟踪记录播放器。这也假设每个磁盘写入都是完全写入,并且完全独立于所有其他写入。

当然,这是一个完美的世界。

对于大多数现代数据库,每次更新通常至少涉及2次写入。一个用于实际数据,另一个用于日志。

在典型情况下,如果更新一行,数据库将在内存中进行更改。如果您提交该行,数据库将通过在日志中记录,同时将实际脏页保留在内存中来确认。稍后,当数据库检查点时,它会将脏页面对齐到磁盘。但是当它这样做时,它会对块进行排序并按顺序写入它们。然后它会在日志中写一个检查点。

在数据库崩溃且无法检查点的恢复期间,数据库将日志读取到最后一个检查点,“向前滚动”并将这些更改应用于实际磁盘页,标记最终检查点,然后使系统可用于服务。

日志写入是顺序的,数据写入主要是顺序的。

现在,如果日志是普通文件的一部分(通常是今天),那么您可以编写日志记录,该记录会附加到磁盘文件中。然后,文件系统(可能)将您刚刚进行的更改附加到ITS日志,以便它可以更新其本地文件系统结构。之后,文件系统也将提交其脏页并使其元数据更改成为永久性的。

因此,您可以看到即使是简单的追加也可以调用对磁盘的多次写入。

现在考虑像CouchDB这样的“仅附加”设计。 Couch会做什么,就是当你做一个简单的写,它没有日志。该文件是它自己的日志。 Couch DB文件无止境地增长,并且在维护期间需要压缩。但是当它执行写操作时,它不仅会写入数据页,还会影响任何索引。当索引受到影响时,Couch会将索引更改的整个BRANCH从root重写为leaf。因此,在这种情况下,简单的写入可能比您最初想象的要贵。

现在,当然,你抛出所有的随机读取来破坏你的随机写入,这一切都变得非常复杂。我所学到的是,虽然流式带宽是IO操作的一个重要方面,但每秒的整体操作更为重要。您可以拥有2个具有相同带宽的磁盘,但是具有较慢盘片和/或磁头速度的磁盘将具有较少的操作/秒,仅从磁头行程时间和拼盘搜索时间开始。

理想情况下,您的数据库使用专用原始存储与文件系统进行存储,但大多数人今天都不这样做。基于文件系统的存储在操作上的优势通常超过了性能优势。

如果你在文件系统上,那么预分配的顺序文件是一个好处,因此你的“仅附加”不仅仅是跳过文件系统上的其他文件,因此变得类似于随机更新。此外,通过使用预分配文件,您的更新只是在写入期间更新DB数据结构,而不是在文件扩展时更新DB AND文件系统数据结构。

将日志,索引和数据放在不同的磁盘上允许多个驱动器同时工作,干扰更少。与使用随机数据读取或索引更新进行比较相比,您的日志只能真正附加。

因此,所有这些因素都会影响数据库的吞吐量。