Flashcache是Facebook技术团队的一个开源项目,最初目的是为加速MySQL的数据库引擎InnoDB,是一个开源的混合存储方案。html
Cache是容量与性能以前取平衡的结果, 以更低的成本,得到更高的收益 ,是系统设计时应该遵循的原则。算法
传统机械硬盘几十年来,容量不断翻倍的增加,相比较而言,性能的增加就慢的像蜗牛了。对于依赖IO性能的应用,典型的如数据库,一直在等待新的技术来拯救数据库
Flash disk(SSD/FusionIO等)的出现,改变了这一切。Flash disk将硬盘从机械产品变成了电气产品,功耗更小,性能更好,时延更优缓存
Flashcache利用了Linux的device mapping机制,将Flash disk和普通硬盘的块设备作了一层映射,在OS中变现为一块普通的磁盘,使用简单。安全
经过在文件系统和设备驱动之间新增了一层缓存层,用来实现对热点数据的缓存。
一般用SSD固态硬盘做为缓存,经过将传统硬盘上的热门数据缓存到SSD上,而后利用SSD优秀的读性能,来加速系统。架构
固态硬盘虽然说没有传统硬盘那样的机械结构,不存在磁头老化、磁盘坏道等问题,但因为采用了闪存做为存储介质,其有限的擦写次数是一大硬伤。以32nm工艺的闪存芯片为例,固态硬盘常见的闪存颗粒理论擦写寿命约为5000-10000次。固态硬盘相比机械硬盘仍是“脆弱”了些:传统硬盘的将数据记录在磁层上,理论上能够经受无数次的读写操做而不会有磁失效的危险,显然闪存作不到这种程度。app
若是说机械硬盘坏了还能够作数据恢复的话,固态硬盘就连这个“后悔药”都没得吃了,为何呢?由于固态硬盘的工做原理与机械硬盘不一样。传统硬盘的将数据记录在磁层上,理论上能够经受无数次的读写操做而不会有磁失效的危险,所以即使是硬盘已经损坏,仍能够经过专业工具读取磁层柱面信息来恢复。可是固态硬盘不一样,其内部没有任何机械结构,数据被零散地分散在各个闪存之中,要从损坏后的闪存芯片中数据恢复,从目前来说几乎是不可能的。由于二者存储原理不一样,固态硬盘删除文件时不是像机械硬盘那样仅仅删除文件的索引,而是所有删除。框架
Device Mapper 是Linux 2.6后内核中全面引入的块设备新架构,是一种从逻辑设备到物理设备的映射框架机制。Device mapper 进一步体现了在 Linux 内核设计中策略和机制分离的原则,将全部与策略相关的工做放到用户空间完成,内核中主要提供完成这些策略所须要的机制,即Device mapper 用户空间相关部分主要负责配置具体的策略和控制逻辑,好比逻辑设备和哪些物理设备创建映射,怎么创建这些映射关系等等,而具体过滤和重定向 IO 请求的工做由内核中相关代码完成。工具
Device mapper在内核中向外提供了一个从逻辑设备到物理设备的映射架构,只要用户在用户空间制定好映射策略,按照本身的须要编写处理具体IO请求的target driver插件,就能够很方便的实现一个相似LVM的逻辑卷管理器。 性能
经过Device Mapper框架,能够统1、灵活地管理系统中全部的真实或虚拟的块设备,也能够方便的根据须要自定义并实现本身的块设备存储资源管理策略。
当前许多比较流行的 Linux 逻辑卷管理器都是基于该机制实现的:
Mapped device 是一个逻辑抽象,能够理解成为内核向外提供的逻辑设备,它经过映射表描述的映射关系和 target device 创建映射。
中间的一层赋值创建映射,定义对BIO请求的处理规则,以及Target deviced构建和删除。
最下面的Target Devices层是mapped device虚拟逻辑设备所映射的真实设备物理地址空间。
它将SSD固态硬盘划分红预先定义大小的缓存块(将目标硬盘也划分为相同大小的硬盘块,默认大小是4KB)。同时,将每512个缓存块分为一组(set)。最后每一个硬盘块映射到SSD一个肯定组中的某个缓存块。
每一个cache set的还有个超级块(super Block),存放缓存相关的信息,如缓存大小,多少缓存块等
硬盘上的块地址是磁盘块号(Disk Block Number,dbn),对硬盘的I/O请求最后都转化为一个具体的磁盘块号。将一个具体的磁盘块号映射到某一个组是直接映射。
肯定了将这个磁盘块映射到一个具体组后,再将这个磁盘块号映射到该组的某一个缓存块。
这样两次映射后,硬盘上的一个块就跟固态硬盘上的一个惟一数据缓存块对应了。当上层请求下达时,根据磁盘块号来查找对应的固态硬盘上的缓存块是否已经缓存,若是是,则表示命中,可直接读写。若是没有缓存,则仍要读写硬盘,同时将该硬盘块缓存至固态硬盘上。
元数据自己使用管理缓存数据块的,包括
超级快(super Block):存放缓存相关的信息,如缓存大小,多少缓存块,数据缓存块的状态(上次是否正常关闭),缓存的目标设备(硬盘,阵列,逻辑卷)版本号等。
元数据块(metadata Block):若干个元数据块,用来管理若干的缓存数据块(Data Block)
缓存命中
当 I / O 操做开始从缓存而不是从非易失存储中检索数据时(如磁盘设备或子系统),缓存命中发生。除了提供来自内存的快速响应以外,缓存命中还缩短了 I / O 路径的距离。如图所示。
缓存未命中
另外一种状况是,虽然搜索了缓存,但没有发现数据,所以数据必须从非易失存储读取,这就是缓存未命中。由亍搜索缓存时须要花费时间,因此缓存未命中增长了 I / O 操做的时间。缓存未命中工做过程如图所示:
Step 1.获取flashcache最新的源码包flashcache-master.zip并解压,进入解压后目录进行 安装
#cd flashcache-master
#make
#make install
Step 2.执行命令,初始化flashcache
# modprobe flashcache
Step 3.查看kernel message,确认是否初始化成功
# dmesg | tail
Step 1.调用lsblk查看块设备信息
Step 2.能使用flashcache的设备必须是没有mount到任何目录的裸磁盘,若是已经mount了,必须先执行umount命令,(umount /dev/sdb1)。 /dev/sdb1上若是没有文件系统,先执行命令mke2fs /dev/sdb1来建立文件系统。
Step 3.执行命令,建立flashcache 卷(这里使用了ramdisk /dev/ram0代替ssd, 必须确保该ramdisk也没有被mount)
flashcache_create相关参数说明:
-p:缓存模式
-s:缓存大小,可选项,若是未指定则整个SSD设备被用于缓存,默认的计数单位是扇区(sectors),可是能够接受k/m/g单位。
-b:指定块大小,可选项,默认为4KB,必须为2的指数。默认单位为扇区。也能够用K做为单位,通常选4KB。
-f:强制建立,不进行检查
-m:设备元数据块大小,只有writeback须要存储metadata块,默认4K
Step 4.建立flashcache后,如要使用该设备,须要挂载设备,执行如下命令进行挂载
# mount /dev/mapper/ram0cache /mnt
Step 5.执行命令,查看flashcache 状态
# dmsetup status
建立一个新的Flashcache卷
# flashcache_create
删除一个flashcache卷
# dmsetup remove
加载一个已经存在的flashcache卷
# flashcache_load
清空一个已经存在的flashcache卷上的缓存
# flashcache_destroy
查看缓存相关的统计数据
# dmsetup status/dmsetup table
(1)flashcache_create
功能:建立一个新的flashcache卷。
命令语法:
flashcache_create [-v] -p back|around|thru [-s cache size] [-w] [-b block size] cachedevname ssd_devname disk_devname
-v: 查看详细状况
-p: 缓存模式 writeback,writethrough,writearound三种。
-s:缓存大小,可选项,若是未指定则整个SSD设备被用于缓存,默认的计数单位是扇区(sectors),可是能够接受k/m/g单位。
-b:指定块大小,可选项,默认为4KB,必须为2的指数。默认单位为扇区。也能够用K做为单位,通常选4KB。
-f:强制建立,不进行检查。
-w: 写缓存模式. 只对写入缓存,不对读取缓存
举例:
flashcache_create -p back -s 1g -b 4k cachedev /dev/sdc /dev/sdb
建立一个1GB的flashcache volume,block size为4k。使用ssd/dev/sdc对磁盘/dev/sdb作缓存. flashcache volume的名字是"cachedev"。
缓存模式:
Writethrough - 最安全的模式,全部的写操做在缓存的SSD的同时,也会马上被写入磁盘。若是SSD写的性能不如磁盘(2008-2010年生产的早期的SSD),会限制系统写性能。全部的磁盘读操做都会被缓存(tunable)。
Writearound - 很安全,写入时绕过SSD直接写入磁盘。磁盘块只有在被读取以后才会被缓存到SSD。全部的磁盘读操做都会被缓存(tunable)。
Writeback - 最快但最不安全,数据先写到SSD,随后基于各类策略写到普通硬盘。全部的磁盘读操做都会被缓存(tunable)。
Writeonly - Writeback的变种,只缓存写,不缓存读
持久性:
Writethrough Writearound 没有持久性,在断电或重启后,缓存数据会丢失,Writeback具备持久性,在断电或重启后,缓存数据不会丢失
(2)flashcache_load
功能:加载一个已经存在的flashcache卷
命令语法:
flashcache_load ssd_devname [cachedev_name]
举例:flashcache_load /dev/ssd
若是想要修改已经存在的flashcache卷的名字,能够指定[cachedev_name]参数,对Writethrough和Writearound模式来讲,这个命令没有用处,每次都必须从新执行flashcache_create
通常是为了重启后可继续使用。
(3) dmsetup remove
功能:删除/卸载一个flashcache卷
命令语法:
dmsetup remove cachedev_name
举例:
dmsetup remove cachedev
删除名为cachedev的flashcache卷
3. flashcache_destroy
功能:清空一个已经存在的flashcache卷上的缓存,全部数据都会丢失!!!
命令语法:
flashcache_destroy ssd_devname
举例:
flashcache_destroy /dev/sdc
清空/dev/sdc中的缓存. 全部数据都会丢失!!!
对Writethrough和Writearound模式来讲,没有必要使用
(4) dmsetup status/dmsetup table
功能:查看缓存相关的统计数据
举例:
dmsetup status cachedev
dmsetup table cachedev
查看名为cachedev的flashcache卷中缓存信息
(5) Cache统计信息
可使用 “dmsetup status”命令来查询cache的统计信息。
“dmsetup table”命令能够dumps出来achce相关的统计信息。
举例:
dmsetup status cachedev
dmsetup table cachedev
另外proc文件系统中也有相应的状态和错误的统计报告:
flashcache 卷的错误信息报告在
/proc/flashcache/<cache name>/flashcache_errors 里
顺序I/O性能,Flashcache并不特别占优点。缓存该类顺序I/O,相反会浪费SSD固态盘的空间和增长负担。
IOPS (Input/Output Operations Per Second),即每秒进行读写(I/O)操做的次数。决定IOPS的主要取决于阵列的算法,cache命中率,以及磁盘个数。
Flashcache使用SSD做为缓存,读写速度完胜普通磁盘,尤为是遇到非连续的散片数据,SSD能体现出极快的读写速度。而传统机械硬盘因为磁头寻道等缘由,传输速度偏慢。
==========
SSD的顺序I/O的性能与磁盘(尤为是RAID盘)性能并不特别占优点,缓存该类顺序I/O,相反会浪费SSD固态盘的空间和负担。
参考文献
[1] 基于flashcache的混合存储方案设计与实现