BCache源碼淺析之一基本使用與代碼模塊

BCache源碼淺析

 BCache可用於雲平臺加速磁盤的讀寫性能;但目前該技術由於較新還不夠穩定。不過由於它已經移入到了Linux內核源碼中,所以穩定性應會得到不斷的提升。本系類文章將嘗試分析Linux Kernel/Driver/Md/Bcache的工作原理與架構, 但由於個人能力與時間原因可能存在很多不足; 另一個想法是和大家交流bcache((其中bset部分的一些代碼還未理解); 所以這裏只能是淺析, 可能有些地方的理解存在錯誤, 希望能與大家交流討論。


1.作用與架構

1.1 簡介 

  bcache是按照SSD特性來設計的,只按擦除桶大小進行分配,使用b+tree和日誌混合方法來跟蹤緩存數據,緩存數據可以是桶上的任意一個扇區。bcache最大程度上減少了隨機寫的代價,它按順序填充一個桶,重新使用時只需將桶設置爲無效。bcache支持寫直達和回寫策略。回寫默認情況下是關閉的,可以在運行時改變。bcache還在最大程度上保護你的數據,在系統異常關機時數據仍然是可靠的。因爲它被設計爲只有在數據完全寫回存儲設備才確認寫成功。回寫策略能夠緩存絕大多數的寫請求,然後再按照索引將髒數據按次序寫回到後端存儲設備。SSD的特點就是隨機IO速度很快,而對於大塊順序IO的提升卻並不大。bcache會檢測順序IO並忽略;還會對每一個任務記錄動態的平均IO大小,當平均IO大小超過截止值時該任務後面的IO將會被忽略,這樣就可以透傳備份或者大文件拷貝。

在flash上發現數據IO錯誤時,首先會嘗試讀以恢復數據或者將該緩存項置爲無效。對於不可恢復的錯誤,例如元數據或髒數據,bcache將會自動關閉緩存。如果有髒數據在緩存中,這時會首先關閉回寫策略然後再等待髒數據刷回。

 

1.2  基本使用:

1.編譯安裝
# git clone http://evilpiepirate.org/git/bcache-tools.git
安裝前需要兩個依賴包pkg-config和libblkid-dev
# apt-get install pkg-config libblkid-dev
然後編譯
# make
# make install

2.使用方式
2.1 創建bcache設備
命令:make-bcache -C [cache-device] -B [backing-device]
以vde作爲緩存盤,vdb和vdc作爲後端設備創建bcache設備,有幾個後端設備就會生成幾個bcache設備。

# make-bcache -C /dev/vde -B /dev/vdb /dev/vdc
UUID: 8941a5d1-074e-4cc6-a6dd-56cb1f65aed3
Set UUID: 7681dbb3-6558-4e60-b062-5fbb648f6665
version: 0
nbuckets: 20480
block_size: 1
bucket_size: 1024
nr_in_set: 1
nr_this_dev: 0
first_bucket: 1
UUID: 9e28d09b-942d-487e-be22-9132063da572
Set UUID: 7681dbb3-6558-4e60-b062-5fbb648f6665
version: 1
block_size: 1
data_offset: 16
UUID: 1bacf83e-2754-4d6a-a964-09e53e6e679f
Set UUID: 7681dbb3-6558-4e60-b062-5fbb648f6665
version: 1
block_size: 1
data_offset: 16
# ls /dev/bcache* -la
brw-rw—T 1 root disk 250, 0 5月22 17:23 /dev/bcache0
brw-rw—T 1 root disk 250, 1 5月22 17:23 /dev/bcache1

然後可以使用lsblk查看這些設備的對應關係
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 254:0 0 20G 0 disk
└─vda1 254:1 0 20G 0 part /
vdb 254:16 0 50G 0 disk
└─bcache1 250:1 0 50G 0 disk
vdc 254:32 0 50G 0 disk
└─bcache0 250:0 0 50G 0 disk
vdd 254:48 0 50G 0 disk
└─bcache2 250:2 0 50G 0 disk
vde 254:64 0 10G 0 disk
├─bcache0 250:0 0 50G 0 disk
└─bcache1 250:1 0 50G 0 disk

2.2 添加一塊後端設備(backing device)
命令:make-bcache -B [backing-device]

# make-bcache -B /dev/vdh
UUID: bd1bc116-6f39-401e-a328-3bc0af4ac8d1
Set UUID: cd86812e-d24c-46da-b949-683969b59575
version: 1
block_size: 1
data_offset: 16
接着看到對應的設備是/dev/bcache3

查看cache set uuid
# ls -la /sys/fs/bcache/
total 0
drwxr-xr-x 3 root root 0 May 22 17:23 .
drwxr-xr-x 6 root root 0 May 22 17:21 ..
drwxr-xr-x 7 root root 0 May 22 17:26 7681dbb3-6558-4e60-b062-5fbb648f6665
–w——- 1 root root 4096 May 2217:57 register
–w——- 1 root root 4096 May 2220:44 register_quiet

“attach”後端設備
命令:echo [cache set uuid] >/sys/block/bcache[N]/bcache/attach
attach之後,緩存設備就能夠對新加的後端設備緩存數據了。
# echo 7681dbb3-6558-4e60-b062-5fbb648f6665 >/sys/block/bcache3/bcache/attach


2.3 刪除一塊後端設備
1)detach backing device
命令:echo [cache set uuid] >/sys/block/bcache[N]/bcache/detach
detach後端設備後,對應的bcache設備還是存在的,只不過這個bcache設備是無緩存的,查看其狀態可以看到是no cache

