深入浅出Flashcache(一)

Cache is king.

在计算机系统中,cache的魔爪无处不在。CPU中有L1,L2,甚至L3 cache;Linux有pagecache,MySQL有buffer cache/query cache;IO系统中Raid卡/磁盘也有cache;在大型互联网系统中,数据库前面一般也都有一层memcache。Cache是容量与性能之前取平衡的结果,以更低的成本,获得更高的收益,是系统设计时应该遵循的原则。

传统机械硬盘几十年来,容量不断翻倍的增长,相比较而言,性能的增长就慢的像蜗牛了。对于依赖IO性能的应用,典型的如数据库,一直在等待新的技术来拯救。在此之前,身躯庞大的高端存储,动辄重达几吨。相比于存储里带的硬盘来说,价格贵得离谱,而存储的附加价值,在于io在大量硬盘之间的均衡分布,以及IO链路的多路容灾,以及部分固件层面的优化和数据保护等。

Flash disk(SSD/FusionIO等)的出现,改变了这一切。Flash disk将硬盘从机械产品变成了电气产品,功耗更小,性能更好,时延更优,看起来传统硬盘已经不堪一击,数据库欢欣鼓舞,新的革命似乎将一夕成功。但新东西也有它致命的缺陷,价格和经过时间检验的稳定性。

所以Facebook的Mohan Srinivasan在2010年开源了Flashcache,将Flash disk做为普通硬盘的cache,这个思路,目前一些尝试也在raid卡硬件层面做尝试,例如LSI的CacheCade Pro,不过之前版本新浪的童鞋测试过似乎性能没有想象的好。Flashcache在淘宝一些核心数据库中已经在线运行了大半年,经过调优后的表现稳定。Flashcache利用了Linux的device mapping机制,将Flash disk和普通硬盘的块设备做了一层映射,在OS中变现为一块普通的磁盘,使用简单,是一个值得推荐的方案。Flashcache最初的实现是write backup机制cache,后来又加入了write through和write around机制:

  • write backup: 先写入到cahce,然后cache中的脏块会由后台定期刷到持久存储。
  • write through: 同步写入到cache和持久存储。
  • write around: 只写入到持久存储。

在详细的介绍Flashcache之前,需要先了解一下Linux的block device和device mapper相关的知识。

1. Block Device
块设备最初主要是依据传统硬盘等IO操作较慢的设备而设计的,所以Linux中为块设备的IO操作提供了cache层,所以基于块设备的请求一般是buffer io,当然后来由于数据库等自己有cache机制的应用,os/fs层面的cache就成了多余,所以出现了绕过os/fs层cache的direct io。

块设备在设备确定层和kernel之间,为Kernel提供了统一的IO操作接口,同时隐藏了不同硬件设备的细节。当有多个并发IO请求到块设备时,请求的顺序会影响IO的性能,因为普通的机械硬盘需要移动机械臂,所以kernel一般会对IO做排序等调度后再发送到块设备层。IO调度算法是一种电梯算法(elevator algorithm),目前主要有cfq/deadline/anticipatory/noop,其中cfq是Linux的默认策略;anticipatory在新的内核中已经放弃;deadline在大部分OLTP数据库应用中更具优势,IO的响应时间更稳定些;noop只对IO请求进行简单的合并,其他不干涉,在FusionIO等IO性能很好的设备上,noop反而更具优势,所以FusionIO的驱动默认使用了noop。关于IO Scheduler,后文会有更详细的解释。

块设备在用户空间是一种特殊的文件类型,由(major,minor)来标识,major区分disk,minor区分partition。Linux中一般把设备文件放在/dev目录。实际上你完全可以将块设备文件创建到其他地方,只要(major,minor)唯一确定,块设备文件最后访问的起始同一个块设备。

$ls -l /dev/sda1
brw-rw—- 1 root disk 8, 1 2011-12-03 01:00 /dev/sda1

$sudo mknod /opt/sda1 b 8 1

$ls -l /opt/sda1
brw-r–r– 1 root root 8, 1 2011-12-03 11:54 /opt/sda1

由于块设备处于文件系统和物理设备驱动之间,在这一层做一些工作可以对所有IO产生影响,因此很多优秀的产品都在这一层做文章,除了Flashcache,还有一个比较著名的就是DRBD(DRBD已经进入2.6.33内核)。
Read more of this post

使用smartmontools监控磁盘状况

现代的磁盘基本上都支持S.M.A.R.T.技术,关于S.M.A.R.T., 维基百科的条文如下:

S.M.A.R.T. (Self-Monitoring, Analysis, and Reporting Technology; sometimes written as SMART) is a monitoring system for computer hard disk drives to detect and report on various indicators of reliability, in the hope of anticipating failures.

When a failure is anticipated by S.M.A.R.T., the drive should be replaced, and can sometimes be returned to the manufacturer, who can use these failed drives to discover where faults lie and how to prevent them from recurring on the next generation of hard disk drives.

