本文翻译自Guy Harrison的blog: Flash tablespace vs. DB Flash Cache, 这是他写的关于Flash Cache系列文章的最后一篇,另外还会翻译两篇Kevin Closson写的关于Flash Cache的相关文章.
之前两篇关于Flash Cache的文章如下:
闪存表空间 VS 数据库Flash Cache
在这篇文章中,我将根据我最近针对使用SSD作为数据文件的存储以及使用Oracle 11GR2数据库Flash Cache所做的测试,给出一份两者的性能对比.
有时,我的整个职业生涯看上去都是在等待旋转磁盘的终结.这项技术是如此古老,能力限制如此明确,如此机械.因此,SSD作为一种数据库存储介质越来越可行(Oracle 11GR2已经直接支持这一点),这个事实令人振奋.
使用SSD作为数据库存储的一部分确实会产生很大的问题,但是,理解闪存SSD的性能特征却是非常重要的,它可以帮助我们确保不会不当地使用它.
SSD有以下两个特征:
- 基于闪存的SSD使用与常见的USB盘相似的闪存技术,这种USB盘已经在小容量移动数据存储领域替代软盘.闪存RAM比较便宜,提供不需要电池备份的持久存储,因此其耗电量也很低.
- 基于DDR RAM的SSD使用本质上与服务器核心内存差别不大的内存模块.这种RAM需要有持久存储(如磁盘或闪存RAM)和内部电池来支撑.在发生电力故障的时候,电池可以提供足够的电力来保证可以将RAM内存中的内容写到持久存储.
DDR SSD非常昂贵(以及$$/GB这个级别),以致于目前无法作为专业的数据库设备使用.但是,基于闪存的SSD磁盘越来越称为机械磁盘的一个可行的替代选项.
读,写以及擦写操作
闪存盘存储是按照页(一般为4K)以及块(一般为256K)来组织的.对于读操作来讲,闪存盘可以从单个页(page)快速返回结果.往一个页中写数据要慢很多(可能要慢10倍).然而,只有在块中刚好有一个空闲的页的往页写才能达到这个速度.如果我们需要往整个块写数据,必须先清除块内的内容才可以.维基百科关于SSD的条目给出了下面这个关于查找/写以及擦写的时间:

当一个闪存SSD盘渐渐填满数据时,需要清除操作的块级别的写操作的比例逐渐增加,闪存SSD的写性能也相应下降.
TRIM API函数
高端的闪存SSD支持一种叫做TRIM的API,这个功能使得OS可以主动提前清除整个块,从而写操作可以在只有一个页级别的IO内完成.大部分高端的SSD盘还支持一种防磨损算法,这种算法可以在设备上移动热点页以避免块级别出现故障的风险.闪存盘在块变得不可靠之前只支持一定次数的擦写操作,加入磁盘可以自动将热点页在物理存储上移动时,这个缺陷就可以得到缓解.
MLC vs SLC
廉价的闪存盘一般都使用MLC(Multi-Level-Cell)技术,它可以实现在一个单元中存储两位的数据,而使用SLC时一个单元中只能保存一位数据.MLC的效果是以牺牲性能的代价来提高数据密度,特别是写性能.从数据丢失的角度讲,MLC也是更加不可靠的.如果你关心写性能,那么或许你应该避免使用基于MLC的SSD.
通常,如果你想要一个高性能的闪存SSD的话(如果它不是高性能的,干嘛还要它呢?),你就应该选择基于SLC的闪存SSD,并且是支持TRIM API以及有着好的防磨损能力的SSD.在我的测试中,我使用一个Intel X-25 E 32GB的SSD盘.它大概需要600澳元(大概534美元).
读写速度差异的问题
假设大部分数据库都是读比写多,我们还需要担心闪存SSD在查找时间与写时间方面的差异吗?毫无疑问答案是YES.对于一个Oracle数据库来讲,当通过Buffer Cache处理事务活动时,一个设备的读能力与往这个设备的写能力之间有很大的不匹配会非常有害.
这个问题与Buffer Cache中的数据的缓存有关.如果往Buffer Cache中放入数据块比从里面写出简单很多,那么Buffer Cache就很可能会被脏块填满,从而出现free buffer waits等待.下图展示了free buffer waits是如何出现的:

如果使用的是廉价的闪存盘,那么写速度就会比读速度慢更多,最终free buffer waits等待将成为事务活动高峰时期的限制因素.
Oracle数据库Flash Cache
Oracle的数据库Flash Cache提供了另外一种利用闪存SSD的途径. 它不是将整个数据文件放到闪存上,而是将闪存作为二级缓存使用.Flash Cache可以非常大从而加快经常被访问的数据块的读速度.但是,如果闪存盘非常繁忙的话,Oracle就只是尽量少写缓存.这样,我们就可以得到闪存来优化读操作的好处,而不用承担多少写操作带来的损失.
我在前一篇文章中总结了Flash Cache的处理算法,下面是我在那篇文章中使用的图表,它概括了当数据库使用Flash Cache时一个数据块的生命周期.
这个架构的关键点是,只有在DBWR没有超负荷时,它才会往Flash Cache中写入数据块.当DBWR逐渐变得繁忙时,往Flash Cache中的写操作将被忽略(这将会降低Flash Cache的效率),它可以防止Buffer Cache被脏块填满,从而导致free buffer waits等待事件的出现.
闪存盘的读性能
让我们来看在实际操作中它是如何表现的.下面来看当我们针对如下情况执行500,000次随机索引读取时的性能对比:
- 1. 一个在机械磁盘上的表,不使用Flash Cache
- 2. 一个在机械磁盘上的表,使用Flash Cache
- 3. 一个直接存储在闪存盘上的表
这个机械磁盘是一块希捷7200.7 80GB Barracuda磁盘,同时这个SSD盘是一块Intel X-25 E 32GB盘(一块非常高端的SLC盘).在这两种情况下,表空间都是创建在裸设备上从而避免文件系统缓存的影响,并且重做日志(Redo Log)以及其他表空间都放置在一个独立的磁盘上.
下面是相关的读性能:

