Ceph开发每周谈Vol 4

2016年01月 · 麦子迈

这是Ceph开发每周谈的第四篇文章,记录从15年12月28号到16年1月3号的社区开发情况。笔者从前年开始做Ceph的技术模块分析到今年中告一段落,想必有挺多人期待下一篇Ceph技术分析。考虑到Ceph的发展已经从前年的一穷二白到现在的如火如荼,但对于社区的方向和实况仍有所脱节,笔者考虑开始Ceph开发每周谈这个系列。每篇文章都会综述上周技术更新,围绕几个热点进行深度解析,如果正好有产业届新闻的话就进行解读,最后有读者反馈问题的话并且值得一聊的话,就附上答疑部分。

上周综述

嗯,这周大家都休假。。。。

Encode/Decode

Ceph序列化(encode)与反序列化(decode)。Ceph作为一个存储系统,序列化是其中一个相当大的开销,包含磁盘和网络。Ceph序列化工作机制易于理解和扩展。

一个struct需要序列化,其序列化就是将其各个成员分别序列化(基于little-endian),而并不用去考虑struct中各个member间的padding字节。这种简单性考虑,出于考虑到跨平台间的复杂性。但是这样设计很难写出高效的代码,例如一个struct如果有几十个long类型的成员,那么分成几十遍去对各个成员进行序列化,这是非常低效的。优化的方案有两种:1、通过__attribute__ ((__packed__))指示编译器取消padding(这种可能导致在访问数据时速度下降),当然其实在 X86 和 ARM 架构下都不会有太多问题,但是像 MIPS 或者其他架构在寻址不对齐时效率时非常低的;2、通过对一个固定的字节的原生类型进行重新排序,使得不论在32bit和64bit机器上都没有padding(也即我们在定义结构的时候就有意的对结构进行排序),那么我们就可以对这些没有padding的成员进行批量地encode和decode。当然,作为另一个优化的难点是对非固定字节的成员(如STL和Hobject)进行encode,目前社区并没有太好的办法去优化。

本质上,解决问题的关键是在减少 STL,这个在 Jewel 的 CDS 就讨论过,未来需要序列化的结构尽量减少使用 STL。

RBD 的 NBD 实现

NBD是目前 Linux Kernel 很早的网络存储机制,基本可以把它理解为块接口的 FUSE,NBD 内核模块可以为远程的网络存储卷建立一个本地映射,如 /dev/nbd0,每次 IO 请求到这个设备时都会通过 TCP 发到服务器端来完成。按照 NBD 官方的意见,Linux 3.6 以上版本的 nbd 内核模块才会比较稳定(笔者还是很疑惑的,NBD在 kernel 2.5就进去了,过了10年还没稳定。。。)。而最近 Ubuntu Kylin 团队实现了 librbd on nbd 的实现,主要出于 rbd kernel module 不太稳定且在其他架构上有严重问题,同时又需要在 baremetal 上建立本地块设备,因此选择了 nbd 作为另一个实现方案。目前这个计划已经合并到社区,在下一个 release 就能看到 rbd-nbd 程序了,使用的方式与之前的 rbd map 挂载类似。