写点什么

智汇华云 | flashcache 原理及实践

作者:华云数据
  • 2022 年 4 月 29 日
  • 本文字数:5317 字

    阅读完需:约 17 分钟

flashcache,是 facebook 技术团队开发的新开源项目,主要目的是用 SSD 硬盘来缓存数据以加速 MySQL 的一个内核模块。可以看到,它最初是用来做数据库加速,但同时,它也被作为通用的缓存模块而设计,能够用于任何搭建在块设备上的应用程序。

一、简介及原理

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

# flashcache_create -p back -b 4k cachedev /dev/sdc /dev/sdb

cachedev cachedev, ssd_devname /dev/sdc, disk_devname /dev/sdb cache mode WRITE_BACK

block_size 8, md_block_size 8, cache_size 0

Flashcache metadata will use 440MB of your 32172MB main memory

参数说明:

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

# dmsetup status cachedev

0 419430400 flashcache stats:

reads(391120), writes(45940753)

read hits(337167), read hit percent(86)

write hits(20875155) write hit percent(45)

dirty write hits(20807737) dirty write hit percent(45)

replacement(11844), write replacement(183083)

write invalidates(5), read invalidates(19)

pending enqueues(33090), pending inval(33090)

metadata dirties(20621560), metadata cleans(1832026)

metadata batch(22220959) metadata ssd writes(232627)

cleanings(1832026) fallow cleanings(0)

no room(4520223) front merge(124207) back merge(1697772)

force_clean_block(0)

disk reads(53953), disk writes(6344364) ssd reads(2169176) ssd writes(41674210)

uncached reads(41405), uncached writes(4512356), uncached IO requeue(0)

disk read errors(0), disk write errors(0) ssd read errors(0) ssd write errors(0)

uncached sequential reads(0), uncached sequential writes(0)

pid_adds(0), pid_dels(0), pid_drops(0) pid_expiry(0)

lru hot blocks(10444544), lru warm blocks(10444544)

lru promotions(0), lru demotions(0)

10、查看内核信息

# sysctl -a | grep flashcache

dev.flashcache.sdc+sdb.cache_all = 1

dev.flashcache.sdc+sdb.clean_on_read_miss = 0

dev.flashcache.sdc+sdb.clean_on_write_miss = 0

dev.flashcache.sdc+sdb.dirty_thresh_pct = 20

dev.flashcache.sdc+sdb.do_pid_expiry = 0

dev.flashcache.sdc+sdb.do_sync = 0

dev.flashcache.sdc+sdb.fallow_clean_speed = 2

dev.flashcache.sdc+sdb.fallow_delay = 900

dev.flashcache.sdc+sdb.fast_remove = 0

dev.flashcache.sdc+sdb.io_latency_hist = 0

dev.flashcache.sdc+sdb.lru_hot_pct = 75

dev.flashcache.sdc+sdb.lru_promote_thresh = 2

dev.flashcache.sdc+sdb.max_clean_ios_set = 2

dev.flashcache.sdc+sdb.max_clean_ios_total = 4

dev.flashcache.sdc+sdb.max_pids = 100

dev.flashcache.sdc+sdb.new_style_write_merge = 0

dev.flashcache.sdc+sdb.pid_expiry_secs = 60

dev.flashcache.sdc+sdb.reclaim_policy = 0

dev.flashcache.sdc+sdb.skip_seq_thresh_kb = 0

dev.flashcache.sdc+sdb.stop_sync = 0

dev.flashcache.sdc+sdb.zero_stats = 0

11、安装状态查询工具

# cp /root/flashcache-master/utils/flashstat /bin/

# chmod +x /bin/flashstat

# flashstat

sysctl: reading key "net.ipv6.conf.all.stable_secret"

sysctl: reading key "net.ipv6.conf.default.stable_secret"

sysctl: reading key "net.ipv6.conf.eth0.stable_secret"

sysctl: reading key "net.ipv6.conf.lo.stable_secret"

======================================================================================================

Flashstat: a tool for flashcache status per second

Author : NinGoo(seaman.ning@gmail.com)

Version : 0.3

======================================================================================================

SSD Device: /dev/sdc Disk Device: /dev/sdb Cache Mode: WRITE_BACK

Capacity: 81598M Block Size: 4K Meta Block Size: 4096b

Total Blocks: 20889088 Cached Blocks: 159897 Cached Percent: 0

Set Numbers: 512 Dirty Blocks: 125921 Dirty Percent: 0

cache_all: 1 reclaim_policy: FIFO dirty_thresh_pct: 20

max_clean_ios_set: 2 max_clean_ios_total: 4 skip_seq_thresh: 0K

======================================================================================================

time read/s write/s diskr/s diskw/s ssdr/s ssdw/s uread/s uwrit/s metaw/s clean/s repl/s wrepl/s hit% whit% dwhit%

12-16 14:32:33 0 98813 0 0 0 99355 0 0 541 0 0 0 0|63 0|0 0|0

12-16 14:32:34 0 112569 0 0 0 113211 0 0 636 0 0 0 0|63 0|0 0|0

12-16 14:32:35 0 111352 0 0 0 112019 0 0 666 0 0 0 0|63 0|0 0|0

12-16 14:32:36 0 84825 0 0 0 85362 0 0 543 0 0 0 0|63 0|0 0|0

12-16 14:32:38 0 102305 0 0 0 102848 0 0 537 0 0 0 0|63 0|0 0|0

12-16 14:32:39 0 109665 0 0 0 110322 0 0 662 0 0 0 0|63 0|0 0|0

12-16 14:32:40 0 158722 0 0 0 159609 0 0 887 0 0 0 0|63 0|0 0|0

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

用户头像

华云数据

关注

还未添加个人签名 2020.11.02 加入

还未添加个人简介

评论

发布
暂无评论
智汇华云 | flashcache原理及实践_华云数据_InfoQ写作社区