bcache: SSD-Caching für (rotierende) Festplatten

Ich hatte neulich privat das Bedürfnis, eine größere Menge an VMs mit etwas größerem Bedarf an Plattenplatz abzubilden. Glücklicherweise hatte ich meinen alten Desktop-PC noch nicht weggeworfen, und da die Maschine viel RAM und eine große 2TiB-SATA-Festplatte verbaut hatte dachte ich mir, das wäre doch ein geeigneter Kandidat. Ich riss dann noch kurz die NVidia GPU heraus (um Strom zu sparen), klebte die Slotblenden zu und installierte das Betriebssystem.

Oh Graus! Nach all der Zeit, in der ich entweder mit SSDs oder mit Serverhardware zu tun habe kam mir der I/O auf die Festplatte unerträglich langsam vor. Bei der Installation der ersten VMs riss mir dann der Geduldsfaden und ich habe mir überlegt, wie ich das erträglich gestalten könnte, ohne mich in Unkosten zu stürzen.

Zu meinem Glück habe ich recht schnell und günstig eine alte, aber kaum gebrauchte SSD mit ~120GiB Kapazität abgegriffen. Sprich, zumindest das System selbst und die Disk-Images für die VMs, auf denen keine Daten liegen, wären damit bedient gewesen. Dummerweise war es aber unabdingbar, dass die VMs eine größere Menge Plattenplatz brauchten. Was also tun?

Die Lösung war dann ganz einfach und nennt sich bcache. Vereinfacht gesagt wird dabei die SSD als Cache (lesend wie schreibend) für die rotierende Platte benutzt. Die Software ist dabei schlau genug, sequentielle Zugriffe direkt durchzureichen und zufällige I/Os vor dem Wegschreiben auf Platte neu zu sortieren.

Und wie immer war Arch Linux auch diesmal unglaublich stressfrei: Zur Installation musste ich lediglich das AUR-Paket bcache-tools bauen, so dass ich es dann während der Arch Linux-Installation kopieren konnte. Das Bauen geht wie gewohnt einfach mit

pacman -S base-devel # falls noch nich installiert
git clone https://aur.archlinux.org/bcache-tools.git
cd bcache-tools
makepkg -sr

Verfügbar macht man das in der ArchISO-Umgebung dann mit:

pacman -Sy
pacman -U /path/to/bcache-tools-<VERSION>.pkg.tar.xz

Bcache kennt sog. backing devices , auf denen die Daten gespeichert werden, und caching devices, also die SSD-Caches. Ich habe mich während der Installation für die Variante entschieden, LVM auf das bcache-Device zu setzen:

make-bcache -B /dev/sdb1 -C /dev/sda2
pvcreate /dev/bcache0
vgcreate playground /dev/bcache0
# und ganz normal weiter mit der Installation

Bei sdb1 handelte es sich um eine Partition auf der rotierenden Festplatte, und sda2 war die dafür vorgesehene Partition auf der SSD (Typ der Parition ist übrigens egal). Vielleicht als Hinweis: Ich habe das /boot-Filesystem auch auf die SSD gelegt (EFI-Partition auf sda1), und am Ende der SSD ungefähr 20GiB frei gelassen (SSD Overprovisioning, keine Ahnung, ob es das nach braucht. Man kann bcache beibringen, immer einen Discard-Befehl an die SSD zu senden, wenn ein Block gelöscht wird, aber das war in meinen Tests dann langsamer).

Bevor man die initrd erstellt muss man nur in der /etc/mkinitcpio.conf noch eintragen, dass das Modul bcache bei Starten geladen und der gleichnamige Hook ausgeführt wird:

MODULES=(bcache)
HOOKS=(...block bcache lvm2 filesystems...)

Generell ist es egal, was man da noch an Zwischenschichten einzieht, mit verschlüsselter Platte wäre es dann halt:

# add keyboard, keymap and encrypt hooks (for umlaut passwords!)
HOOKS=(...keyboard keymap block bcache encrypt lvm2 filesystems...)

Den Cache-Mode habe ich direkt auf writeback gestellt, da mich ein Datenverlust im privaten Bereich nicht so wirklich interessiert (und bei einem Spielsystem schon gleich zweimal nicht). Das ganze geht via sysfs, also z.B. ein File namens /etc/tmpfiles.d/bcache.conf mit folgendem Inhalt anlegen:

w /sys/block/bcache0/bcache/cache_mode - - - - writeback

Ich bin von der Performance und der Einfachheit, mit der das ganze funktioniert hat, wirklich beeindruckt :-)