Bcache

出自 Arch Linux 中文维基

本文內容或本節內容已經過期。

原因: 請提供模板的第一個位置參數以概括原因。 (在Talk:Bcache討論)

本文或本章節的語言、語法或風格需要改進。參考:Help:Style

原因:包含個人主觀評價, see Help:Style.(在Talk:Bcache討論)

Bcache (block 緩存) 允許使用固態硬碟作為讀寫緩存(writeback模式)或者讀緩存(writethrough 或者 writearound模式)來為另一個 block 設備(通常是機械硬碟或硬碟陣列)加速。這篇文章會展示如何把 Bcache 作為根分區安裝 Arch Linux。如果要看對於 bcache 本身的介紹,請瀏覽 bcache 首頁。請一定要閱讀並參考 bcache 手冊。Bcache 從 Linux 內核 3.10 版本開始就已經併入 mainline,而 Arch Linux 的安裝盤自從 2013.08.01 版本開始就支持 bcache。

類似 Bcache 的還有 Facebook 的 Flashcache

本文或本章節的事實準確性存在爭議。

原因: Backwards incompatible changes to on-disk format for linux 3.18 appears to be false. bcache on-disk format changes have not yet landed upstream yet as of 3.19(在 Talk:Bcache 中討論)


Bcache 需要把後端設備格式化成 bcache block 設備。多數情況下,blocks to-bcache 可以用來做轉換。

警告: * 一定要先備份數據!
  • bcache-dev 分支正處於非常不成熟的開發階段。The on-disk format has undergone changes in 3.18 which are not backwards compatible with previous formats[1]. Note: This only applies to users who compile-in bcache-dev. The version built-in to the upstream Linux kernel is unaffected[2].
  • Bcache and btrfs could leave you with a corrupted filesystem. Please visit this post for more information. Btrfs wiki reports that it was fixed in kernels 3.19+ [3].

在現存的系統上配置bcache設備[編輯 | 編輯原始碼]

警告: make-bcache 不會 導入(import)一個現存的設備或分區——它會格式化它。請務必做好數據備份。

1. 從 AUR 安裝 bcache-toolsAUR

2. 創建一個後端設備(通常來說這是你的機械硬碟)。後端設備可以是整個設備、一個分區或者其他任何的block設備。這將會創建/dev/bcache0:

# make-bcache -B /dev/sdx1

3. 創建一個緩存設備(這通常是你的固態硬碟)。緩存設備可以是整個設備、一個分區或者其他任何的block設備:

# make-bcache -C /dev/sdy2

在這個例子裡,默認的block大小是512B、bucket大小是128kB。block的大小應該與後端設備的sector大小匹配(通常是512或者4k)。bucket的大小應該與緩存設備的擦除block大小匹配(以減少寫入放大)。例如,如果是一個4k sector的HDD和一個擦除block大小是2MB的SSD搭配,命令就應該是這樣的:

# make-bcache --block 4k --bucket 2M -C /dev/sdy2

4. 把緩存設備註冊到後端設備。為了找到它的cache set UUID,運行# bcache-super-show /dev/sdy2 | grep cset.uuid然後把它添加到bcache設備。Udev規則會在以後的重啟階段自動搞定這個,因此你只需要執行一次這個命令:

# echo cset.uuid > /sys/block/bcache0/bcache/attach

5. 更改你的緩存模式(如果你想要同時緩存讀和寫):

# echo writeback > /sys/block/bcache0/bcache/cache_mode

6. 如果你需要讓這個分區在initcpio的時候就已經可以使用(即,在系統啟動過程中需要用到它),你需要把'bcache'添加到/etc/mkinitcpio.conf文件裡:

/etc/mkinitcpio.conf
...
MODULES=(... bcache)
...
HOOKS=(... block ... bcache ... filesystems ...)
...

然後請重新生成initramfs鏡像:

# mkinitcpio -p linux

管理 Bcache[編輯 | 編輯原始碼]

1. 確認所有的東西都已經正確地配置了:

# cat /sys/block/bcache0/bcache/state

輸出的內容有以下可能:

  • no cache: 這代表你還沒有綁定緩存設備到你的後端設備上
  • clean: 這代表一切正常,緩存是clean的
  • dirty: 這代表一切正常,緩存模式被設置成了writeback,緩存是dirty的
  • inconsistent: 這代表問題很大,後端設備與緩存設備沒有同步

使用一個沒有緩存設備的 /dev/bcache0 的話所有的IO都會直接在後端設備上執行,等於pass-through模式。

