一、简介及原理
1、工作原理
基于Device Mapper,它将快速的SSD硬盘和普通的硬盘映射成一个 带缓存的逻辑块设备,作为用户操作的接口。用户直接对这个逻辑设备执行读写操作,而不直接对底层的SSD或者普通硬盘操作。如果对底层的这些块设备操作, 那么会失去作为一个整体提供的缓存功能。
2、内核层次
flashcache,它是通过在文件系统和块设备驱动层中间 增加一缓存层次实现的,这里不得不提到DM层的映射机制。由于DM是作为虚拟的块设备驱动在内核中被注册的,它不是一个真实的设备驱动,不能完成bio的 处理,因此,它主要是基于映射表对bio进行分解、克隆和重映射,然后,bio到达底层真实的设备驱动,启动数据传输。在Device mapper中,引入了target_driver,每个target_driver由target_type类型描述,代表了一类映射,它们分别用来具 体实现块设备的映射过程。通过调用某一target_driver的map方法,来映射从上层分发下来的bio,也即是,找到正确的目标设备,并将bio 转发到目标设备的请求队列,完成操作。flashcache_target就是这样一个新的target_driver(作为一个新的映射类 型,target_type是必须的),以模块化的方式加入到了DM层。
3、逻辑架构
从源代码层次分析,可以将flashcache分为这个四个模 块,调度模块(也称‘读写模块’)、逻辑处理模块(也称“读写后处理模块”)、底层存储模块、以及后台清理模块,它们都是基于SSD Layout实现的,构建在SSD布局(后面会分析)之上。其中,调度模块,在代码中对应flashcache_map映射函数,它是 flashcache缓存层次数据入口,所以到达逻辑设备的读写请求,最终都会经过DM层的处理,通过flashcache_map进入调度模块。称之为 “调度”,主要是指,接收到数据后,它会根据bio请求的读写类型、是否命中缓存等因素,选择不同的处理分支,如 flashcache_read/write或者flashcache_uncached_io,在read和write中会选择是 flashcache_read_hit/miss还是flashcache_write_hit/miss。经过不同分支的读写,会调用底层存储模块来 完成磁盘或cache的数据读写。逻辑处理模块,在代码中对应flashcache_io_callback,它在调度模块通过底层存储模块执行数据读写 操作完成后回调执行,所以说它是“读写后处理模块”,它是采用状态机实现的,根据调度模块中的读写类型进行后续的处理,如读未命中情况下,磁盘读完成后, 回调到逻辑处理模块,由它负责将从磁盘读取的数据写回到SSD,或者写未命中情况下,写SSD完成后,回调到逻辑处理模块执行元数据的更新,再有就是对调 度模块中读写操作的错误进行处理。底层存储模块,主要提供了两种方式来完成真实的数据读写,一是由DM提供的dm_io函数,它最终还是通过 submit_bio的方式,将由调度模块处理过的bio提交到通用块层,进行转发到真实的设备驱动,完成数据读写;另外,一种方式,kcopyd,是由 内核提供的一种底层拷贝函数,主要负责脏块的写回(从SSD到磁盘),会引起元数据的更新。而后台清理模块,是针对每个set进行数据清理,它会基于两种 策略对脏块做回收:(1)set内脏块超过了阈值;(2)脏块超过了设定的空闲时间,即fallow_delay,一般是15分钟,在15分钟没有被操作 则会被优先回收。要注意的是,并没有单独的线程在后台做定期空闲块回收,必须由IO操作触发,如果长时间没有对某set操作,则其中的脏数据很长期保持, 容易危害数据安全。
4、源代码布局
两个工作队列。结合device mapper代码,特别是dm.c可以知道,在调用flashcache_create工具创建flashcache设备时,会调用 flashcache_ctl函数,执行创建工具,它会创建一工作队列_delay_clean,主要负责对整个cache设备的脏块清理,由 flashcache_clean_set在特定条件下调用(见代码),通过flashcache_clean_all执行对所有sets的扫描与清理。另外一个工作队列,_kq_xxx,在flashcache_init中,由flashcache模块加载时执行,通过对5个job链表进行 处理,执行元数据的更新与完成处理函数、读磁盘后的SSD写入、以及对等待队列的处理,主要就是负责读写后的处理工作隶属于逻辑处理模块,即“读写后处理 模块”,由磁盘或SSD读写后不同情况下被调度。
调度的时机可以看flashcache_map函数,处理逻辑则主要在函数flashcache_io_callback内部判断,the same block的等待队列是否为空,如果不为空,则同样会调用flashcache_do_handler,执行对等待队列的处理。
5、数据调度
对读,接收到bio,首先,根据 bio->bi_sector,即硬盘的扇区号,得到SSD上的set。其次,在set内查找是否命中,如果命中,则将硬盘的扇区号转换为SSD的 扇区号,然后将此bio向SSD提交,进行读取;如果未命中,则首先向硬盘驱动提交bio,从硬盘读数据,读取完成后,由回调函数启动回写SSD操作,将 bio的扇区号转换为SSD的=扇区号,然后向SSD驱动程序提交,将硬盘读取的数据写入SSD。对写,同文件系统页缓冲,并不直接写入硬盘,而是写入 SSD,同时,保持一个阀值,一般为20%,在脏块数目达到此数值时,写回磁盘。
6、源代码地址:
https://github.com/facebook/flashcache
7、缓存模式 flashcache支持三种缓存模式:
Writeback : 对于写入,首先会写入到Cache中,同时将对于block的元数据dirty bit,但是并不会立即写入后备的device
Writethrough : 对于写入,写入到Cache中,同时也会将数据写入backing device,知道写完backing device,才算写完
Writearound : 写入的时候,绕过Cache,直接写入backing device,即SSD只当读缓存
二、安装内核
1、升级内核
# rpm -ivh kernel-4.4.199-1.x86_64.rpm
# rpm -ivh kernel-devel-4.4.199-1.x86_64.rpm
2、生成grub
# grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
3、重启
# reboot
三、安装flashcache
1、安装依赖工具
# yum install -y git make gcc
2、下载flashcache源码
# git clone https://github.com/facebook/flashcache
3、编译安装
# cd flashcache/
# make
# make install
4、加载内核模块
# modprobe flashcache
检查
# lsmod | grep flashcache
flashcache 106496 1
dm_mod 110592 11 dm_log,dm_mirror,flashcache
5、自动加载内核模块
新建文件/etc/sysconfig/modules/flashcache.modules内容如下
#! /bin/sh
/sbin/modinfo -F filename flashcache > /dev/null 2>&1
if [ $? -eq 0 ]; then
/sbin/modprobe flashcache
fi
赋予权限
# chmod +x /etc/sysconfig/modules/flashcache.modules
6、创建缓存设备
参数说明:
-p:缓存模式 writeback,writethrough,writearound三种。
-s:缓存大小,可选项,如果未指定则整个SSD设备被用于缓存,默认的计数单位是扇区(sectors),但是可以接受k/m/g单位。
-b:指定块大小,可选项,默认为4KB,必须为2的指数。默认单位为扇区。也可以用K作为单位,一般选4KB。
-f:强制创建,不进行检查
注意:加速的ssd和后端HDD磁盘可以是一个分区也可以是一块磁盘
7、格式化磁盘
# mkfs.xfs /dev/mapper/cachedev
8、查看状态
# ll /proc/flashcache/sdc+sdb/
total 0
-r--r--r-- 1 root root 0 Dec 16 14:05 flashcache_errors #flashcache 卷的错误信息报告
-r--r--r-- 1 root root 0 Dec 16 14:05 flashcache_iosize_hist
-r--r--r-- 1 root root 0 Dec 16 14:05 flashcache_pidlists
-r--r--r-- 1 root root 0 Dec 16 14:05 flashcache_stats #flashcache 卷的统计信息报告
9、查看具体的读写和命中率信息
10、查看内核信息
11、安装状态查询工具
12、卸载
# dmsetup info cachedev
Name: cachedev
State: ACTIVE
Read Ahead: 256
Tables present: LIVE
Open count: 0
Event number: 0
Major, minor: 253, 2 #从设备号2
Number of targets: 1
# dmsetup remove /dev/dm-2
# flashcache_destroy /dev/sdc
flashcache_destroy: Destroying Flashcache found on /dev/sdc. Any data will be lost !!
# dmsetup remove cachedev
# flashcache_destroy /dev/sdc -f
四、遇到的问题
1、重启之后设备没了
# modprobe flashcache
# modprobe -r flashcache
# flashcache_load /dev/sdc