Ceph性能:有趣的事情正在发生

Ceph开发者峰会已经结束了,哇!有很多好的东西即将到来!在这次在线活动中,我们讨论了Firefly版本的未来(计划于2014年2月发布)。在香港的OpenStack峰会上,我有机会与Sage讨论了一个可能进入Firefly的新功能。这也在CDS期间进行了讨论。他的计划是为filestore添加一个多后端功能。相信我,这肯定会将Ceph提升到一个新的水平。
I. 当前集成状态
在深入研究新的实现以及即将发生的变化之前,我想简要介绍一下Ceph的内部设计。详细的解释可以在图片下方找到。

I.1. 单次写入… ¶
Ceph是一种软件定义存储,这意味着数据的复制和可用性由软件智能提供和保证。我认为理解Ceph的内部工作方式(默认逻辑设计)非常重要。这里的关键点是向您展示在执行写入操作时会发生什么。因此,让我们以一个副本为2的单个对象写入为例。这将导致4个IO
- 客户端将请求发送到主 OSD
- 第一个IO写入Ceph日志
- 日志使用libaio并使用
O_DIRECT和O_DSYNC写入。写入使用writev()处理 - 第二个IO使用
buffered_io写入后端文件系统。写入使用writev()处理 - filestore在达到
filestore_max_sync_interval时调用syncfs并修剪日志,并在释放锁之前等待syncfs完成。
相同的过程重复到辅助OSD进行复制。
I.2. 关于日志 ¶
在上一段中,我提到一个日志,但它到底做什么?嗯,它做了许多事情,例如
- 确保数据和事务的一致性。它基本上充当传统的日志文件系统,因此可以在发生错误时重放内容。
- 提供原子事务。它跟踪已提交的内容和将要提交的内容。
- 写入日志是顺序进行的
- 作为FIFO工作
Ceph OSD守护程序停止写入并将日志与文件系统同步,允许Ceph OSD守护程序从日志中修剪操作并重用空间。
如果OSD文件系统是Btrfs或ZFS,则上述语句不适用。传统上,我们建议使用XFS或ext4作为OSD文件系统,这使得日志使用writeahead模式。我们先写入日志,然后写入后端文件系统。这与COW(Copy On Write)文件系统不同,使用writeparallel模式。我们同时写入日志和后端文件系统。
I.3. 设计缺陷 ¶
显然,您已经注意到使用writeahead模式执行的日志会造成巨大的性能损失,同时写入对象。由于我们写入两次,如果日志存储在与osd数据相同的磁盘上,这将导致以下情况
Device: wMB/s
sdb1 - journal 50.11
sdb2 - osd_data 40.25
传统的企业级SATA磁盘可以提供大约110 MB/sec的顺序写入IO模式。所以是的,基本上我们将IO分成两半。
为了避免(或隐藏)这种影响,有几种方法可以实现日志。
通常,Ceph日志只是文件系统上的一个文件(在/var/lib/ceph/osd/<osd-id>/journal下)。首先,这效率极低,因为文件系统开销很大,其次,我们确切地不知道日志放置在硬盘驱动器上的哪个位置(文件和块之间的相关性)。
另一种实现方法是在OSD数据磁盘的开头使用原始分区。基本上,您只需使用第一个扇区创建一个小的分区。由于我们位于设备的开头,我们可以确定这是磁盘上最快的区域。边缘总是更快,并且一旦机械臂靠近盘片中心,性能就会开始下降(这是一个众所周知的问题)。如果您不想为日志专门分配一个磁盘,这可能是使用日志的最佳方法。
然后,如果您想提高性能,可以使用单独的旋转磁盘。不幸的是,这不会表现得很好,因为磁盘将花费大部分时间在寻找写入的位置,因为并发的日志写入发生(多个日志写入)。
最后,实现日志的最佳方法是使用单独的SSD磁盘。这使您可以获得使用SSD的常见好处,例如:无寻道、快速顺序写入和快速访问时间。
II. Firefly:对象存储多后端
II.1. 上下文 ¶
当前,OSD具有一个通用的接口,称为ObjectStore,唯一的当前实现是FileStore。FileStore是Ceph中的一个逻辑实体,负责OSD数据。简而言之,对象被写入文件系统上的文件。通常,这发生在/var/lib/ceph/osd/<osd-id>/current/<pg-num>/目录中。任何文件系统层都会带来一些开销,这绝对是一个巨大的改进领域。我甚至会说这可能是分布式存储系统最后的明显瓶颈之一。
正在涌现许多新的键/值存储。键/值存储本质上是非常快的数据库。
可以区分两个级别的KVS
硬件键/值存储的另一个好处是它们甚至不在块层级别进行交互,而是直接与设备的内部数据结构进行交互。
请参阅下面的通用演变
| 类型 | 应用程序 | 访问方法 | 级别 | |
|---|---|---|---|---|
| 闪存盘 | 应用程序源代码将本机数据结构转换为块I/O | 传统I/O访问 | 块I/O | |
| 超越磁盘的闪存 | 应用程序源代码使用本机数据结构进行I/O | 增强型I/O | 原子IO事务 - 键/值事务 - 本机原语 | |
| 闪存作为内存 | 应用程序源代码操作本机内存数据结构 | 内存访问 | 扩展内存 - 持久内存 |
来自FusionIO关于闪存媒体优势的一些说明
- 98%的原始写入性能 更智能的媒体现在本机理解原子更新,没有额外的元数据开销。
- 闪存媒体寿命延长2倍,原子写入可以使闪存媒体寿命延长高达2倍,因为减少了写前日志和双写缓冲。
- 关键模块中的代码减少了50% 原子操作极大地减少了应用程序逻辑,例如作为解决方法构建的日志记录。
扩展FileStore对多个硬件KVS后端的支持将避免由文件系统产生的开销,因为filestore将直接与设备接口通信。拥有一个可插拔的FileStore将允许它与不同的API通信。显然,稍后可以实现各种专有解决方案。这只是编写后端的问题。
实现逻辑

II.2. 那么,什么会发生根本性的变化? ¶
II.2.1. 默认后端 ¶
在我看来,遗留的file后端可能会消失,转而支持levelDB或RocksDB。它已被提议用于Emperor。Haomai Wang最近在Ceph邮件列表上分享了一些实现方面的更新。第一个代码片段可以在他的Github上找到。LevelDB是一个用Google编写的快速键/值存储库,它提供从字符串键到字符串值的有序映射。
该项目提供了许多功能,例如
- 原子事务
- 可以一次性原子地进行多个更改。
LevelDB自Cuttlefish以来已经用于存储Monitor的数据。
II.2.1. 不再需要日志! ¶
日志是与FileStore实现紧密相关的遗留事物。如上所述,我们避免了文件系统开销。大多数KVS存储将处理事务,因此我们不再依赖日志来存储事务,而是依赖新的后端。
键/值DB具有事务参数,因此我们将事务原样从OSD传递给键/值存储。然后,它将确保事务是原子的。
这表明了一个巨大的设计改进。例如,副本计数为2的单个对象写入将导致两个IO,而不是以前的四个。
II.2.2. 性能提升 ¶
通过此实现,我们降低了一个数据路径级别,因此不可避免地会提高我们的性能。
感谢Haomai Wang,我们已经可以预览性能


总体性能高于FileStore,差异不是很大,但请记住这目前只是一个原型。
有关更多信息,请访问官方蓝图。
我对这个未来的实现感到非常兴奋。看起来Firefly版本的事情变得认真起来了。许多功能将包含在其中,例如擦除编码、分层和filestore多后端。请注意,Firefly可能是Ceph的第一个LTS(长期支持)版本!