2. 查看正在使用的緩存模式:

# cat /sys/block/bcache0/bcache/cache_mode
[writethrough] writeback writearound none

在這個示例中,輸出顯示當前使用的是writethrough模式。

3. 顯示bcached設備的信息:

# bcache-super-show /dev/sdXY

4. 停止後端設備:

# echo 1 > /sys/block/sdX/sdX[Y]/bcache/stop

5. 讓緩存設備脫機:

# echo 1 > /sys/block/sdX/sdX[Y]/bcache/detach

6. 安全移除緩存設備:

# echo <cache-set-uuid> > /sys/block/bcache0/bcache/detach

7. 釋放已連接的設備:

# echo 1 > /sys/fs/bcache/<cache-set-uuid>/stop

將系統安裝到一個 bcache 設備[編輯 | 編輯原始碼]

1. 從 Arch Linux 的USB安裝盤啟動 (至少是 2013.08.01 版本的)。

2. 從 AUR 安裝 bcache-toolsAUR

3. 對硬碟進行分區

注意: 雖然 Grub2 理論上不提供對 bcache 的支持,但是因為它完整支持 UEFI ,所以是有辦法啟動系統的。只要用來處理 boot 設備的模塊被正確編譯進內核或者包含在 initramfs 裡面,那麼就沒必要按照下面的例子單獨分區一個 boot 分區(第二行,名字是 arch_boot 的)。詳情參考 GRUBUEFI

grub 無法處理 bcache, 所以你需要至少兩個分區 (一個 boot 和一個作為 bcache 後端設備的分區). 如果你用的是 UEFI, 則額外需要 EFI system partition (ESP)。比如:

     1            2048           22527   10.0 MiB    EF00  EFI System
     2           22528          432127   200.0 MiB   8300  arch_boot
     3          432128       625142414   297.9 GiB   8300  bcache_backing
注意: 例子裡是沒有 swap 文件或分區的,如果要讓 swap 也受到 cache 設備緩存,使用步驟7裡面的 LVM 來實現。如果不需要 swap 被緩存,請在這一步就創建 swap 分區。

4. 配置你的機械硬碟作為 bcache 後端設備。

# make-bcache -B /dev/sda3
注意:
  • 在配置啟動盤的時候,一定要明白自己在做什麼——多看幾次你選擇的 boot-loader/boot-manager 的文檔,想想它和 bcache 一起用會不會有兼容性問題。
  • 如果所有相關的設備都通過下面這樣的命令連接起來的話,bcache 會自動把緩存設備連接到後端設備,步驟5就可以跳過。# make-bcache -B /dev/sd? /dev/sd? -C /dev/sd?

現在你有了一個 /dev/bcache0

5. 配置固態硬碟。

下面這個例子是把整個固態硬碟(/dev/sdb)作為緩存設備格式化,並連結到後端設備:

# make-bcache -C /dev/sdb
# echo /dev/sdb > /sys/fs/bcache/register 
# echo 前面的命令输出的UUID > /sys/block/bcache0/bcache/attach
注意: 如果忘了 UUID 是什麼,可以用 ls /sys/fs/bcache/ 命令找到(如果緩存設備成功連結),最長的那一串東西就是 UUID。

6. 格式化 bcache 設備。如果你要在 /dev/bcache0 裡面分區的話,用 LVM 或者 btrfs 的 子捲來實現,比如下面的例子用 btrfs 的子卷功能分了 //home 兩個區:

# mkfs.btrfs /dev/bcache0
# mount /dev/bcache0 /mnt/
# btrfs subvolume create /mnt/root
# btrfs subvolume create /mnt/home
# umount /mnt

你甚至可以配置 LUKS 如果你想要用類似 cryptsetup 的東西。把內核 option 'cryptdevice' 指向 bcache 設備是沒有問題的。

7. 配置安裝掛載點(這裡用的是步驟3的分區方案和步驟6的btrfs子卷分區方案):

# mkfs.ext4 /dev/sda2 (arch_boot 分区)
# mkfs.msdos /dev/sda1 (如果你的 ESP 分区有至少 500MB,请用 mkfs.vfat 命令来创建一个 FAT32 分区)
# pacman -S arch-install-scripts
# mount /dev/bcache0 -o subvol=root,compress=lzo /mnt/ (挂载btrfs的root子卷作为根目录)
# mkdir /mnt/boot /mnt/home
# mount /dev/bcache0 -o subvol=home,compress=lzo /mnt/home (挂载btrfs的home子卷作为home目录)
# mount /dev/sda2 /mnt/boot
# mkdir /boot/efi
# mount /dev/sda1 /mnt/boot/efi/

