此次分享主要为以下四大块内容。
开始第一块内容:SSD基本工作原理。
了解SSD工作原理之前,先迅速的回顾一下传统机械硬盘。它的主要构成:盘片,磁头,磁道,柱面,扇区。
硬盘的存储容量公式=磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数
延迟(latency)=平均寻道时间Tseek+旋转延迟Trotation
一般寻道时间各种硬盘几乎相同,平均8ms,区别在于转速不同,所以:延迟(latency)=8ms+60/磁盘转速/2,也就是说一般机械硬盘的平均延迟在10ms左右。
固态硬盘(SSD :Solid State Disk)是在传统硬盘上衍生出来的概念,简单的说就是用固态电子存储芯片阵列(NAND FLASH)而制成的硬盘。
看一下传统机械硬盘和固态硬盘参数对比,实际中各种硬盘的性能参数会有所不同,上图只是取了相对平均的值。
从以上对比可以看出,ssd在顺序读和写方面优势相对并不是很明显,和HDD属于同一数量级,突出的优势在于随机小块的读取及写入。
那么固态硬盘是如何工作的,和机械硬盘有哪些不同,看下面一张图。
如上图,SSD主要由SSD控制器,FLASH存储阵列,板上DRAM(可选),以及跟HOST接口(诸如SATA,SAS, PCIe等)组成。HOST发送请求到SSD主控,通过多个通道,根据一定算法对底层的NAND FLASH进行写入读取等操作。
上面说的NAND FLASH 是什么?简单说NAND FLASH 是一种固态电子存储阵列,它的基本存储单元为CELL,它是一个晶体管结构如上图所示。看一下他的结构。
向通过左边名为 POLY1 FLOATING GATE 的区域注入和提取电子来保存数据,没有注入电子的部分为1,已经被注入电子的部分为0。注入的电子通过Tunnel Oxide的绝缘膜来保持电子的通电状态。一个cell可以存放1个bit的数据(SLC),当成千上万的晶体管组成在一起的时候,就可以存放具有规模性的数据了。
注意绝缘膜在不断的冲放电过程中会逐渐的老化,所以固态硬盘具有一定期限的寿命,且它的寿命和写入擦除的次数直接相关,理论上只读操作并不会对SSD的寿命产生影响。
NAND Flash 有三个种类:SLC,MLC,TLC
一个cell里面存放1bit 为SLC (Single Level Cell),一个cell里面存放两个2bit为MLC(Multi Level Cell), 一个cell里面存放3bit为TLC(Trinary Level Cell)。
三种类型的NAND Flash对比如下:
再来看一下,另一重要的部件主控。
主控是影响SSD性能的重要因素,好的主控拥有稳定且快速的固件和先进的算法。一款优秀的主控即便搭配上相对廉价的MLC 闪存其性能也要比较低的主控搭配上SLC闪存要好。市面上相对比较优秀的主控品牌如:Intel,SandForce,Marvell
第二块内容:SSD写入放大与相关技术解析
什么是写入放大Write amplification,看一下它的计算公式:
闪存的特性决定它不能像机械硬盘一样,直接覆盖写入到已有的数据上,当闪存在写入过程中碰到存储单元已被写入过的情况,必须先对闪存存储单元进行擦除才能改写。
在执行这些操作的时候,移动(或重写)用户数据和元数据不止一次。这些多次的操作,减少了SSD的写入寿命.也增加了无谓的写入量。
更高的写入放大意味着SSD更短的寿命和更低的性能。因此写入放大是衡量主控性能的重要指标.所有的算法优化技术都是为了降代写入放大。
闪存运作特性中,数据以页面(由多个单元组成)为单位写入到闪存中。然而,存储器只能以较大的单位区块(由多个页面组成)擦除。
当整个块写满之后,如果需要擦除之前的无效数据,需要把有效数据移动到一个新的空块,再把原来的块进行擦除后才能写入,这个过程叫做垃圾回收(GC)。良好的垃圾回收机制,可以控制写入放大的系数。
垃圾回收可以分为两类:后台GC和主动GC。
后台GC。后台垃圾收集算法(也称为闲置垃圾收集),该控制器会使用空闲的时间来做垃圾收集,让主控在使用时一直保持高性能。例如barefoot主控. 在空闲的时候进行GC.以提高SSD性能。
主动GC。主动GC需要有相当性能的主控制器,以保证在操作数据的同时进行GC操作,这类GC适合在服务器里用到,因为个人用户可以把电脑闲置了做GC,但是服务器可不行,所以要保证性能的话必须在运行的同时做GC,这对主控制器的性能提出了很高的要求,SandForce与Marvell BJP2的主控就是这类。
再看一下ssd的磨损平衡技术:
均衡磨损Wear Leveling简单来说,就是用映射的方法,把将要写入的地址映射到写入次数最少的区块上面去,这样就达到了尽量让FLASH芯片上各处的单元擦写次数保持尽量相似。大大延长了FLASH的使用寿命。
接着来看预留空间。
预留空间是指用户不可操作的容量,为实际物理闪存容量减去用户可用容量。在SSD的垃圾收集、耗损均衡及坏块映射操作中,额外的预留空间有助于降低控制器写入闪存时的写入放大。
预留空间可以分为3份:第一层为固定的7.37%,这个数字是如何得出的哪?
SSD的厂商容量是这样算的,1GB是1,000,000,000字节(10的9次方),但是闪存的实际容量是每GB=1,073,741,824,(2的30次方) ,2者相差7.37%。所以说假设1块128GB的SSD,用户得到的容量是128,000,000,000字节,多出来的那个7.37%就被主控固件用做OP了。
第二层来自制造商的设置,通常为0%,7%和28%等。
打个比方,对于128G颗粒的SandForce主控SSD,市场上会有120G和100G两种型号卖,这个取决于厂商的固件设置,这个容量不包括之前的第一层7.37%。
第三层是用户在日常使用中可以分配的预留空间,而用户也可以自己在分区的时候,不分到完全的SSD容量来达到同样的目的。
TRIM技术是什么?
当用户在操作系统上删除一个文件,通常只会将该文件标记为已删除,而并未真正擦除磁盘上的实际内容。正因如此SSD不知道可以擦除先前的那些LBA(只有在操作系统再次写入到相同的Logical Block Address时才知道这些无效),所以在垃圾回收时仍然会保留它们。
TRIM是一个SATA命令,使得操作系统告诉SSD那些文件对应的LBA(Logical Block Address)地址已经被删除了,哪些不需要了。SSD知道后就以标记这些LBA过时或者无效,在垃圾回收的过程中就不需要再保留那些块。那么在垃圾回收过程中需要移动的LBA因此而减少。结果是SSD将有更多的空闲空间,同时获得低写入放大及更高的性能。
支持TRIM命令的操作系统如:Windows 7、Mac OS及Linux>= 2.6.33。
总结一下关于写入放大的内容:写入放大是衡量SSD的关键指标,闪存的写入比读取要慢的多,所以现在闪存的多通道设计就是用来提高写入的性能。
同样的颗粒同样的通道数,为什么闪存的性能差距会有那么大,原因就是一个写的多,一个写的少。一切算法的根本目标就是要尽可能的减少写入放大。
第三块内容:4K对齐
传统硬盘的扇区大小都为512b,但是随着大众对存储空间的需求越来越高,这么小的扇区大小已经不能满足人们的需求,于是就出来了4kb扇区的硬盘。
如图,原生512n每个扇区都有50bytes的ECC纠错码;4KB扇区将这个ECC区域合并、扩大(100bytes),并省去了间隔、地址标记等空间,提高了格式化和写入的效率。
固态硬盘,无论是SLC颗粒还是MLC颗粒,都属于NAND闪存存储单元,硬盘扇区都为4k。
在高级格式化(AF)下,物理扇区的大小为4k,IO都是直接对4k扇区进行操作,这种模式为本地化模式(native node)。但是要使用这种模式应用和操作系统必须进行修改来适应这种新的模式,于是为了保持向后的兼容性就出来了仿真模式512e(Emulation Mode)。
在512e的模式下,存储系统会自动把512的逻辑扇区,自动转换为4096的物理扇区如下图所示,并且赋予一个逻辑扇区地址。如图:
这种情况最为常见但是需要重点注意局部IO(Partial IO)和对齐(Aligment)问题。
局部IO(Partial IO)是什么?在512e模式下,单一个进程读取一个512b的块实际需要读取4k的量,这个叫做局部读(partial read)。
还有重要的问题就是在写入的时候:当一个进程写一个512b的块时,存储系统需要把一整个4k数据读入到内存,然后修改单个512的逻辑块,最后再把一整个4k扇区写入到存储系统。这个叫做局部写(partial write )。
对齐 (Alignment),如下图
512e其实是一种逻辑扇区和物理扇区的一种对应算法,4KB块(比如对应文件系统的页面)操作需要先以8个512bytes逻辑扇区写入到硬盘,再合并记录到4KB物理扇区,在非对齐的情况下,一个4KB逻辑写I/O对应到2个物理磁盘扇区,如果是新写入就会产生2次I/O,并且引起局部IO问题。
怎么避免不对齐?1.尽量不对ssd进行分区;2.如果分区保证分区从4k扇区的边缘开始;3.在分区对齐的情况下,如果所有的数据文件块都是4k的整数倍,就能避免局部IO的问题。
第四部分:SSD企业应用实践
缺乏优化的业务系统总是趋向于IO瓶颈的,解决了IO问题就解决了业务系统性能问题全部或者绝大部分。
那么如何在生产环境中应用SSD技术呢?SSD在ORACLE数据库上应用通常有两种方式。1.SSD直接存储数据文件;2.SSD当做数据库二级缓存。
SSD直接存储数据文件,当前系统又在512e模式下对SSD的分区需要注意:1.不要使用分区给asm;2.如果必须使用分区,必须保证分区从4k物理扇区的边缘开始。
在保证分区对齐的情况下避免非对齐的情况,datafile的块大小是8kb,控制文件是16kb,所以也没有partial io问题,唯有online redo log默认块大小为512bytes,会存在parital的问题。
Redo是否适合放在ssd的问题,一直存在争议。
LGWR进程是通过持续的连续写入把log buffer中的内容刷到redo log上,由于在ssd写入方面存在放大系数,在写入的过程中可能存在高分期,会增加'log file sync的值。所以mos上有文章说不建议redo log放在ssd上,但是同时在exdata上,redolog确实是放在ssd上,oracle据称自己是做了优化。
本人认为我们自己完全也可以做到这类的优化,控制写入放大系数。1采用比较高端的SLC或者MLC闪存颗粒的固态硬盘;2采用较大的预留空间;3拥有高效垃圾回收机制的主控。也就是说采用企业级的中高端PCIE FLASH CACHE卡,基本不会出现orale说的write peaks。
另外告诉大家一个不用ssd也能明显提升redo log 写的方法:在现实的数据库设计物理存放中,Online Redo Log几乎总是和其他数据文件共享存放磁盘组,从而使顺序写的Online redo Log在实际操作中需要不断的移动磁头以进行随机访问,也就是从顺序写变成了随机写。所以只要把redo log放在单独的一个磁盘组上,能显著的提高性能。
在把redo放在ssd上后,由于通常redo的blocksize 为512b,所以在512e的模式下,存在partial IO的问题。在11gr2的版本以后,可以设置redolog的block size为4096来避免partial IO问题。设置4k redo的步骤如下:
对redo分别放在sas机械盘,ssd+blocksize 512 ,ssd+blocksize 4k进行了压力测试。实验采用hammerdb压力测试工具,把系统cpu压到100%后对比TPM值和对应的AWR报告,实验结果如下:
实验结果说明把redo log放到ssd后可以有效降低log file sync的值,数据库吞吐量提高34%左右且性能保持稳定。采用ssd+4k blocksize的redo log吞吐量提高60%左右,性能也十分稳定。
考虑目前闪存依然比较磁盘昂贵,生产系统数据量通常较大的现实,混合存储或者把闪存作为Buffer的二级缓存可能是目前最为现实的解决方案。
Database smart flash cache 是11gr2之后的新功能,可用通过SSD作为SGA的二级缓存来提高缓存的效率。
从SGA中驱逐出来的干净的块会首先进入smart flash cache中,如果驱逐出来的块是被修改过的,这个脏块会先被dbwr写到磁盘,再写入到smart flash cache。
也就是说ssd中缓存的是干净的块,ssd崩溃不会对数据库造成影响。写入smart flash cache中的块,在被请求时可以直接从flash cache中读取,如果命中次数较多也可能重新回到SGA中。
那么什么情况下建议开启Database smart flash cache?1.操作系统为?Solaris或者Linux (最好是rhel 核心的);2.AWR的Buffer Pool Advisory?中显示2倍buffer pool值会有效减少物理读;3.db file sequential read 等待事间突出;4.cpu有一定的空闲率。
开启Database smart flash cache功能主要有2个参数。
DB_FLASH_CACHE_FILE --指定闪存设备,可以指向裸设备或者ASM磁盘组。如db_flash_cache_file = "/export/home/oracle/lffile_raw”db_flash_cache_file = "+dg1/lffile_asm"
DB_FLASH_CACHE_SIZE --指定使用闪存设备的大小,最好为SGA的2-10倍之间。如db_flash_cache_size = 50G
注意:SGA中缓存有Flash cache中buffer的头信息,在单机情况下每个flash cache中的buffer占用100b的头信息在sga中,rac情况下这个值为200b。因此在配置smart flash cache的情况下,实际sga可以使用的值会减少,因此应该适当计算增加SGA的值。
在rac情况下,flash cache 设备不能够被两个实例共享,因此每个实例需要指定自己私有的flash cache,需要为asm每个实例需要指定一个单独的磁盘组。
Oracle 对自家的smart flash cache 进行过测试。环境为一个在Sun SPARC Enterprise M5000机器上和sun F5100 闪存。数据库大小72G,SGA大小8G,业务模拟为OLTP类型,测试中模拟两倍的用户量的操作,数据库处于IO资源紧张的情况。随着DB_FLASH_CACHE_SIZE值不断的增大,各个指标结果如下:
当flash cahe size 值达到50g左右的时候物理IO基本为0,数据库吞吐量达到顶峰。使用flash cache 之后事物数为达到了原来的5倍的左右。随着flash cache size的增大,flash write (把SGA中的数据输入到flash cache中)也不断的减少,因为数据已经基本全部缓存进去。