Smartmontool是sourceforge上的一个开源项目,可以对磁盘的S.M.A.R.T.进行提取和定期监控。Smartmontool包含两个工具: smartctl和smartd。

$sudo apt-get install smartmontools

Smartctl用于提取和修改硬盘的某些属性和统计信息。Smartd则可以作为守护进程运行,定期收集信息,监控硬盘状态。在我的Thinkpad X200上运行smartctl的结果如下:


ningoo@ning:/sys/block/sda/queue$ sudo smartctl --all /dev/sda
smartctl 5.40 2010-03-16 r3077 [i686-pc-linux-gnu] (local build)
Copyright (C) 2002-10 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Device Model:     FUJITSU MJA2320BH G2
Serial Number:    K95DTA52FWAA
Firmware Version: 0084001C
User Capacity:    320,072,933,376 bytes
Device is:        Not in smartctl database [for details use: -P showall]
ATA Version is:   8
ATA Standard is:  ATA-8-ACS revision 3f
Local Time is:    Tue Mar 22 19:14:04 2011 CST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status:  (0x00)	Offline data collection activity
					was never started.
					Auto Offline Data Collection: Disabled.
Self-test execution status:      (   0)	The previous self-test routine completed
					without error or no self-test has ever 
					been run.
Total time to complete Offline 
data collection: 		 (1009) seconds.
Offline data collection
capabilities: 			 (0x7b) SMART execute Offline immediate.
					Auto Offline data collection on/off support.
					Suspend Offline collection upon new
					command.
					Offline surface scan supported.
					Self-test supported.
					Conveyance Self-test supported.
					Selective Self-test supported.
SMART capabilities:            (0x0003)	Saves SMART data before entering
					power-saving mode.
					Supports SMART auto save timer.
Error logging capability:        (0x01)	Error logging supported.
					General Purpose Logging supported.
Short self-test routine 
recommended polling time: 	 (   2) minutes.
Extended self-test routine
recommended polling time: 	 ( 143) minutes.
Conveyance self-test routine
recommended polling time: 	 (   2) minutes.
SCT capabilities: 	       (0x003d)	SCT Status supported.
					SCT Error Recovery Control supported.
					SCT Feature Control supported.
					SCT Data Table supported.
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   200   253   000    Old_age   Always       -       2
200 Multi_Zone_Error_Rate   0x000f   100   100   060    Pre-fail  Always       -       4364
203 Run_Out_Cancel          0x0002   100   100   000    Old_age   Always       -       1533219504675
240 Head_Flying_Hours       0x003e   200   200   000    Old_age   Always       -       0

SMART Error Log Version: 1
ATA Error Count: 1
	CR = Command Register [HEX]
	FR = Features Register [HEX]
	SC = Sector Count Register [HEX]
	SN = Sector Number Register [HEX]
	CL = Cylinder Low Register [HEX]
	CH = Cylinder High Register [HEX]
	DH = Device/Head Register [HEX]
	DC = Device Command Register [HEX]
	ER = Error register [HEX]
	ST = Status register [HEX]
Powered_Up_Time is measured from power on, and printed as
DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,
SS=sec, and sss=millisec. It "wraps" after 49.710 days.

Error 1 occurred at disk power-on lifetime: 1222 hours (50 days + 22 hours)
  When the command that caused the error occurred, the device was active or idle.

  After command completion occurred, registers were:
  ER ST SC SN CL CH DH
  -- -- -- -- -- -- --
  84 51 03 97 95 a6 00  Error: ABRT

  Commands leading to the command that caused the error were:
  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
  -- -- -- -- -- -- -- --  ----------------  --------------------
  00 08 01 01 00 00 00 ff      02:19:49.864  NOP [Reserved subcommand]
  60 08 00 90 95 a6 40 08      02:19:49.862  READ FPDMA QUEUED
  60 10 00 c8 3c a6 40 08      02:19:49.850  READ FPDMA QUEUED
  60 20 00 a8 3c a6 40 08      02:19:49.841  READ FPDMA QUEUED
  60 08 00 88 95 a6 40 08      02:19:49.833  READ FPDMA QUEUED

SMART Self-test log structure revision number 1
No self-tests have been logged.  [To run self-tests, use: smartctl -t]


SMART Selective self-test log data structure revision number 1
 SPAN  MIN_LBA  MAX_LBA  CURRENT_TEST_STATUS
    1        0        0  Not_testing
    2        0        0  Not_testing
    3        0        0  Not_testing
    4        0        0  Not_testing
    5        0        0  Not_testing
Selective self-test flags (0x0):
  After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.

对于使用了RAID卡的硬盘,还需要RAID卡的支持才能读取到磁盘的S.M.A.R.T.信息,同时intel的SSD也将自身的一些健康指标如磨损率等写入了S.M.A.R.T.信息,于是我们就能通过smartctl来获取安装了RAID卡的SSD的寿命等关键指标了。有了这些指标,可以提前预知到SSD的健康状况,对于SSD单点有写入极限这个担忧,就可以稍微降低那么一点,在生产环境中使用也就更有谱了。具体的用法,之前褚霸B2B的DBA都有写过blog介绍,这里就不展开了,通过MegeCli可以获取LSI的Raid卡的信息(其他Raid卡也有类似的工具):