如你所料,将表直接放置在闪存上是最快的,因为这里只有读IO,并且每个读IO都是针对这个非常快的闪存SSD.注意,Flash Cache也同样带来了很大的好处,数据库文件的IO数量下降了,当然从Flash Cache读取的速度是非常快的.
更新性能
下面,我将测量基于主键的更新操作的性能.这样一个更新操作的性能是由读性能(读取这个数据块到缓存中)与DBWR性能共同决定的.如果DBWR写出脏块的速度不是足够快的话,就会出现free buffer waits与write complete waits等待事件了.
我最初预计,对闪存表空间的测试肯定会遇到大量的free buffer waits,因为理论上讲闪存的写操作要比闪存的读操作慢很多很多. 我认为使用Flash Cache将会避免这个问题,并且能够提供更好的性能. 然而,结果非常出人意外.

我使用不同的负荷重复进行上面的测试,但是每一次结果都非常相似.然而,使用Flash Cache还是要比不使用Flash Cache来得好,将表直接存储到闪存储存上性能就更好了.X-25 E SSD盘支持一个远远超出我预期的写频率(大概2000次写操作/秒).Intel 宣称(现在我相信了)他们拥有精密的算法可以有效避免通常与闪存SSD存储介质有关的写损失.
注意,实际上大部分的free buffer waits等待事件的产生都是由Flash Cache的配置导致的.Flash Cache使得Oracle的逻辑读的速度更快,但是由于物理写仍然会面对相对更慢的机械旋转磁盘,Buffer Cache常常会被脏块所填满.
或许随着时间的流逝,当所有的块都被至少写过一次,清除操作变得更加普遍时,X-25的性能会出现下降.然而,如果TRIM API能够正常工作,那么理论上这种性能恶化应该可以避免.注意,并不是所有环境都支持TRIM API,并不是所有的SSD都支持,旧版本的Windows操作可能也不支持.
Write complete waits: flash cache
在上一篇文章中,我注意到,当DBWR繁忙的时候会跳过而不写Flash Cache,这一点应该可以避免Flash Cache的活动不会成为导致free buffer waits的直接原因.然而,我观察到,在特定的负荷下会遇到大量的”write complete waits: flash cache“等待事件.例如,下面的输出结果显示大约有75%的实耗时间(elapsed time)消耗在这个等待事件上.

当一个会话想要修改一个数据,但同时DBWR又正在将这个数据块写到数据文件的时候会出现write complete waits等待事件.Flash Cache相对应的等待事件的出现也是由于类似的原因,但这是不是写数据块到数据文件,而将由DBWR将它写到Flash Cache.当一个特定的数据块被非常频繁的修改的时候,这种现象就会出现;在这种情况下,数据块在被DBWR写完之前被修改的机会相当高.
结论
X-25 E闪存SSD盘给我留下了非常深刻的印象.如果它可以长时间的保持优异的写吞吐量的话,相比于传统的机械旋转磁盘以及11GR2的数据库Flash Cache,它提供的吞吐量有惊人的优势.不过,还有几句忠告:
- 我没有长时间对这个SSD盘做压力测试.有些闪存盘在磨损后显示出更长写延迟.理论上,Intel X-25 E的TRIM功能应该可以避免这一点,但我并没有在这些测试中验证这一点.
- 在经过长时间的使用后,闪存盘可能会成为一种不可靠的存储介质.当然,任何磁盘都会损坏,但是闪存盘比机械磁盘更加容易损坏(虽然在损坏之前它可能可以做更多的工作).
- 在我的测试中,我的表很小,足以完全存放在闪存存储上.如果做不到这一点,使用数据库Flash Cache让我们在无法将整个数据库都放到SSD上的时候,也可以利用闪存盘.
现在,我更加热衷于使用闪存盘了.只要你购买一个高性能的SSD盘(考虑SLC & TRIM),你就可以考虑将整个表空间或者数据库都存放在这些盘上.如果担负不起所有的数据都存放在高端的闪存盘上,还可以考虑使用11GR2的数据库Flash Cache来获得显著的性能提升.
Related posts:


太棒了!这是解惑的一篇,并且非常有价值!
感谢您的译文,非常有用!
不客气, 欢迎经常来光顾..
[...] 闪存表空间 VS 数据库Flash Cache [...]