聲明:
- 文中 斜體帶下劃線 的段落為翻譯不夠準确的段落
- 原文:https://www.kernel.org/doc/Documentation/bcache.txt
- 官網:https://bcache.evilpiepirate.org/
什麼是bcache
bcache是linux核心塊層cache.它使用類似SSD來作為HDD硬碟的cache,進而起到加速作用。 HDD硬碟便宜并且空間更大,SSD速度快但更貴。如果能兩者兼得,豈不快哉?bcache能做到。
bcache使用SSD作為其他塊裝置cache.類似ZFS的L2Arc,但bcache還增加了寫回政策,并且是與檔案系統無關的。bcache被設計成隻需要最小的代價,無需配置就能在所有環境中工作。預設狀态下bcache不緩存順序IO,隻緩存随機讀寫。
bcache适用于桌面、伺服器,進階存儲陣列,甚至是嵌入式環境。設計bcache目标是讓被緩存裝置與SSD一樣快(包括緩存命中、緩存不命中、透寫和回寫)。現在還未達到初衷,特别是順序寫。同時測試結果表明離目标很接近,甚至有些情況下表現更好,例如随機寫。
bcache是資料安全的。對于寫回政策緩存來說,可靠性是非常重要的,出錯就意味着丢失資料。bcache是用電池備份陣列控制器的替代選擇,同時也要求bcache在異常掉電時也是資料安全的。對于寫而言,必須在所有資料寫到可靠媒體之後才能向上層傳回寫成功。如果在寫一個大檔案時掉電了,則寫入是失敗的。異常掉電資料安全是指 cache 中的髒資料是不會丢的,不像記憶體中的髒資料掉電就沒了。
bcache性能設計目标是等同于SSD.最大程度上去最小化寫放大,并避免随機寫。bcache将随機寫轉換為順序寫,首先寫到SSD,然後回寫緩存使用SSD緩存大量的寫,最後将寫有序寫到磁盤或者陣列上。對于RAID6陣列,随機寫性能很差,還要花費不菲的價格購買帶有電池保護的陣列控制器。現在有了bcache,你就可以直接使用linux自帶的優秀軟RAID,甚至可以在更廉價的硬體上擷取更高的随機寫性能。
特性:
1、一個緩存裝置可以作為多個裝置的緩存,并且可以在裝置運作時動态添加和删除緩存。
2、隻有當寫到磁盤後緩存才會确認寫完成。
3、正确處理寫阻塞和刷緩存
4、支援writethrough, writeback和writearound
5、檢測并避開順序IO(可配置關閉該選項)
6、當檢測到SSD延遲超過配置邊界值,減少到SSD流量(當一個SSD作為多個磁盤緩存時使用)
7、緩存不命中時預讀(預設關閉)
8、高性能的 writeback 實作:髒資料都是排序後再回寫。如果設定了 writeback 水位線,PD控制器會根據髒資料比例來平滑處理到背景writeback流量。
9、使用高效率的 B+樹,bcache随機讀可以達到1M IOPS
10、穩定
安裝
參考文檔
調優
1.Bcache 有一堆配置選項和可調參數,預設參數對于典型的桌面和伺服器工作負載是合理的,但是,當您在基準測試時,它們不是你想要獲得最佳參數
- Backing device 對齊
bcache中的預設(metadata)中繼資料大小為8k.如果你的 Backing device 是基于 RAID 的,那麼請務必使用`make-bcache --data-offset`将其與你的 RAID 條帶大小對齊(即設定為 raid 條帶大小的倍數)。--可避免寫放大
如果考慮未來RAID的擴充,則建議這樣計算data-offset的值
For example: If you have a 64k stripe size, then the following offset
would provide alignment for many common RAID5 data spindle counts:
64k * 2*2*2*3*3*5*7 bytes = 161280k
That space is wasted, but for only 157.5MB you can grow your RAID 5
volume to the following data-spindle counts without re-aligning:
3,4,5,6,7,8,9,10,12,14,15,18,20,21 ...
- 寫入性能差
預設 bcache 的 cache_mode 是 writeround,改成 writeback,提高寫入性能
echo writeback > /sys/block/bcache0/bcache/cache_mode
2.預設情況下,bcache不會緩存所有内容.它嘗試跳過順序的IO,因為你确實想要緩存随機的IO。
如果你複制一個10 GB的檔案,你可能也不希望将 cache 中 10 GB 的随機通路資料從緩存中重新整理走(cache 可用空間不夠時,根據 lru 算法将冷資料回寫到 backing device)。
例如:如果要對緩存進行基準讀取測試,使用 fio 設定一個8 GB的測試檔案,你需要禁用它:
echo 0 > /sys/block/bcache0/bcache/sequential_cutoff
調整 backing 裝置的連續 IO 門檻值,表示 bcache0 裝置的連續 IO 大于 4MB 時,大于 4MB 的部分不會走 SSD 裝置,也不會緩存到 ssd,而是直接讀寫 backing 裝置。(default:4M)
echo 4M > /sys/block/bcache0/bcache/sequential_cutoff
3. 如何防止 cache 裝置成為瓶頸
bcache會跟蹤每個IO,如果IO的時間超過門檻值,則旁路cache裝置,直接讀寫backing裝置。
如果你的SSD足夠強大,可以不跟蹤,減少跟蹤的開銷。
# echo 0 > /sys/fs/bcache/<cache set uuid>/congested_read_threshold_us
# echo 0 > /sys/fs/bcache/<cache set uuid>/congested_write_threshold_us
關閉旁路的另一個好處是,所有的離散讀寫都會經過cache裝置,進而不會導緻cache missing。
預設情況下當讀請求超過2ms,寫請求超過20ms時,旁路cache裝置。
The default is 2000 us (2 milliseconds) for reads, and 20000 for writes.
錯誤處理
Bcache嘗試透明地處理來自緩存裝置的 IO 錯誤,而不會影響正常操作;如果它看到太多錯誤(門檻值可配置,并且預設為0),它将關閉緩存裝置并将所有 backing device 切換到 writethrough 模式。
- 對于從緩存讀取,如果它們出現錯誤,将從 backing device 重新嘗試讀取
- 對于 writethroungh writes,如果寫入緩存錯誤,我們隻需切換到緩存中的 lba(Logical Block Address, LBA) 上使資料無效(即我們為繞過 cache write 做同樣的事情)
- For writethrough writes, if the write to the cache errors we just switch to invalidating the data at that lba in the cache (i.e. the same thing we do for a write that bypasses the cache)
- 對于 writeback writes,我們目前将該錯誤傳遞給檔案系統/使用者空間。這可以改進 - 我們可以嘗試繞過緩存的寫入,是以可心避免寫入錯誤。
- 對于分離操作,我們首先嘗試重新整理任何髒資料(如果我們以 writeback 模式運作)。但是,如果它無法讀取髒資料,它将不會做任何操作。
BACKING DEVICE
實際裝置目錄: /sys/block/<bdev>/bcache
以下目錄軟連結到實際裝置目錄:
/sys/block/bcache*/bcache
/sys/fs/bcache/<cset-uuid>/bdev*
attach
echo <cset-uuid> 到此檔案将緩存裝置連接配接到後端裝置
cache_mode
可以是writethrough,writeback,writearound或none之一
clear_stats
寫入此檔案将重置正在運作的總(total)統計資訊(不是 day/hour/5minute)
detach
寫入此檔案将從緩存集中分離.如果緩存中有髒資料,則會先重新整理
dirty_data
緩存中此 backing device 的髒資料量, cache 設定的版本不斷更新,但可能會稍微偏離
label
底層裝置名稱
readahead
應該執行的readahead的大小,預設為0.如果設定為1M,它會将cache未命中的資料讀取到 1M,但是沒有重疊現有的緩存條目
running
echo 1 可強制 bcache 在無 cache 的情況下運作
sequential_cutoff
一旦連續的 IO 大小越過此門檻值,它将繞過緩存;最近的128個IO被跟蹤,是以即使沒有一次完成,也可以檢測到連續的IO (default:4M)
sequential_merge
如果非零,bcache将送出的最後128個請求的清單與所有新請求進行比較,以确定哪些新請求是先前請求的順序連續,以确定順序截止.如果順序截止值大于任何單個請求的最大可接受順序大小,則這是必需的
state
backing device 可以處于四種不同狀态之一:
- no cache:從未附加到緩存集。
- clean:部分緩存集,且 cache 沒有髒資料。
- dirty:部分緩存集,且 cache 有髒資料。
- inconsistent:backing device 被使用者強制運作後 cache 中存在髒資料但緩存集不可用時;backing device 上的任何資料可能已損壞
stop
寫入此檔案以關閉 bcache 裝置并關閉 backing device
writeback_delay
當髒資料被寫入 cache 并且之前沒有包含任何資料時,在啟動回寫之前等待幾秒鐘。預設為30。
writeback_percent
bcache 試圖保持這個百分比的 cache 髒資料,并通過調節 writeback 及使用 PD 控制器來平滑調整速率 (default:10)
writeback_rate
每秒多少扇區的速度 - 如果 writeback_percent 不為0,則回寫被限制到指定速度。
由 bcache 連續調整,但也可由使用者設定
writeback_running
如果關閉,則不會發生髒資料的回寫,髒資料仍将被添加到緩存中,直到其将要滿時.僅用于基準測試。預設開啟 (default: on [on:1,off:0])
BACKING DEVICE 狀态統計:
實際裝置目錄下有狀态總計目錄(stats_total),以及一天(stats_day),1小時(stats_hour)和5分鐘(stats_five_minute)共四個目錄,其中目錄中的檔案含義分别如下:
bypassed
繞過緩存的 IO (讀取和寫入)量
cache_hits
cache_misses
cache_hit_ratio
在 bcache 來看,hit 和 miss 根據每個 IO 來計數,部分 hit 會被計為 miss
cache_bypass_hits
cache_bypass_misses
繞過緩存的 IO 的 hit 和 miss 的計數
cache_miss_collisions
cache miss 插入 cache 的執行個體計數,但是随着寫入和資料已經存在(通常為0,因為 cache miss 的同步被重寫)
原文:
Counts instances where data was going to be inserted into the cache from a cache miss, but raced with a write and data was already present (usually 0 since the synchronization for cache misses was rewritten)
cache_readaheads
預讀次數的計數
CACHE SET:
所在目錄:/sys/fs/bcache/<cset-uuid>
average_key_size # todo
btree中每個鍵的平均大小
bdev<0..n>
link 到每個附加的 backing device
ls -lrth 的結果
bdev0 -> ../../../devices/pci0000:00/0000:00:02.2/0000:04:00.0/host0/port-0:0/expander-0:0/port-0:0:6/end_device-0:0:6/target0:0:6/0:0:6:0/block/sdg/bcache
block_size
緩存裝置的塊大小
btree_cache_size
btree 緩存目前使用的記憶體量
bucket_size
buckets 大小
cache<0..n>
link 到 cache device 的真實裝置
cache0 -> ../../../devices/pci0000:00/0000:00:02.2/0000:04:00.0/host0/port-0:0/expander-0:0/port-0:0:5/end_device-0:0:5/target0:0:5/0:0:5:0/block/sdf/bcache
cache_available_percent
不包含髒資料的緩存裝置的百分比,并且可能被用于回寫。這并不意味着這個空間不用于清理緩存的資料;未使用的統計資訊(在priority_stats中)通常要低得多。
清除與此高速緩存關聯的統計資訊
在緩存中髒資料的量(在垃圾回收(gc)運作時将更新)
flash_vol_create
echo 一個大小到這個檔案,(以人類可讀的機關,k/M/G)建立一個由緩存集支援的精簡卷
io_error_halflife
io_error_limit
這些決定了在禁用緩存之前接受的錯誤數量,每個錯誤都會在半衰期之後衰減(在#ios中),如果衰減計數達到 io_error_limit,則會寫出髒資料,并禁用緩存
journal_delay_ms
日志寫入延遲幾毫秒,除非緩存重新整理發生得更早。預設值為100
root_usage_percent
正在使用的 root btree節點的百分比,如果這太高,節點會分裂,增加樹的深度。(default:2)
寫入此檔案以關閉緩存集,等待直到所有連接配接的後備裝置都已關閉
tree_depth
btree的深度(單節點btree的深度為0)(default:1)
unregister
分離所有 backing device 并關閉緩存裝置,如果存在髒資料,它将禁用回寫式緩存并等待它被重新整理
CACHE SET INTERNAL
所在目錄:/sys/fs/bcache/<cset-uuid>/internal/
此目錄也暴露出大量的内部操作的計時,具有平均持續時間,平均頻率,最後一個比對項和最大持續時間:垃圾收集,btree讀取,btree節點排序和btree分割
This directory also exposes timings for a number of internal operations, with separate files for average duration, average frequency, last occurrence and max duration: garbage collection, btree read, btree node sorts and btree splits.
active_journal_entries
比索引新的日志條目的數目
btree_nodes
btree中的總節點
btree_used_percent
btree在使用中的平均值
bset_tree_stats
關于輔助搜尋樹的統計
btree_cache_max_chain
btree節點緩存的哈希表中最長的鍊
cache_read_races
計數在從緩存讀取資料的情況下,桶被重用和無效 - 即在讀取完成後指針過期。發生這種情況時,資料将從後備裝置重新讀取
trigger_gc
寫入此檔案将強制運作垃圾回收
CACHE DEVICE:
<cdev>=cache裝置的真實裝置名
所在目錄: /sys/block/<cdev>/bcache
block_size
寫入的最小粒度應符合硬體扇區大小
btree_written
所有btree寫入的總和,(千/兆/千兆)位元組
bucket 大小
cache_replacement_policy
cache 重新整理政策,lru,fifo或random
discard
存儲SSD TRIM 開關的開啟與關閉狀态
- 延伸知識:在SSD上使用TRIM,預設是不開啟的 (固态硬碟(SSD)為什麼需要TRIM?,TRIM 的解釋檢視參考資料 Trim)
freelist_percent # 人為減小可以緩存的資料量
空閑cache的大小占總數的百分比。可以寫入來增加freelist上儲存的 bucket 數,這樣可以在運作時人為地減小緩存的大小。主要用于測試目的(即測試不同大小的緩存如何影響您的命中率),但是由于在移動到freelist之後丢棄了 bucket,是以也可以通過有效地給予更多的保留白間來使SSD的垃圾回收更容易。
io_errors
發生的錯誤數量,由 io_error_halflife 衰減
metadata_written
所有非資料寫入(btree寫入和所有其他中繼資料)的總和
nbuckets
此緩存中的總桶數
priority_stats
關于緩存中最近的資料被通路的統計資訊。這可以顯示您的工作集大小。
- Unused:是不包含任何資料的緩存的百分比
- Metadata:是bcache的中繼資料占的百分比
- Average:是 cache buckets 的平均優先級。
- Quantiles:是每個具有優先級門檻值的分位數的清單
- a list of quantiles with the priority threshold of each
written
已寫入高速緩存的所有資料的總和;與btree_written的比較獲得 bcache 實際的寫入增量