清华课题 Octopus 源码分析(一)
前言
由于项目工作的需要,我们团队阅读了清华在文件系统方面的一个比较新颖的工作:Octopus。Octopus是一个基于持久内存 NVM 和远程直接内存访问 RDMA 技术的分布式内存文件系统。清华的陆游游老师现已将代码开源,可 点击此处 阅读。
这一工作中的是 ATC-17 (CCF A类),可 点击此处 阅读论文。
我们团队希望通过学习清华的这个优秀的同行工作,来进一步开展自己对于分布式持久内存文件系统的研究。关于论文的分析,虽然有做PPT给同伴们介绍过,但具体的博客分析可能会晚些才放上来。这一系列的内容主要是分析Octopus的源码设计(少许会结合论文内容来讲,希望有兴趣的同学可以自己先读一读),总结Octopus的框架、结构、设计组件及代码创新点等。
系列分析总共包括 个部分。第一部分是 论文摘要,相当于Octopus系统的一个简介;第二部分是 设计框架,在这一部分我们会宏观地介绍Octopus的组成体系及各部分的功能及相互间的联系;第三部分是 代码分析,也是本博客的重中之重。在这一部分我们首先介绍头文件体系(在include文件夹中),了解Octopus的存储结构,表结构,主要数据结构,内存池划分等等。接下来我们介绍方法实现代码(在src文件夹中),我们会通过比对头文件内的函数名称来看每一个方法是采用何种方式实现,好处是什么,取舍考虑是什么。进一步地,我们会通过代码文件间的依赖关系,函数依赖关系去深入探讨Octopus的创新性、局限性并留出进一步讨论的空间。
论文摘要
新型非易失内存 NVM 的出现和 RDMA 技术的兴起为高效存储和高速网络通信提供了机遇。现有的分布式文件系统没有很好地融合系统层和网络层的设计,从而产生了大量的软件开销,浪费了硬件本身的潜能。基于这一观察,研究者提出了一种新型的基于RDMA 与 NVM 的持久内存分布式文件系统,它重新设计了文件系统内部机制,核心思想是将 NVM 存储与 RDMA 通信两者的特征紧密地耦合起来,纳入一种统一的设计。对于数据操作,Octopus 利用共享持久内存池来减少数据拷贝过程,并且使用客户端的主动读写来减少服务器工作负载。对于元数据操作来说,Octopus 引入一种自识别远程过程调用 RPC 来减少文件系统层与网络层的通信延迟,并且实现了一种高效的分布式事务机制来维护一致性。实验表明,Octopus 在大 I/O 几乎能够取得接近网络原生带宽的性能,与其他分布式文件系统相比,Octopus也表现出极其优越的文件处理性能。
设计框架
Octopus的设计框架如图2所示。它有几个重要特点:
- 分布式数据存储:在Octopus上,所有文件数据是分布式存储的。而与传统的分布式文件系统不同的是,Octopus上不存在数据拷贝,即任意文件唯一地对应某一节点的某一地址。这种唯一性是通过哈希映射来实现的。Octopus使用一致性哈希来对文件数据进行布局,哈希映射的键是带路径文件名,值是节点。注意,这种数据分布方式可能使得目录与文件不在同一节点或物理相关区域,具有扁平化特性,与传统的 B 树结构区别很大。
- 共享内存池设计:Octopus将各个独立节点上的持久内存在整体上抽象为一个共享内存池。这种抽象之所以成立,是因为Octopus上不存在重复文件数据(或元数据),因此每个文件对象都是全局唯一的,在抽象成一个统一数据空间时访问不会造成混淆。这种共享内存池的好处是,使文件数据对用户和文件系统彻底透明,从而减少数据传输时的软件栈拷贝过程【见图4】。
- 私有及公有数据区分:Octopus 对于文件数据和元数据的存放方式不同,对于文件数据,设置为公有数据,也就是全局可见,这样做的好处是可以充分利用RDMA的原语特性,执行远程直读直写,提高性能;而文件元数据(包括文件系统元数据-超级块)则设置为私有,即仅存储该元数据的服务器节点可见,这是因为元数据表征的是文件的重要属性,对文件元数据的操作应该由具体的服务器来执行,从而保证安全性和系统数据一致性。
- 分布式事务机制:与传统的二阶段提交协议不同,Octopus 采用的是 Collect-Dispatch 的事务机制来保证一致性。简单来说,这一机制的特点是减少了参与事务的服务器节点的多次信息交互,而改为少量的集中式的数据交互。
结合图 2 举一个例子来说明 Octopus 的典型工作过程:加入我是一个用户,想在 home 目录下创建一个名为 a 的文件(或目录),那么具体的执行过程为:
- Octopus文件系统对以字符串 “/home/a” 为 key,做一致性哈希,将该文件分配到目标节点,假设该节点为 i 节点。
- i 号节点服务器在此节点的共享持久内存区写入文件数据,并将元数据信息(如创建时间,文件大小,用户名,权限等等)保存在私有持久区域。
- 若该文件变更涉及到其他依赖文件的变更(比如home目录元数据更新:文件数,大小,访问时间等),需要执行事务,则需进一步联络其他节点(home目录所在服务器节点,比如 j)执行 Collect-Dispatch 处理。
- 若以上步骤均成功,则返回给用户“创建文件成功”的消息(可显式或隐式)。
Octopus的数据布局如下图所示。由图可见,每个服务器节点上总共有六个组成部分:超级块,信息池,元数据索引区域,元数据区域,数据区域,日志区域。接下来我们分别介绍它们的功能:
- 超级块:用于保存文件系统元数据信息,如文件系统大小及规格等,常规数据。
- 信息池:用于保存 RDMA 网络通信的信息缓冲池。
- 元数据索引区域:用于定位文件元数据,基于桶哈希,可在节点内快速定位元数据位置。
- 元数据区域:用于保存文件元数据,如文件“/home/a”的元数据信息,包括文件所在具体位置的偏移。Bitmap 的功能是记录数据块的使用状态。
- 数据区域:用于保存文件数据,如文件“/home/a”的内容。Bitmap功能同上。
- 日志区域:用于保存文件事务的操作以便系统崩溃后执行 redo/undo 操作,又分为本地日志和分布式日志。
源码分析
(内容请见系列下一篇博客)