8. 按照 Installation Guide 的步驟安裝系統,除了下面這個:

在修改 /etc/mkinitcpio.conf 並運行 mkinitcpio -p linux 之前:

  • 在新系統上,從 AUR 安裝 bcache-toolsAUR
  • 修改 /etc/mkinitcpio.conf:
    • 添加 bcache 到 MODULES=() 裡面
    • 添加 bcache 到 HOOKS=() 的 block 和 filesystems 之間
注意: 因為安裝介質不會儲存任何更改,所以如果你想在重啟之後再在安裝介質裡打開bcache的後端設備,你需要手動註冊它。首先確認 bcache 模塊已經加載,然後把相關的設備都 echo 到 /sys/bcache/register。可以通過 dmesg 來檢查是否已經成功註冊。

從安裝盤訪問bcache分區[編輯 | 編輯原始碼]

要訪問一個在安裝盤啟動之前就已經存在的 bcache 分區,首先從 AUR 安裝 bcache-toolsAUR,然後加載 bcache 模塊:

# modprobe bcache

然後強制內核重新加載分區表:

# partprobe

現在 /dev/bcache* 應該會存在了,掛載、格式化之類的操作也可以進行了。

配置[編輯 | 編輯原始碼]

可以配置的選項有很多,比如緩存模式、緩存寫入時間間隔、啟發式順序寫入等。通過寫入 /sys/block/bcache[0-9]/bcache 目錄中的對應文件可以進行相應的配置,詳情查看 bcache 用戶文檔

例如,改變緩存模式通過以下命令實現:

echo 'writethrough' > /sys/block/bcache[0-9]/bcache/cache

可以把 'writethrough' 換成 'writeback', 'writearound' 或者 'none' 中的任意一個。

注意: 寫入 /sys 的設置有些是臨時的,重啟之後就會失效(緩存模式的更改不會失效)。如果要「模擬」永久更改,在 /etc/tmpfile.d 目錄中創建包含類似下面的內容的 .conf 文件:
/etc/tmpfile.d/my-bcache.conf
w /sys/block/bcache0/bcache/sequential_cutoff - - - - 1M
w /sys/block/bcache0/bcache/cache_mode        - - - - writeback

在這個例子中該文件會在系統啟動時把 sequential cutoff 設置為1M、cache mode 設置為 writeback。

高級操作[編輯 | 編輯原始碼]

調整後端設備的容量[編輯 | 編輯原始碼]

It is possible to resize the backing device so long as you do not move the partition start. This process is described on the mailing list. Here is an example using btrfs volume directly on bcache0. For LVM containers or for other filesystems, procedure will differ.

擴容舉例[編輯 | 編輯原始碼]

In this example, I grow the filesystem by 4GB.

1. Reboot to a live CD/USB Drive (need not be bcache enabled) and use fdisk, gdisk, parted, or your other favorite tool to delete the backing partition and recreate it with the same start and a total size 4G larger.

警告: Do not use a tool like GParted that might perform filesystem operations! It will not recognize the bcache partition and might overwrite part of it!!

2. Reboot to your normal install. Your filesystem will be currently mounted. That is fine. Issue the command to resize the partition to its maximum. For btrfs, that is

# btrfs filesystem resize max /

For ext3/4, that is:

# resize2fs /dev/bcache0

縮容舉例[編輯 | 編輯原始碼]

這裡舉例的是縮小4G容量。

1. 切換緩存模式,從 writeback 改成 writethrough,並等待緩存寫入後端設備。

# echo writethrough > /sys/block/bcache0/bcache/cache_mode
$ watch cat /sys/block/bcache0/bcache/state

請等到第二個命令輸出 "clean"。

強制把緩存寫入後端設備[編輯 | 編輯原始碼]
 # echo 0 > /sys/block/bcache0/bcache/writeback_percent

這會把緩存比例改成0,從而強制把緩存的內容寫入到後端設備。

然後把緩存比例改回來:

 # echo 10 > /sys/block/bcache0/bcache/writeback_percent

2. 為了避免之後縮小分區的時候不會破壞文件系統,請把文件系統縮小比想要縮小的大小更多的量。比如例子裡要把分區縮小4G,那就要把文件系統縮小5G以避免破壞了文件系統。如果用的是 btrfs,用下面的命令來縮小文件系統:

# btrfs filesystem resize -5G /