比如刪除bcache3
# echo 7681dbb3-6558-4e60-b062-5fbb648f6665 >/sys/block/bcache3/bcache/detach
# cat /sys/block/bcache3/bcache/state
no cache

2)stop backing device
命令:echo 1 > /sys/block/bcache[N]/bcache/stop
detach後端設備後,對應的bcache設備還存在,如果要刪除,還需要stop該設備
# echo 1 > /sys/block/bcache3/bcache/stop
# ls /dev/bcache* -la
brw-rw—T 1 root disk 250, 0 May 22 17:51 /dev/bcache0
brw-rw—T 1 root disk 250, 1 May 22 17:54 /dev/bcache1
brw-rw—T 1 root disk 250, 2 May 22 20:42 /dev/bcache2


2.4 新增一塊緩存設備(caching device)
1)創建cache設備
命令:make-bcache -C [cache device]
有可能對應的設備已經有一些元數據,需要使用wipefs清理掉

# make-bcache -C /dev/vdf
Device /dev/vdf already has a non-bcache superblock, remove it using wipefs andwipefs -a
# wipefs -a /dev/vdf
4 bytes were erased at offset 0x27fff0000 (linux_raid_member)
they were: fc 4e 2b a9
# make-bcache -C /dev/vdf
UUID: 1f8bc71f-0106-4da5-b781-5de7b1517706
Set UUID: 7bfb0d17-b6d0-4fe9-942b-a1c75a0893ab
version: 0
nbuckets: 20480
block_size: 1
bucket_size: 1024
nr_in_set: 1
nr_this_dev: 0
first_bucket: 1


2)與bcache設備關聯
命令:echo [cache set uuid] >/sys/block/bcache[N]/bcache/attach
緩存設備需要與bcache設備關聯後,才能作爲對應bcache設備緩存。

# echo 7bfb0d17-b6d0-4fe9-942b-a1c75a0893ab >/sys/block/bcache3/bcache/attach

2.5 刪除cache設備
首先確保沒有backing device在使用它,上述的“刪除一塊後端設備”有說明如何設置取消後端設備對緩存設備的使用。
然後可以使用lsblk來查看是否有盤在引用它。
在在/sys/fs/bcache目錄下還有對應的cacheset uuid,unregister該set uuid後這個cache設備就被視爲刪除了。
命令:echo 1 > /sys/fs/bcache/[cache setuuid]/unregister

