flashcache,是facebook技術團隊開發(fā)的新開源項目,主要目的是用SSD硬盤來緩存數(shù)據(jù)以加速MySQL的一個內(nèi)核模塊。可以看到,它最初是用來做數(shù)據(jù)庫加速,但同時,它也被作為通用的緩存模塊而設計,能夠用于任何搭建在塊設備上的應用程序。
一、簡介及原理
1、工作原理
基于Device Mapper,它將快速的SSD硬盤和普通的硬盤映射成一個 帶緩存的邏輯塊設備,作為用戶操作的接口。用戶直接對這個邏輯設備執(zhí)行讀寫操作,而不直接對底層的SSD或者普通硬盤操作。如果對底層的這些塊設備操作, 那么會失去作為一個整體提供的緩存功能。
2、內(nèi)核層次
flashcache,它是通過在文件系統(tǒng)和塊設備驅動層中間 增加一緩存層次實現(xiàn)的,這里不得不提到DM層的映射機制。由于DM是作為虛擬的塊設備驅動在內(nèi)核中被注冊的,它不是一個真實的設備驅動,不能完成bio的 處理,因此,它主要是基于映射表對bio進行分解、克隆和重映射,然后,bio到達底層真實的設備驅動,啟動數(shù)據(jù)傳輸。在Device mapper中,引入了target_driver,每個target_driver由target_type類型描述,代表了一類映射,它們分別用來具 體實現(xiàn)塊設備的映射過程。通過調用某一target_driver的map方法,來映射從上層分發(fā)下來的bio,也即是,找到正確的目標設備,并將bio 轉發(fā)到目標設備的請求隊列,完成操作。flashcache_target就是這樣一個新的target_driver(作為一個新的映射類 型,target_type是必須的),以模塊化的方式加入到了DM層。
3、邏輯架構
從源代碼層次分析,可以將flashcache分為這個四個模 塊,調度模塊(也稱‘讀寫模塊’)、邏輯處理模塊(也稱“讀寫后處理模塊”)、底層存儲模塊、以及后臺清理模塊,它們都是基于SSD Layout實現(xiàn)的,構建在SSD布局(后面會分析)之上。其中,調度模塊,在代碼中對應flashcache_map映射函數(shù),它是 flashcache緩存層次數(shù)據(jù)入口,所以到達邏輯設備的讀寫請求,最終都會經(jīng)過DM層的處理,通過flashcache_map進入調度模塊。稱之為 “調度”,主要是指,接收到數(shù)據(jù)后,它會根據(jù)bio請求的讀寫類型、是否命中緩存等因素,選擇不同的處理分支,如 flashcache_read/write或者flashcache_uncached_io,在read和write中會選擇是 flashcache_read_hit/miss還是flashcache_write_hit/miss。經(jīng)過不同分支的讀寫,會調用底層存儲模塊來 完成磁盤或cache的數(shù)據(jù)讀寫。邏輯處理模塊,在代碼中對應flashcache_io_callback,它在調度模塊通過底層存儲模塊執(zhí)行數(shù)據(jù)讀寫 操作完成后回調執(zhí)行,所以說它是“讀寫后處理模塊”,它是采用狀態(tài)機實現(xiàn)的,根據(jù)調度模塊中的讀寫類型進行后續(xù)的處理,如讀未命中情況下,磁盤讀完成后, 回調到邏輯處理模塊,由它負責將從磁盤讀取的數(shù)據(jù)寫回到SSD,或者寫未命中情況下,寫SSD完成后,回調到邏輯處理模塊執(zhí)行元數(shù)據(jù)的更新,再有就是對調 度模塊中讀寫操作的錯誤進行處理。底層存儲模塊,主要提供了兩種方式來完成真實的數(shù)據(jù)讀寫,一是由DM提供的dm_io函數(shù),它最終還是通過 submit_bio的方式,將由調度模塊處理過的bio提交到通用塊層,進行轉發(fā)到真實的設備驅動,完成數(shù)據(jù)讀寫;另外,一種方式,kcopyd,是由 內(nèi)核提供的一種底層拷貝函數(shù),主要負責臟塊的寫回(從SSD到磁盤),會引起元數(shù)據(jù)的更新。而后臺清理模塊,是針對每個set進行數(shù)據(jù)清理,它會基于兩種 策略對臟塊做回收:(1)set內(nèi)臟塊超過了閾值;(2)臟塊超過了設定的空閑時間,即fallow_delay,一般是15分鐘,在15分鐘沒有被操作 則會被優(yōu)先回收。要注意的是,并沒有單獨的線程在后臺做定期空閑塊回收,必須由IO操作觸發(fā),如果長時間沒有對某set操作,則其中的臟數(shù)據(jù)很長期保持, 容易危害數(shù)據(jù)安全。
4、源代碼布局
兩個工作隊列。結合device mapper代碼,特別是dm.c可以知道,在調用flashcache_create工具創(chuàng)建flashcache設備時,會調用 flashcache_ctl函數(shù),執(zhí)行創(chuàng)建工具,它會創(chuàng)建一工作隊列_delay_clean,主要負責對整個cache設備的臟塊清理,由 flashcache_clean_set在特定條件下調用(見代碼),通過flashcache_clean_all執(zhí)行對所有sets的掃描與清理。 另外一個工作隊列,_kq_xxx,在flashcache_init中,由flashcache模塊加載時執(zhí)行,通過對5個job鏈表進行 處理,執(zhí)行元數(shù)據(jù)的更新與完成處理函數(shù)、讀磁盤后的SSD寫入、以及對等待隊列的處理,主要就是負責讀寫后的處理工作隸屬于邏輯處理模塊,即“讀寫后處理 模塊”,由磁盤或SSD讀寫后不同情況下被調度。
調度的時機可以看flashcache_map函數(shù),處理邏輯則主要在函數(shù)flashcache_io_callback內(nèi)部判斷,the same block的等待隊列是否為空,如果不為空,則同樣會調用flashcache_do_handler,執(zhí)行對等待隊列的處理。
5、數(shù)據(jù)調度
對讀,接收到bio,首先,根據(jù) bio->bi_sector,即硬盤的扇區(qū)號,得到SSD上的set。其次,在set內(nèi)查找是否命中,如果命中,則將硬盤的扇區(qū)號轉換為SSD的 扇區(qū)號,然后將此bio向SSD提交,進行讀取;如果未命中,則首先向硬盤驅動提交bio,從硬盤讀數(shù)據(jù),讀取完成后,由回調函數(shù)啟動回寫SSD操作,將 bio的扇區(qū)號轉換為SSD的=扇區(qū)號,然后向SSD驅動程序提交,將硬盤讀取的數(shù)據(jù)寫入SSD。對寫,同文件系統(tǒng)頁緩沖,并不直接寫入硬盤,而是寫入 SSD,同時,保持一個閥值,一般為20%,在臟塊數(shù)目達到此數(shù)值時,寫回磁盤。
6、緩存模式 flashcache支持三種緩存模式:
Writeback : 對于寫入,首先會寫入到Cache中,同時將對于block的元數(shù)據(jù)dirty bit,但是并不會立即寫入后備的device
Writethrough : 對于寫入,寫入到Cache中,同時也會將數(shù)據(jù)寫入backing device,知道寫完backing device,才算寫完
Writearound : 寫入的時候,繞過Cache,直接寫入backing device,即SSD只當讀緩存
二、安裝內(nèi)核
1、升級內(nèi)核
# 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
3、編譯安裝
# cd flashcache/
# make
# make install
4、加載內(nèi)核模塊
# modprobe flashcache
檢查
# lsmod | grep flashcache
flashcache 106496 1
dm_mod 110592 11 dm_log,dm_mirror,flashcache
5、自動加載內(nèi)核模塊新建文件/etc/sysconfig/modules/flashcache.modules內(nèi)容如下
#! /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、創(chuàng)建緩存設備
# 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
參數(shù)說明:
-p:緩存模式 writeback,writethrough,writearound三種。
-s:緩存大小,可選項,如果未指定則整個SSD設備被用于緩存,默認的計數(shù)單位是扇區(qū)(sectors),但是可以接受k/m/g單位。
-b:指定塊大小,可選項,默認為4KB,必須為2的指數(shù)。默認單位為扇區(qū)。也可以用K作為單位,一般選4KB。
-f:強制創(chuàng)建,不進行檢查
注意: 加速的ssd和后端HDD磁盤可以是一個分區(qū)也可以是一塊磁盤
7、格式化磁盤
# mkfs.xfs /dev/mapper/cachedev
8、查看狀態(tài)
# 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 卷的統(tǒng)計信息報告
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、查看內(nèi)核信息
# 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、安裝狀態(tài)查詢工具
# 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
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