對於 ext3/4,用的命令是 resize2fs,但是需要目標文件系統沒有處於掛載:

$ df -h /home
/dev/bcache0    290G   20G   270G   1% /home
# umount /home
# resize2fs /dev/bcache0 283G

3. 重啟到 LiveCD/USB盤 (並不需要支持 bcache) 並使用 fdisk、gdisk、parted或者其他你用得順手的工具去把後端分區刪掉並重新創建一個 start 位置一樣的、但是總大小少4G的分區。

警告: 不要使用類似 Gparted 的工具,因為它們會進行文件系統操作!它們可能識別不出來 bcache 分區並破壞它!

4. 重啟到原來的系統,現在你的文件系統會掛載好,並且分區已經縮小了4G。現在要做的是把文件系統擴展到分區的大小。對於 btrfs,命令是:

# btrfs filesystem resize max /

對於 ext3/4:

# resize2fs /dev/bcache0

5. 把緩存模式重新改成 writeback (如果你想用 writeback 的話):

# echo writeback > /sys/block/bcache0/bcache/cache_mode
注意: 如果你夠小心,第二步裡面文件系統可以剛好縮小4G而不預留更多的空間,但是很多分區工具並不是按照字面意思來工作的,它們會把分區的起始和終止位置對齊到底層硬碟的 sector 邊界,所以就會出現意料之外的文件系統破壞事故。小心為妙。

疑難解答[編輯 | 編輯原始碼]

啟動時 /dev/bcache 不存在[編輯 | 編輯原始碼]

如果你在啟動時見到下面的提示信息並進入了busybox shell:

ERROR: Unable to find root device 'UUID=b6b2d82b-f87e-44d5-bbc5-c51dd7aace15'.
You are being dropped to a recovery shell
    Type 'exit' to try and continue booting

可能是因為後端設備設置成了"writeback"模式 (默認是 writearound)。在"writeback"模式下 /dev/bcache0 在緩存設備註冊並連接之前是不存在的。註冊(register)是每次啟動時需要進行的操作,但是連接(attach)只需要進行一次。

To continue booting, try one of the following:

  • Register both the backing device and the caching device
# echo /dev/sda3 > /sys/fs/bcache/register
# echo /dev/sdb > /sys/fs/bcache/register

If the /dev/bcache0 device now exists, type exit and continue booting. You will need to fix your initcpio to ensure devices are registered before mounting the root device.

注意:
  • An error of "sh: echo: write error: Invalid argument" means the device was already registered or is not recognized as either a bcache backing device or cache. If using the udev rule on boot it should only attempt to register a device if it finds a bcache superblock
  • This can also happen if using udev's 69-bcache.rules in Installation's step 7 and blkid and bcache-probe "disagree" due to rogue superblocks. See bcache's wiki for a possible explanation/resolution.
  • Re-attach the cache to the backing device:

If the cache device was registered, a folder with the UUID of the cache should exist in /sys/fs/bcache. Use that UUID when following the example below:

# ls /sys/fs/bcache/
b6b2d82b-f87e-44d5-bbc5-c51dd7aace15     register     register_quiet
# echo b6b2d82b-f87e-44d5-bbc5-c51dd7aace15 > /sys/block/sda/sda3/bcache/attach

If the /dev/bcache0 device now exists, type exit and continue booting. You should not have to do this again. If it persists, ask on the bcache mailing list.

注意: An error of sh: echo: write error: Invalid argument means the device was already attached. An error of sh: echo: write error: No such file or directory means the UUID is not a valid cache (make sure you typed it correctly).
  • Invalidate the cache and force the backing device to run without it. You might want to check some stats, such as "dirty_data" so you have some idea of how much data will be lost.
# cat /sys/block/sda/sda3/bcache/dirty_data
-3.9M

dirty data is data in the cache that has not been written to the backing device. If you force the backing device to run, this data will be lost, even if you later re-attach the cache.

# cat /sys/block/sda/sda3/bcache/running
0
# echo 1 > /sys/block/sda/sda3/bcache/running

The /dev/bcache0 device will now exist. Type exit and continue booting. You might want to unregister the cache device and run make-bcache again. An fsck on /dev/bcache0 would also be wise. See the bcache documentation.

警告: Only invalidate the cache if one of the two options above did not work.

/sys/fs/bcache/ 不存在[編輯 | 編輯原始碼]

當前嘗試啟動的內核不支持bcache或者bcache內核模塊未加載

參考資料[編輯 | 編輯原始碼]