sudo  /opt/MegaRAID/MegaCli/MegaCli64 -LdPdInfo -aALL

值得一提的是,SSD的磨损率一般通过E9(233)来获取,也就是Media_Wearout_Indicator指标,是0~100的值,精度还是比较粗的,B2B这边线上用了很久,写入了40TB的测试数据,这个值也还是比较高(99,只少了一滴血,这个boss很难打啊^_^)。如果需要更细粒度的数据,上次Intel的人过来交流的时候,说可以取E2(226 Timed Workload Indicator),E3(227 Timed Workload Read Ratio),E4((228 Timed Workload Timer)的值来做更高精度的计算,在开始压力测试前,先将对应的E2/E3/E4的值清零

smartctl -t vendor, 0x40 -a /dev/hdx

当然,如果你使用了Riad卡,还是需要配合Raid卡的相应工具才行

smartctl -t vendor,0x40 -d megaraid,30 /dev/sdx

然后执行一次测试(至少60分钟),重启系统,再次执行smartctl得到E2 = 22, 则该次测试的磨损率为 22 / 1024 / 100= 0.021%(E9的一点血是E2的100点血,也就是说E2的精度比E9高100倍,所以可以在较短时间的测试中看到其变化)。E3 =99 说明读写比例为 99%。该次测试的时间则为E4 = 981分钟,通过计算可以得到该SSD在这样的工作压力下的寿命为E4*1024*100/E2/1440/365 = 8.68年(一年按365天计算)。当然,这个结果是假设这些E2/E3/E4/E9的值都是线性变化的前提下得出的,如果像某些手机的电池指示一样,第一格电可以用一天,最后一格电只能用一个小时,那么这些估算就都是浮云。欲知后事如何,只能等某块SSD用到寿命正常终止,再回头来分析这些指标是否靠谱了。

SSD硬盘的IO性能测试

发现有一段时间没有写东西了,忙碌是懒惰的接口,接下来还是需要经常写点什么的,好记性不如烂笔头。最近拿到了一台SSD硬盘的测试机,今天抽空用Orion做了几个测试,结果嘛,应该说随机读的IOPS的性能是非常满意的。测试环境为Linux+Orion,一共三块32G的SSD硬盘,直接用裸盘,不做raid,不做文件系统,避免cache的影响。不多废话,看结果:

三块盘的8k随机读最高接近14000,响应时间1ms左右,可以说随机读是SSD相对传统机械硬盘的最大优势所在,按照15k转速机械盘最高200左右(此时响应时间基本到了20ms)的IOPS计算,一块SSD至少相当于24块机械盘,当然,这仅仅是指的随机读的性能。而对于像淘宝这类web应用来说,随机读的IOPS往往是最关键的问题所在。

吞吐量大约每块盘在120MB/s左右,这个相对来说,提升的空间没有IOPS明显,但也算一个不错的值了。

8K随机写,每块盘大概在300左右,相对于读来说,写还是偏慢,当然相对机械盘还是有成倍的性能提升的。

顺序写的吞吐量和读基本一致,那么吞吐量的瓶颈有可能在IO通道上,而不一定是SSD盘本身的限制。

上面只是一个初步的测试结果,没有做长时间的稳定性测试。不过从上面的数据来看,SSD在随机读方面的优势还是非常大的。目前Intel 32G的SSD报价已经在4000左右了,相对来说,也不算太贵了。但是32G的单盘容量还是太小了点,而且10w次单点写的问题也还有待新技术的解决,不管目前还存在多少问题,SSD的未来应该是光明的,我很看好你哦。

SSD硬盘时代即将到来?

EMC最新的企业级高端存储DMX4据说将支持SSD(Solid State Drive)固态硬盘,而联想也在最近发布了一款新的ThinkPad X300计划,要和Apple的超薄Macbook Air一争高下,也将采用SSD作为硬盘。看来不管是企业存储还是个人电脑,SSD都开始抢占地盘了。

SSD的单个硬盘的IOPS据称可以超过5w,而目前一个15000转的机械硬盘只能到达150个IOPS左右。当然,5w只是厂家宣传值,在实际应用中肯定是达不到的。据EMC的人说,一个SSD在IO性能上可以相当于30多个机械盘。对于高并发的OLTP系统来说,SSD的诱惑力可不一般了。

SSD的寿命受制于擦写次数,据说是200w次,不知道这个数字是说同一个存储位置,还是说整个盘,如果是同一个位置200w次,那没什么问题,如果是同一块盘,对于写入比较密集的系统就有点危险了,毕竟现在SSD盘的价格那还是相当的贵啊。在读密集操作的应用中,SSD应当是比较适用的了,谁有在Oracle生产系统中实际使用的案例么?

ThinkPad X300

无觅相关文章插件,快速提升流量