什麼是Bcache?
HDD一般具有較大的容量,並且可以實現良好的順序讀和寫操作,但是在隨機寫和讀時非常慢,因此它們的IOPS級別較低;SSD具有非常好的整體性能,尤其是較高的IOPS,因此隨機寫入和讀取要比HDD更好,但是它們的容量卻很小。
Bcache是Linux內核塊設備層cache,支持多塊HDD使用同一塊SSD作爲緩存盤。它讓SSD作爲HDD的緩存成爲了可能。因此採用SSD作爲緩存,HDD作爲數據存儲盤,既解決了SSD容量太小,又解決了HDD運行速度太慢的問題。
圖片如今,一些SSD的順序讀寫性能也比單個HDD盤要好,但無法與某些SAS的RAID進行比較。儘管如此,SSD在隨機IO中表現仍然會更好。有一個可配置選項允許bcache也可以緩存順序的讀寫。
將來,將有可能在緩存設備上使用raid機制,以提高可靠性和性能。另外也可以通過與lvm的結合,提高容量與擴展性。
Bcache緩存模式
“writeback”:
最高性能的緩存模式。
寫入設備的數據首先寫入ssd,然後異步複製到後端設備,在SSD上覆制結束時,寫入就被視爲完成。爲了安全起見,此處的機制始終確保在將數據完全寫入後端設備(髒頁)之前,不認爲任何數據是安全的,因此,如果在SSD上仍存在數據時斷電,則在下次啓動時,數據將被推回支撐設備。這是使bcache能夠和軟件Linux Raid與具有BBU的硬件Raid設備一樣安全。
“writethrough”:
安全緩存模式。
寫入設備的數據將同時複製到ssd和HDD上,在HDD寫入結束時,寫入才被視爲完成。因此,這往往比“writeback”更爲安全,但缺乏一些性能。
“writearound”:
只讀緩存模式。
寫入設備的數據直接進入HDD,而根本不寫入SSD,因此不會對寫有任何性能提升。第一次讀取此數據時,將從HDD中讀取該數據。這樣做的好處是有更多空間用於緩存讀取,並減少了SSD的磨損。
“none” :
停用緩存功能(但/dev/bcache設備仍然可用)
所有這些caching_modes都可以在運行時進行修改。通過以下的命令可以知道當前的緩存模式:
# cat /sys/block/bcache0/bcache/cache_mode
# writethrough [writeback] writearound none
更改cache_mode:
# echo writethrough > /sys/block/bcache0/bcache/cache_mode
# cat /sys/block/bcache0/bcache/cache_mode
[writethrough] writeback writearound none
使用Bcache
Bcache可以在普通設備上使用,也可以在設備分區上使用。在本文中,我們將僅使用普通設備。
bcache需要的配置:
- Bcache是從Linux-3.10開始正式併入內核主線的,因此,要使用Bcache,需要將內核升級到3.10及以上版本纔行。(本文使用ubuntu 20.04)
- 固態硬盤
- 普通hdd硬盤
如果您使用的是Ubuntu 20.04,則可以如下進行測試。
系統更新,軟件包安裝:
# apt-get update
# apt-get upgrade
# apt-get install bcache-tools
確認每塊磁盤的用途:
- 系統將位於/dev/sda
- hdd硬盤(稱爲後端設備)將爲/dev/sdb
- ssd(稱爲緩存設備)將爲/dev/sdc。
在配置緩存之前,我們需要清理磁盤上的所有數據。
我們使用dd命令將磁盤的前4kB置0:
# dd if=/dev/zero if=/dev/sdb bs=512 count=8
# dd if=/dev/zero if=/dev/sdc bs=512 count=8
# wipefs -a /dev/sdb
# wipefs -a /dev/sdc
現在您可以創建bcache了:
# make-bcache -C /dev/sdc -B /dev/sdb
您還可以設置一些配置標誌,即:
# make-bcache -C /dev/sdc -B /dev/sdb --discard --writeback
參數說明:
- -C用於您的緩存設備(ssd)
- -B用於您的後端設備(hdd)
- --discard用於在ssd上使用TRIM,默認情況下未激活。
- --writeback使用緩存模式寫回,默認情況下它設置爲直寫。
如果操作系統在寫入新數據之前就擦除了未使用的空間,而不是在寫入時同時進行擦除,則可以提高文件保存性能。這種做法就是 TRIM。TRIM 命令本質上允許你的操作系統告訴驅動器哪些區域的數據不再使用,以便擦除它們,加快驅動器將來的寫入,可以 SSD 的用戶提供更佳的體驗。
在 Linux 中,fstrim 提供此功能,它可以爲寫入新數據而準備驅動器,並延長驅動器的使用壽命。由於在我使用的 Linux 發行版上 SSD 的 trim 不是自動的,所以必須去調度該操作,否則 SSD 的性能會隨着時間的推移而降低。
現在,您能夠列出您的設備:
# ls /dev/bcache*
/dev/bcache0
在此設備上創建新文件系統:
# mkfs.ext4 /dev/bcache0
警告! 您無法在/dev/bcache0上創建新分區,如果您需要在兩個ssd和sata設備中同時做多個bcache設備,則需要先對普通磁盤進行分區,並使用分區作爲後端和緩存設備來創建bcache設備。
現在您可以掛載bcache設備:
# mkdir /media/bcache
# mount /dev/bcache0 /media/bcache
您還必須將其添加到fstab中:
# /dev/bcache0 /media/bcache ext4 rw 0 0 >> /etc/fstab
警告! 如果您有多個bcache設備,則需要使用UUID。您可以通過執行以下操作來檢索bcache UUID:
# blkid /dev/bcacheX
然後在/etc/fstab中用UUID=YOUR_UUID_GIVEN_BEFORE替換/dev /bcacheX。確保在下一次重啓服務器之前,該配置已經配置完成
一些簡單的性能測試
我創建了一個Ubuntu 20.04虛擬機,該虛擬機僅使用openssh服務。此虛擬機在啓動時設置爲tar-gz根文件系統,然後自動關閉電源。
啓動的虛擬機vm的數量與當前CPU邏輯核數一樣多(12個)。他們在具有8GB內存的主機系統上消耗了6GB內存,而每個vm上的文件系統大小約爲1.4GB,因此通常系統緩存效果不會顯得太重要(除非激活了共享頁面)。
測試分爲兩個部分:
將基礎鏡像複製n份,並同時啓動n個vm,直到它們都關閉電源。
同時啓動n個虛擬機,直到它們全部斷電。
當測試檢查鏡像是否已經存在時,第一次運行的時間要長於下一個。
使用的啓動命令:
# kvm -m 512 -nographics -drive if=virtio,file=${BASE}${BASE_IMAGE} -net nic -net user -k fr --kernel $BASE/vmlinuz --initrd $BASE/initrd --append "root=/dev/vda1 nomodeset"
結果爲(僅兩次運行,可能需要更多運行才能得出平均值):
HDD only:
12個vms在硬盤上啓動:real 42m34.324s user 18m33.683s sys 4m20.040s
12個vms重新啓動硬盤:real 36m20.788s user 17m49.306s sys 3m23.770s
SSD only:
12個vm在ssd上啓動:real 6m22.430s user 20m39.627s sys 3m11.735s
12個vms重新啓動(ssd):real 3m35.279s user 19m21.430s sys 2m5.923s
Bcache writearound模式:
12個vms啓動:real 43m58.575s user 19m29.924s sys 4m39.586s
12個vms重啓:real 4m16.057s user 18m57.197s sys 2m8.818s
Bcache writethrough模式:
12個vms啓動:real 33m33.490s user 17m54.543s sys 3m56.084s
12個vms重啓:real 7m7.148s user 18m7.827s sys 2m26.736s
Bcache writeback模式:
12個vms啓動:real 21m37.536s user 17m4.371s sys 3m11.529s
12個vms重啓:real 3m58.942s user 18m30.382s sys 2m2.761s
恢復先前配置的bcache設備
加載模塊:
# modprobe bcache
在每次啓動時加載模塊:
# echo bcache >> /etc/modules
可選驗證每個設備角色:
# bcache-super-show -f /dev/sdb
# bcache-super-show -f /dev/sdc
重新註冊bcache設備:
# echo /dev/sdb > /sys/fs/bcache/register
# echo /dev/sdc > /sys/fs/bcache/register
現在您必須能夠安裝它:
# mount /dev/bcacheX /media/bcache
刪除bcache
測試之後,您可能想要恢復資源,這是刪除bcache設備所需的操作:
Backup:
首先,您可能需要備份數據,因爲您將刪除所有內容。
Umount:
如果您的設備已安裝,則現在更安全地進行安裝。
# umount -v /dev/bcache0
Stopping the bcache:
# echo 1 >/sys/fs/bcache/......../unregister
# echo 1 >/sys/block/bcache0/bcache/stop
# wipefs -a /dev/sdX_caching
# wipefs -a /dev/sdY_backing
ceph 中的Bcache
目前,在Ceph中使用SSD的主要方法有兩種:緩存分層和OSD緩存。衆所周知,Ceph的緩存分層機制尚未成熟,策略更加複雜,IO路徑更長。在某些IO場景中,它甚至可能導致性能下降,升級的粒度越大,也會帶來更多的負面影響。因此,在使用SSD時,我們選擇加速OSD所在的塊設備。在Linux內核塊層,SSD用於加速HDD塊設備。當前,更成熟的解決方案是:閃存,enhancedIO,dm-cache,bcache等。
在這些開放源代碼解決方案中,前三個高速緩存塊索引算法都相對相似,均基於哈希索引,並且主存儲數據塊到高速緩存塊使用組關聯映射方法。Bcache與其他方法之間的最大區別是,它使用相對標準的B +樹作爲索引,並且命中率將大大提高。同時,它在架構設計中考慮了SSD本身的某些特性,在充分發揮SSD的性能的同時,還保護了SSD的壽命,即它與SSD閃存介質具有良好的親和力。
Bcache的內部實現相對複雜,並且代碼複雜度遠高於flashcache/enhancedIO等,並且已經集成到內核的主線中。在高版本內核(4.8及更高版本)上,它仍然相對穩定和可靠,但是在Ceph For OSD加速中,仍有一些問題需要解決:
功能問題:
SSD和HDD不支持熱插拔
從緩存池中卸載HDD時,需要等待所有髒數據被刷新,這需要很長時間
當硬盤損壞時,無法刪除SSD中相應的髒數據,從而浪費空間
系統重啓後無法恢復精簡閃存卷
性能問題:
當上層中的大量隨機寫入IO充滿了緩存空間時,您必須等待所有髒數據被刷新,然後才能繼續爲寫入IO提供緩存
當GC線程運行時,它將導致業務IO的波動
Bcache元數據緩存會佔用大量內存。當系統內存不足時,無法緩存大量的元數據。需要從SSD讀取它並影響性能
使用方式:
當使用bcache加速ceph OSD時,我們採用以下的方式:
爲每個SSD創建一個緩存池,將相同數量的HDD附加到每個緩存池
從每個緩存池創建一個精簡閃存卷,以將每個OSD的OMAP目錄分離到其中
日記可以獨立放置到SSD中,也可以從緩衝池中創建多個精簡捲來寫入日記
通過大量的測試和分析,我們使bcache在ceph的生產環境中能夠穩定運行,這不僅可以最大化SSD的性能,而且可以延長SSD的使用壽命,節省用戶投資,併爲客戶提供更多成本有效的混合存儲解決方案。
參考文章:
https://wiki.ubuntu.com/ServerTeam/Bcache
https://titanwolf.org/Network/Articles/Article?AID=4fc8cd53-c4a2-450b-a01f-e92240850241#gsc.tab=0
https://gist.github.com/mikulely/e2931b7cce388dbff006622a3eef7b42