Luminous 中的新增功能:BlueStore

sage

BlueStore 是 Ceph 的一种新的存储后端。它拥有更好的性能(写入速度大约快 2 倍)、完整的数据校验和以及内置压缩。它是 Luminous v12.2.z 中 Ceph OSD 的新默认存储后端,并且将在使用 ceph-disk、ceph-deploy 和/或 ceph-ansible 部署新 OSD 时默认使用。

有多快?

大致来说,BlueStore 比 FileStore 快两倍,并且性能更稳定,尾部延迟更低。

当然,实际情况要比这复杂得多

  • 对于大型写入,我们避免了 FileStore 所做的双重写入,因此速度可以提高两倍。
  • ……但许多 FileStore 部署将日志放在单独的 SSD 上,因此这种优势可能会被掩盖
  • 对于小型随机写入,即使与带有日志的 FileStore 相比,我们的表现也更好得多。
  • ……但如果使用的是 NVMe,情况就不太清楚了,因为 NVMe 通常不会在实际存储设备上出现瓶颈,而是在 CPU 上(测试仍在进行中)
  • 对于键/值数据,我们的表现明显更好,避免了在 FileStore 中可能出现的一些非常糟糕的行为。例如,对于某些 RGW 工作负载,我们发现写入性能提高了 3 倍!
  • 我们避免了 FileStore 中由于“拆分”而导致在用数据填满集群时出现的吞吐量下降。
  • 使用原始 librados 的小型顺序读取在 BlueStore 中较慢,但这似乎只影响微基准测试。这在某种程度上是故意的:BlueStore 没有实现自己的预读(因为所有位于 RADOS 之上的东西都有自己的预读),并且使用更高层接口(如 RBD 和 CephFS)进行的顺序读取通常效果很好。
  • 与 FileStore 不同,BlueStore 采用写时复制:RBD 卷或 CephFS 文件最近快照的性能会更好。

我们预计在未来几周内发布另一篇博文,其中包含一些实际数据,深入探讨 BlueStore 的性能。

也就是说,BlueStore 仍然是一个正在进行中的工作!我们继续识别问题并进行改进。这个第一个稳定版本是一个重要的里程碑,但绝不是我们旅程的结束——只是开始的结束!

方孔圆钉

Ceph OSD 执行两个主要功能:将数据通过网络复制到其他 OSD(以及随之而来的重新平衡、修复等),以及将数据存储在本地连接的设备(硬盘、SSD 或两者的组合)上。第二个本地存储部分当前由现有的 FileStore 模块处理,该模块将对象作为文件存储在 XFS 文件系统中。关于我们最终采用的精确架构和接口,有很多历史原因,但核心挑战是 OSD 是围绕事务性更新构建的,而这些更新在标准文件系统上实现起来既笨拙又不高效。

最终,我们发现 XFS 本身没有问题;它只是不适合这项工作。从今天的 FileStore 设计来看,我们发现它的大多数缺点都与适应我们的接口到 POSIX 所需的黑客行为有关,而不是与 Ceph 或 XFS 本身有关。

BlueStore 是如何工作的?

BlueStore 是我们内部 ObjectStore 接口的一个干净实现,从第一性原理出发,并受到我们期望的工作负载的驱动。BlueStore 构建在原始底层块设备(或块设备)之上。它嵌入了 RocksDB 键值数据库,用于管理其内部元数据。一个小的内部适配器组件 BlueFS 实现了一个类似文件系统的接口,该接口仅提供足够的功能,以便 RocksDB 能够存储其“文件”并与 BlueStore 共享相同的原始设备。

您会注意到旧的 FileStore 基于 OSD(例如,任何在 Luminous 之前使用 Ceph 部署的 OSD)和 BlueStore OSD 之间的最大区别在于分区和挂载点的外观。对于 FileStore OSD,您会看到类似的内容

