本文转载自微信公众号「新钛云服」,作者祝祥。转载本文请联系新钛云服公众号。
什么是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都可以在运行时进行修改。通过以下的命令可以知道当前的缓存模式:
- sudo cat /sys/block/bcache0/bcache/cache_mode
- writethrough [writeback] writearound none
更改cache_mode:
- sudo su - -c 'echo writethrough > /sys/block/bcache0/bcache/cache_mode'
- sudo 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,则可以如下进行测试。
系统更新,软件包安装:
- sudo apt-get update
- sudo apt-get upgrade
- sudo apt-get install bcache-tools
确认每块磁盘的用途:
- 系统将位于/dev/sda
- hdd硬盘(称为后端设备)将为/dev/sdb
- ssd(称为缓存设备)将为/dev/sdc。
在配置缓存之前,我们需要清理磁盘上的所有数据。
我们使用dd命令将磁盘的前4kB置0:
- sudo dd if=/dev/zero if=/dev/sdb bs=512 count=8
- sudo 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
在此设备上创建新文件系统:
- sudo mkfs.ext4 /dev/bcache0
警告! 您无法在/dev/bcache0上创建新分区,如果您需要在两个ssd和sata设备中同时做多个bcache设备,则需要先对普通磁盘进行分区,并使用分区作为后端和缓存设备来创建bcache设备。
现在您可以挂载bcache设备:
- sudo mkdir /media/bcache
- sudo mount /dev/bcache0 /media/bcache
您还必须将其添加到fstab中:
- sudo su - -c “/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设备
加载模块:
- sudo modprobe bcache
在每次启动时加载模块:
- sudo su - -c ‘echo bcache >> /etc/modules’
可选验证每个设备角色:
- sudo bcache-super-show -f /dev/sdb
- sudo bcache-super-show -f /dev/sdc
重新注册bcache设备:
- sudo su - - c ‘echo /dev/sdb > /sys/fs/bcache/register’
- sudo su - - c ‘echo /dev/sdc > /sys/fs/bcache/register’
现在您必须能够安装它:
- sudo mount /dev/bcacheX /media/bcache
删除bcache
测试之后,您可能想要恢复资源,这是删除bcache设备所需的操作:
Backup:
首先,您可能需要备份数据,因为您将删除所有内容。
Umount:
如果您的设备已安装,则现在更安全地进行安装。
- sudo umount -v /dev/bcache0
Stopping the bcache:
- sudo su - -c "echo 1 >/sys/fs/bcache/......../unregister"
- sudo su - -c "echo 1 >/sys/block/bcache0/bcache/stop"
- sudo wipefs -a /dev/sdX_caching
- sudo 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