?flashcache,是facebook技術(shù)團(tuán)隊(duì)開(kāi)發(fā)的新開(kāi)源項(xiàng)目,主要目的是用SSD硬盤(pán)來(lái)緩存數(shù)據(jù)以加速M(fèi)ySQL的一個(gè)內(nèi)核模塊??梢钥吹?,它最初是用來(lái)做數(shù)據(jù)庫(kù)加速,但同時(shí),它也被作為通用的緩存模塊而設(shè)計(jì),能夠用于任何搭建在塊設(shè)備上的應(yīng)用程序。
一、簡(jiǎn)介及原理
1、工作原理
基于Device Mapper,它將快速的SSD硬盤(pán)和普通的硬盤(pán)映射成一個(gè) 帶緩存的邏輯塊設(shè)備,作為用戶(hù)操作的接口。用戶(hù)直接對(duì)這個(gè)邏輯設(shè)備執(zhí)行讀寫(xiě)操作,而不直接對(duì)底層的SSD或者普通硬盤(pán)操作。如果對(duì)底層的這些塊設(shè)備操作, 那么會(huì)失去作為一個(gè)整體提供的緩存功能。
2、內(nèi)核層次
flashcache,它是通過(guò)在文件系統(tǒng)和塊設(shè)備驅(qū)動(dòng)層中間 增加一緩存層次實(shí)現(xiàn)的,這里不得不提到DM層的映射機(jī)制。由于DM是作為虛擬的塊設(shè)備驅(qū)動(dòng)在內(nèi)核中被注冊(cè)的,它不是一個(gè)真實(shí)的設(shè)備驅(qū)動(dòng),不能完成bio的 處理,因此,它主要是基于映射表對(duì)bio進(jìn)行分解、克隆和重映射,然后,bio到達(dá)底層真實(shí)的設(shè)備驅(qū)動(dòng),啟動(dòng)數(shù)據(jù)傳輸。在Device mapper中,引入了target_driver,每個(gè)target_driver由target_type類(lèi)型描述,代表了一類(lèi)映射,它們分別用來(lái)具 體實(shí)現(xiàn)塊設(shè)備的映射過(guò)程。通過(guò)調(diào)用某一target_driver的map方法,來(lái)映射從上層分發(fā)下來(lái)的bio,也即是,找到正確的目標(biāo)設(shè)備,并將bio 轉(zhuǎn)發(fā)到目標(biāo)設(shè)備的請(qǐng)求隊(duì)列,完成操作。flashcache_target就是這樣一個(gè)新的target_driver(作為一個(gè)新的映射類(lèi) 型,target_type是必須的),以模塊化的方式加入到了DM層。
3、邏輯架構(gòu)
從源代碼層次分析,可以將flashcache分為這個(gè)四個(gè)模 塊,調(diào)度模塊(也稱(chēng)‘讀寫(xiě)模塊’)、邏輯處理模塊(也稱(chēng)“讀寫(xiě)后處理模塊”)、底層存儲(chǔ)模塊、以及后臺(tái)清理模塊,它們都是基于SSD Layout實(shí)現(xiàn)的,構(gòu)建在SSD布局(后面會(huì)分析)之上。其中,調(diào)度模塊,在代碼中對(duì)應(yīng)flashcache_map映射函數(shù),它是 flashcache緩存層次數(shù)據(jù)入口,所以到達(dá)邏輯設(shè)備的讀寫(xiě)請(qǐng)求,最終都會(huì)經(jīng)過(guò)DM層的處理,通過(guò)flashcache_map進(jìn)入調(diào)度模塊。稱(chēng)之為 “調(diào)度”,主要是指,接收到數(shù)據(jù)后,它會(huì)根據(jù)bio請(qǐng)求的讀寫(xiě)類(lèi)型、是否命中緩存等因素,選擇不同的處理分支,如 flashcache_read/write或者flashcache_uncached_io,在read和write中會(huì)選擇是 flashcache_read_hit/miss還是flashcache_write_hit/miss。經(jīng)過(guò)不同分支的讀寫(xiě),會(huì)調(diào)用底層存儲(chǔ)模塊來(lái) 完成磁盤(pán)或cache的數(shù)據(jù)讀寫(xiě)。邏輯處理模塊,在代碼中對(duì)應(yīng)flashcache_io_callback,它在調(diào)度模塊通過(guò)底層存儲(chǔ)模塊執(zhí)行數(shù)據(jù)讀寫(xiě) 操作完成后回調(diào)執(zhí)行,所以說(shuō)它是“讀寫(xiě)后處理模塊”,它是采用狀態(tài)機(jī)實(shí)現(xiàn)的,根據(jù)調(diào)度模塊中的讀寫(xiě)類(lèi)型進(jìn)行后續(xù)的處理,如讀未命中情況下,磁盤(pán)讀完成后, 回調(diào)到邏輯處理模塊,由它負(fù)責(zé)將從磁盤(pán)讀取的數(shù)據(jù)寫(xiě)回到SSD,或者寫(xiě)未命中情況下,寫(xiě)SSD完成后,回調(diào)到邏輯處理模塊執(zhí)行元數(shù)據(jù)的更新,再有就是對(duì)調(diào) 度模塊中讀寫(xiě)操作的錯(cuò)誤進(jìn)行處理。底層存儲(chǔ)模塊,主要提供了兩種方式來(lái)完成真實(shí)的數(shù)據(jù)讀寫(xiě),一是由DM提供的dm_io函數(shù),它最終還是通過(guò) submit_bio的方式,將由調(diào)度模塊處理過(guò)的bio提交到通用塊層,進(jìn)行轉(zhuǎn)發(fā)到真實(shí)的設(shè)備驅(qū)動(dòng),完成數(shù)據(jù)讀寫(xiě);另外,一種方式,kcopyd,是由 內(nèi)核提供的一種底層拷貝函數(shù),主要負(fù)責(zé)臟塊的寫(xiě)回(從SSD到磁盤(pán)),會(huì)引起元數(shù)據(jù)的更新。而后臺(tái)清理模塊,是針對(duì)每個(gè)set進(jìn)行數(shù)據(jù)清理,它會(huì)基于兩種 策略對(duì)臟塊做回收:(1)set內(nèi)臟塊超過(guò)了閾值;(2)臟塊超過(guò)了設(shè)定的空閑時(shí)間,即fallow_delay,一般是15分鐘,在15分鐘沒(méi)有被操作 則會(huì)被優(yōu)先回收。要注意的是,并沒(méi)有單獨(dú)的線程在后臺(tái)做定期空閑塊回收,必須由IO操作觸發(fā),如果長(zhǎng)時(shí)間沒(méi)有對(duì)某set操作,則其中的臟數(shù)據(jù)很長(zhǎng)期保持, 容易危害數(shù)據(jù)安全。
4、源代碼布局
兩個(gè)工作隊(duì)列。結(jié)合device mapper代碼,特別是dm.c可以知道,在調(diào)用flashcache_create工具創(chuàng)建flashcache設(shè)備時(shí),會(huì)調(diào)用 flashcache_ctl函數(shù),執(zhí)行創(chuàng)建工具,它會(huì)創(chuàng)建一工作隊(duì)列_delay_clean,主要負(fù)責(zé)對(duì)整個(gè)cache設(shè)備的臟塊清理,由 flashcache_clean_set在特定條件下調(diào)用(見(jiàn)代碼),通過(guò)flashcache_clean_all執(zhí)行對(duì)所有sets的掃描與清理。 另外一個(gè)工作隊(duì)列,_kq_xxx,在flashcache_init中,由flashcache模塊加載時(shí)執(zhí)行,通過(guò)對(duì)5個(gè)job鏈表進(jìn)行 處理,執(zhí)行元數(shù)據(jù)的更新與完成處理函數(shù)、讀磁盤(pán)后的SSD寫(xiě)入、以及對(duì)等待隊(duì)列的處理,主要就是負(fù)責(zé)讀寫(xiě)后的處理工作隸屬于邏輯處理模塊,即“讀寫(xiě)后處理 模塊”,由磁盤(pán)或SSD讀寫(xiě)后不同情況下被調(diào)度。
調(diào)度的時(shí)機(jī)可以看flashcache_map函數(shù),處理邏輯則主要在函數(shù)flashcache_io_callback內(nèi)部判斷,the same block的等待隊(duì)列是否為空,如果不為空,則同樣會(huì)調(diào)用flashcache_do_handler,執(zhí)行對(duì)等待隊(duì)列的處理。
5、數(shù)據(jù)調(diào)度
對(duì)讀,接收到bio,首先,根據(jù) bio->bi_sector,即硬盤(pán)的扇區(qū)號(hào),得到SSD上的set。其次,在set內(nèi)查找是否命中,如果命中,則將硬盤(pán)的扇區(qū)號(hào)轉(zhuǎn)換為SSD的 扇區(qū)號(hào),然后將此bio向SSD提交,進(jìn)行讀取;如果未命中,則首先向硬盤(pán)驅(qū)動(dòng)提交bio,從硬盤(pán)讀數(shù)據(jù),讀取完成后,由回調(diào)函數(shù)啟動(dòng)回寫(xiě)SSD操作,將 bio的扇區(qū)號(hào)轉(zhuǎn)換為SSD的=扇區(qū)號(hào),然后向SSD驅(qū)動(dòng)程序提交,將硬盤(pán)讀取的數(shù)據(jù)寫(xiě)入SSD。對(duì)寫(xiě),同文件系統(tǒng)頁(yè)緩沖,并不直接寫(xiě)入硬盤(pán),而是寫(xiě)入 SSD,同時(shí),保持一個(gè)閥值,一般為20%,在臟塊數(shù)目達(dá)到此數(shù)值時(shí),寫(xiě)回磁盤(pán)。
6、源代碼地址:
https://github.com/facebook/flashcache
7、緩存模式 flashcache支持三種緩存模式:
Writeback : 對(duì)于寫(xiě)入,首先會(huì)寫(xiě)入到Cache中,同時(shí)將對(duì)于block的元數(shù)據(jù)dirty bit,但是并不會(huì)立即寫(xiě)入后備的device
Writethrough : 對(duì)于寫(xiě)入,寫(xiě)入到Cache中,同時(shí)也會(huì)將數(shù)據(jù)寫(xiě)入backing device,知道寫(xiě)完backing device,才算寫(xiě)完
Writearound : 寫(xiě)入的時(shí)候,繞過(guò)Cache,直接寫(xiě)入backing device,即SSD只當(dāng)讀緩存
二、安裝內(nèi)核
1、升級(jí)內(nèi)核
#rpm-ivhkernel-4.4.199-1.x86_64.rpm
#rpm-ivhkernel-devel-4.4.199-1.x86_64.rpm
2、生成grub
# grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
3、重啟
# reboot
三、安裝flashcache1、安裝依賴(lài)工具
# yuminstall -y git make gcc
2、下載flashcache源碼
# git clonehttps://github.com/facebook/flashcache
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、自動(dòng)加載內(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
賦予權(quán)限
# chmod +x /etc/sysconfig/modules/flashcache.modules
6、創(chuàng)建緩存設(shè)備
# flashcache_create -p back -b 4k cachedev /dev/sdc /dev/sdb
cachedev cachedev, ssd_devname /dev/sdc, disk_devname /dev/sdbcachemodeWRITE_BACK
block_size 8, md_block_size 8, cache_size 0
Flashcache metadata willuse440MBofyour 32172MBmainmemory
參數(shù)說(shuō)明:
-p:緩存模式 writeback,writethrough,writearound三種。
-s:緩存大小,可選項(xiàng),如果未指定則整個(gè)SSD設(shè)備被用于緩存,默認(rèn)的計(jì)數(shù)單位是扇區(qū)(sectors),但是可以接受k/m/g單位。
-b:指定塊大小,可選項(xiàng),默認(rèn)為4KB,必須為2的指數(shù)。默認(rèn)單位為扇區(qū)。也可以用K作為單位,一般選4KB。
-f:強(qiáng)制創(chuàng)建,不進(jìn)行檢查
注意: 加速的ssd和后端HDD磁盤(pán)可以是一個(gè)分區(qū)也可以是一塊磁盤(pán)
7、格式化磁盤(pán)
# 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 卷的錯(cuò)誤信息報(bào)告
-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)計(jì)信息報(bào)告
9、查看具體的讀寫(xiě)和命中率信息
# 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)查詢(xún)工具
# 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 toolforflashcache 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 #從設(shè)備號(hào)2
Number of targets: 1
# dmsetup remove /dev/dm-2
# flashcache_destroy /dev/sdc
flashcache_destroy: Destroying Flashcache foundon/dev/sdc. Any data will be lost !!
# dmsetup remove cachedev
# flashcache_destroy /dev/sdc -f
四、遇到的問(wèn)題
1、重啟之后設(shè)備沒(méi)了
# modprobe flashcache
# modprobe -r flashcache
# flashcache_load /dev/sdc
(免責(zé)聲明:本網(wǎng)站內(nèi)容主要來(lái)自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。
任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁(yè)或鏈接內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書(shū)面權(quán)利通知或不實(shí)情況說(shuō)明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會(huì)依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開(kāi)相關(guān)鏈接。 )