$ lsblk … sdb      8:16   0 931.5G  0 disk ├─sdb1   8:17   0 930.5G  0 part /var/lib/ceph/osd/ceph-56 └─sdb2   8:18   0  1023M  0 part … $ df -h … /dev/sdb1       931G  487G  444G  53% /var/lib/ceph/osd/ceph-56 $ ls -al /var/lib/ceph/osd/ceph-56 … drwxr-xr-x 180 root root 16384 Aug 30 21:55 current lrwxrwxrwx   1 root root    58 Jun  4  2015 journal -> /dev/disk/by-partuuid/538da076-0136-4c78-9af4-79bb40d7cbbd …

也就是说,有一个小的日志分区(尽管通常这个分区位于单独的 SSD 上),数据目录中的日志符号链接指向单独的日志分区,以及一个包含所有实际对象文件的current/目录。df命令显示设备的使用情况。

由于 BlueStore 使用原始块设备,因此情况有所不同

$ lsblk … sdf      8:80   0   3.7T  0 disk ├─sdf1   8:81   0   100M  0 part /var/lib/ceph/osd/ceph-75 └─sdf2   8:82   0   3.7T  0 part … $ df -h … /dev/sdf1        97M  5.4M   92M   6% /var/lib/ceph/osd/ceph-75 … $ ls -al /var/lib/ceph/osd/ceph-75 … lrwxrwxrwx 1 ceph ceph   58 Aug  8 18:33 block -> /dev/disk/by-partuuid/80d28eb7-a7e7-4931-866d-303693f1efc4 …

您会注意到数据目录现在是一个只有 100MB 的小分区,其中只有几个文件,而设备的其余部分看起来像一个大型未使用的分区,数据目录中的block符号链接指向它。BlueStore 在这里放置所有数据,并使用 Linux 异步 libaio 基础设施直接对原始设备进行 IO(来自 ceph-osd 进程)。(您仍然可以使用标准的ceph osd df命令查看每个 OSD 的利用率,如果这是您所需要的。)

您不再能够像以前那样查看底层的对象文件,但有一种新的技巧可以“窥视幕后”查看每个 OSD 存储的内容,这适用于 BlueStore 和 FileStore 基于的 OSD。如果 OSD 已停止,您可以使用 FUSE 将 OSD 数据“挂载”为

$ mkdir /mnt/foo $ ceph-objectstore-tool --op fuse --data-path /var/lib/ceph/osd/ceph-75 --mountpoint /mnt/foo

如果 fuse 配置正确,也可以挂载在线 OSD(通过启用osd_objectstore_fuse配置选项,osd 数据目录中会出现一个fuse/目录),但这通常不建议这样做,就像不建议用户对 FileStore 基于的 OSD 目录中的文件进行任何更改一样。

多个设备

BlueStore 可以使用慢速和快速设备的组合,类似于 FileStore,但 BlueStore 通常能够更好地利用快速设备。在 FileStore 中,日志设备(通常放置在更快的 SSD 上)仅用于写入。在 BlueStore 中,所需的内部日志记录用于一致性要轻量得多,通常表现为元数据日志,并且仅在更快(或必要)时才记录小写入。快速设备剩余的部分可用于存储(和检索)内部元数据。

BlueStore 可以管理最多三个设备

  • 必需的main设备(block符号链接)存储对象数据和(通常)元数据。
  • 可选的db设备(block.db符号链接)存储(尽可能多的)元数据(RocksDB)。未放入其中的内容将回退到主设备。
  • 可选的WAL设备(block.wal符号链接)仅存储内部日志(RocksDB 的写前日志)。

通常的建议是,尽可能多地使用 SSD 空间用于 OSD,并将其用于block.db设备。使用 ceph-disk 时,可以通过 --block.db 参数实现

ceph-disk prepare /dev/sdb --block.db /dev/sdc

