智汇华云 | flashcache原理及实践

来源:华云公众号 更新时间:2022-05-22
flashcache是facebook技术团队开发的新开源项目,主要目的是用SSD硬盘来缓存数据以加速MySQL的一个内核模块。可以看到,它最初是用来做数据库加速,但同时,它也被作为通用的缓存模块而设计,能够用于任何搭建在块设备上的应用程序。本期智汇华云,为大家介绍flashcache原理及实践。

/upload/image/20220522/dc21d328ca16290be4576619d5a2a161.jpg

一、简介及原理

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只当读缓存

/upload/image/20220522/08cc346ccd902ceb7cd935ec12b7f98c.png

二、安装内核

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、创建缓存设备

6.png

参数说明:

-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、查看具体的读写和命中率信息

9.png

10、查看内核信息

10.png

11、安装状态查询工具

11.png

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

在线咨询
400-808-4000
免费试用