比如vde已經不作爲任何設備的緩存盤了,在/sys/fs/bcache目錄下有對應的cache set uuid
# ls /sys/fs/bcache/ -la
total 0
drwxr-xr-x 4 root root 0 5月 26 09:07 .
drwxr-xr-x 6 root root 0 5月 26 09:06 ..
drwxr-xr-x 7 root root 0 5月 26 09:077681dbb3-6558-4e60-b062-5fbb648f6665
drwxr-xr-x 7 root root 0 5月 26 09:077bfb0d17-b6d0-4fe9-942b-a1c75a0893ab
–w——- 1 root root 4096 5月 26 09:07 register

        

1.3 源碼模塊與接口說明

文件

作用

重要接口函數

函數說明

註釋

Super.c

驅動註冊 與bache初始化

bcache_init

bcache_exit

驅動註冊與卸載

 

register_bcache

Make-bcache的內核態實現

Bcache_init調用sysfs_create_files(bcache_kobj, files)註冊

register_bdev

註冊對block層的設備,該設備作爲最終的/dev/bcache

 

register_cache

註冊緩存設備

 

Request.c

實現對block層的訪問接口

cached_dev_make_request

處理block層的request

Bcache_init==>

bch_cached_dev_request_init

cached_dev_write

cached_dev_read

處理設備的讀寫

 

Sysfs.c

對用戶層的sys文件接口

bch_cached_dev_files

bch_cache_set_files

bch_cache_files

 

 

Closure.c

Closure用於維護對象的引用計數和回調完成

 

 

該模塊爲底層機制

Stats.c

 

包含一個timer用於時間統計

用於參數統計

 

Util.c

 

1. CRC

2.uuid

3. bch_bio_map

4.字符串處理

輔助函數

 

Util.h

 

Heap,

Fifo,

array

封裝了這3種數據結構

 

Alloc.c

Bucket的分配與回收管理

bch_bucket_alloc

bch_allocator_thread

桶分配,當剩餘量不足時啓動線程來分配

 

bch_bucket_free

回收桶,但不直接回收而是標記爲GCGC統一回收

 

bch_alloc_sectors

bkey分配新的桶,並更新bkey相關字段

 

Beset.c

Bkey的集合管理

bch_btree_iter_init

bch_btree_iter_next

bch_btree_iter_next_filte

Btreez結構中的bkey集合的訪問迭代器

該模塊實現了t->tree binary search點相關代碼目前還沒讀懂

bch_btree_sort_partial

Btreez結構中的bkey的排序

Extents.c

btreekey的訪問

bch_extent_keys_ops

頁節點操作集合

mca_alloc中賦值,操作包含合法性判斷,合併與排序

bch_btree_keys_ops

非頁節點操作結合

Io.c

對緩存設備與主設備的操作封裝

Bch_bio 開頭函數操作主設備

Bch_bbio開頭操作cache設備

 

該模塊爲底層機制,建立在bio機制上

Movinggc.c

Bucket回收管理

bch_moving_gc

根據bucket的標誌位做實際回收

 

Writeback.c

緩存寫回機制

bch_cached_dev_writeback_init

初始化, super.c調用

 

bch_writeback_thread

Writeback線程

 

 

 

bcache_dev_sectors_dirty_add

標記緩存設備的sectordirty

Extents調用該函數

Btree.c

Btree的建立,插入與替換操作,以及btree的垃圾標記

btree_gc_開頭函數爲gc相關

 

bch_gc_threadgc線程

bch_btree_insert_check_key

bch_btree_insert

節點插入操作

沒有直接的 delete操作,通過replace來實現key的替換

bch_btree_node_alloc

bch_btree_set_root

btree_node_free

Btree節點的分配與回收

 

bch_btree_map_keys

bkey查找,並執行響應操作

 

Journal.c

btree頁節點的操作做 journal管理用於減少插入時的非順序讀寫

bch_journal

btree添加時,調用該函數建立journal

 

bch_journal_replay

下次打開時對未處理的btree insert做重新提交操作

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章