默认情况下,将在 sdc 设备上创建一个分区,该分区的大小为主设备大小的 1%。可以使用bluestore_block_db_size配置选项覆盖此设置。更奇特的情况是使用三个设备:一个主 HDD 用于主设备,SSD 的一部分用于 db 设备,以及一个较小的 NVDIMM 支持的设备用于 WAL。

请注意,随着我们将 BlueStore 支持添加到新的ceph-volume工具中(该工具最终将取代ceph-disk),您可能会看到一些变化。(我们预计在准备好时将所有新的 ceph-volume 功能回移植到 Luminous。)

有关更多信息,请参阅BlueStore 配置指南

内存使用情况

FileStore 的一个优点是它使用正常的 Linux 文件系统,这意味着内核负责管理用于缓存数据和元数据的内存。特别是,内核可以使用所有可用 RAM 作为缓存,并在需要内存时立即释放。由于 BlueStore 作为 OSD 的一部分在用户空间中实现,我们管理自己的缓存,并且可用的内存管理工具较少。

底线是,BlueStore 有一个bluestore_cache_size配置选项,用于控制每个 OSD 将用于 BlueStore 缓存的内存量。默认情况下,对于基于 HDD 的 OSD 为 1 GB,对于基于 SSD 的 OSD 为 3 GB,但您可以根据环境设置适当的值。(有关更多信息,请参阅BlueStore 配置指南。)

一个注意事项是,内存会计目前不完善:分配器(在本例中为 tcmalloc)在分配时会产生一些开销,堆可能会随着时间的推移而碎片化,并且碎片化会阻止一些已释放的内存返回到操作系统。因此,BlueStore(和 OSD)认为它正在使用的内存与进程实际消耗的内存(RSS)之间通常存在差异,大约为 1.5 倍。您可以通过比较 ceph-osd 进程 RSS 与ceph daemon osd.<id>dump_mempools的输出来看到这种差异。改进内存会计的准确性是一个正在进行中的项目。

校验和

BlueStore 计算、存储和验证其存储的所有数据和元数据的校验和。每次从磁盘读取数据时,都会使用校验和来验证数据是否正确,然后将其暴露给系统的其他部分(或用户)。

默认情况下,我们使用 crc32c 校验和。还有其他几个可用的(xxhash32、xxhash64),也可以使用截断的 crc32c(即仅使用 32 个可用位中的 8 或 16 位)来降低元数据跟踪开销,但代价是可靠性。也可以完全禁用校验和(尽管不建议这样做)。有关更多信息,请参阅文档中的校验和部分

压缩

BlueStore 可以透明地使用 zlib、snappy 或 lz4 压缩数据。默认情况下禁用此功能,但可以在全局范围内启用,针对特定池启用,或者在 RADOS 客户端提示数据可压缩时选择性地使用。有关更多信息,请参阅压缩文档

将现有集群转换为使用 BlueStore

后端选择是每个 OSD 的决定:单个集群可以包含一些 FileStore OSD 和一些 BlueStore OSD。升级后的集群将继续像以前一样运行,唯一的例外是新的 OSD 默认情况下将使用 BlueStore 部署。

大多数用户会对将他们现有的 OSD 转换为新的后端感兴趣。这本质上是一个重新配置每个 OSD 设备的过程,并让集群使用其现有的修复功能来复制数据。有几种安全的方法可以做到这一点(还有一些不太安全的方法)。我们创建了一个指南,其中记录了当前推荐的迁移过程。

结论

BlueStore 在性能、稳健性和功能方面比我们之前分层到现有文件系统的方法具有巨大的优势。我们控制了更大的存储堆栈,一直到原始块设备,从而提供了对 IO 流和数据布局的更大控制。这种变化带来了提高性能和功能的潜力,但也带来了安全管理数据的责任。我们对 BlueStore 在过去一年中的改进和测试中看到的可靠性和稳健性感到非常满意,并非常高兴地向 Luminous 版本的用户推荐它。