Ceph RocksDB 深度调优

本文深入探讨了 Ceph 的 BlueStore 和 RocksDB 的调优,详细介绍了历史背景、当前默认配置及潜在问题,并提供了一组新的调优候选方案。在测试中,新的调优配置在保持较低写入放大率的同时,显著提高了性能。特别是在 Ceph Pacific 版本的 RBD 和 RGW 测试中,新调优表现优秀,但压缩选项对 CPU 使用率和读取性能的影响值得注意。
摘要由CSDN通过智能技术生成

58e5817d583ea1cc4665c9c78841e510.gif

新钛云服已累计为您分享683篇技术干货

2819dde25e1ef3c4b9348573a35713f3.gif

介绍

调优 Ceph 可能是一项艰巨的挑战。在 Ceph、RocksDB 和 Linux 内核之间,实际上有数以千计的选项可以进行调整以提高存储性能和效率。由于涉及的复杂性,比较优的配置通常分散在博客文章或邮件列表中,但是往往都没有说明这些设置的实际作用或您可能想要使用或避免使用它们的原因。这种现象的一个特别常见的例子是调优 Ceph 的 BlueStore RocksDB。

本文档将尝试解释这些选项的实际作用以及您可能想要调整它们或保持它们默认值的原因。同时还将展示基于新版 Ceph 在几种不同配置下的最新性能结果

历史回溯

在过去的十年中,Ceph 的对象存储守护进程依赖于两个对象存储实现将用户数据写入磁盘。第一个(现已弃用)对象存储是 FileStore。

2016 年,我们开始编写一个名为 BlueStore 的新对象存储。

FileStore 使用现有的文件系统来存储对象数据,而 BlueStore 将对象数据直接存储在块设备上,并将对象元数据存储在 RocksDB 中。

在 BlueStore 开发过程的早期,我们观察到在 RocksDB 中存储元数据的开销会对性能产生巨大影响。

对于小型随机写入尤其如此,其中元数据几乎与对象数据一样大。在 2016 年秋天,我们开始调整 RocksDB,并重点关注对性能和写入放大有很大影响的 3 个设置:

  1. max_write_buffer_number  

    在 RocksDB 将键值对写入数据库之前,它会将它们写入预写日志,并将它们存储在称为 memtables 的内存缓冲区中。此设置控制可以在内存中累积的最大内存表数。

    请注意,此设置在整个数据库中不是全局的。相反,它应用于称为”列族“的单独数据库分区。最初编写 BlueStore 时,所有数据都存储在单个列族中。

    现在我们跨多个列族对数据进行分区,这可能意味着更多的内存缓冲区和数据,除非还应用了全局限制。

  2. write_buffer_size  

    在将内存表标记为不可变并将数据写入新内存表之前,可以将多少字节数据写入内存表。

  3. min_write_buffer_number_to_merge  

    在这些内存表被刷新到数据库的级别 0 之前需要填充的最小内存表数。

正如我们在 2016 年(https://drive.google.com/uc?export=download&id=0B2gTBZrkrnpZRFdiYjFRNmxLblU) 发现的那样,这些设置相互交互的方式对性能和写入放大有巨大影响。为简洁起见,我们将只关注我们运行的一小部分测试用例:

Max Write Buffer Number Min Write Buffer Number to Merge Write Buffer Size 4K Random Write IOPS Data Written to RocksDB
32 8 32MiB 64004 51569
32 1 32MiB 40256 118022
4 1 256MiB 62105 41374

大内存表通常比小内存表表现出更低的写入放大。如果使用小型内存表,则必须先累积几个内存表,然后再将它们刷新到数据库。每次刷新聚合大量小型 memtable 会导致性能小幅提升,但与使用大型 memtable 相比,会以额外的写入开销和驱动器磨损为代价。

出于这个原因,我们最终选择使用(最多)4 256MiB 内存表,这些内存表在满时会立即刷新。这些值作为 BlueStore 的 RocksDB 调优的一部分一直保留至今。

当前 Ceph

自从进行了最初的 RocksDB 测试以来,闪存驱动器变得更快了,BlueStore 发生了巨大变化,并且我们了解了更多关于 RocksDB 的使用如何影响性能的信息。

例如,BlueStore 不仅仅将对象元数据写入 RocksDB。它还存储内部 BlueStore 状态。这包括 pglog 更新、extents和磁盘分配等数据。其中一些数据的寿命很短:可能会被写入然后几乎立即删除。

RocksDB 处理这个问题的方式是首先将数据写入内存中的内存表,然后将其附加到磁盘上的预写日志中。当请求删除该数据时,RocksDB 会写入一个列族,指示应删除该数据。

当一次写入和随后的删除同时刷新时,只有最新的更新会保留在数据库中。但是,当这两个操作位于不同的刷新组中时(可能是因为使用了小型内存表),这两个操作可能会持久化到数据库中,从而导致写入放大增加和性能降低。

事实证明,这对我们在最初的 RocksDB 调优中看到更高的性能和更低的写入放大起到了重要作用。

随着时间的推移,其他各种 RocksDB 设置被调整或添加,最终导致 Ceph Pacific 的默认配置如下:

bluestore_rocksdb_options = compression=kNoCompression,max_write_buffer_number=4,min_write_buffer_number_to_merge=1,recycle_log_file_num=4,write_buffer_size=268435456,writable_file_max_buffer_size=0,compaction_readahead_size=2097152,max_background_compactions=2,max_total_wal_size=1073741824

附加选项总结如下:

  • compression = kNoCompression  

    不压缩数据库。由于担心 CPU 开销和延迟,在 bluestore 的开发过程中很早就被选中。

  • *recycle_log_file_num = 4  

    这个选项在 BlueStore 的开发早期就由 Sage Weil 提交给 RocksDB,以提高 WAL 写入的性能。不幸的是,在 2020 年,RocksDB 开发人员发现与他们的许多更强大的恢复模式一起使用并不安全。从RocksDB PR #6351(https://github.com/facebook/rocksdb/pull/6351)开始,RocksDB 本身通常会默认禁用此选项。

    Ceph PR #36579(https://github.com/ceph/ceph/pull/36579)尝试在 RocksDB 中切换到不同的恢复模式以重新启用日志文件的回收,但最终因不安全而被关闭。到目前为止,我们还没有删除这个选项,以防 RocksDB 开发人员找到一种在幕后重新启用它的方法,但现在这似乎不太可能。

  • writable_file_max_buffer_size = 0  

    在很旧的 RocksDB 版本中,WritableFileWriter 默认总是分配 64K 的缓冲区。Ceph 不需要或使用此内存,但在将数据写入 BlueFS 时必须复制它。

    RocksDB PR #1628(https://github.com/ceph/ceph/pull/36579)是为 Ceph 实现的,因此可以将初始缓冲区大小设置为小于 64K。

  • compaction_readahead_size = 2097152  

    这个选项是在Ceph PR #14932(https://github.com/ceph/ceph/pull/14932)中添加的,以大大提高压缩期间的性能。在设置此选项之前,CompactionIterator 将为每个 Next() 调用发出读取。因为读取是顺序的,所以 2MB

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值