SIGMOD 2019 Paper 分布式元数据论文阅读笔记整理
问题
随着容器化和微服务的出现,越来越多的应用程序转移到容器化环境中。在每组容器上运行的微服务通常独立于本地磁盘存储,虽然将计算与存储脱钩允许更有效的扩展容器资源,但也带来了对单独存储的需求:(1)容器需要保存应用程序数据,即使在它们关闭之后,(2)不同的容器可能需要同时访问同一文件,(3)存储资源需要由不同的服务和应用程序共享。
挑战
为了实现容器的需求,通常通过容器存储接口(CSI)将现有的分布式文件系统带到云原生环境中,或者通过一些存储协调器(例如Rook)。但性能和可扩展性不足。
-
由于组合工作负载中文件大小不同,并且按随机或顺序的方式访问,现有文件系统很少同时支持大文件和小文件的存储。
-
现有文件系统采用相同的复制协议,无法为不同写入场景提供优化的复制性能。
-
大量客户端可能同时对文件进行大量访问,大多数文件操作需要更新文件元数据。因此,存储所有文件元数据的单个节点很容易成为性能或存储瓶颈[23,24]。可以通过使用单独的集群来存储元数据来解决这个问题,但需要在容量扩展期间重新平衡存储节点,这可能会显著降低读/写性能。
-
符合POSIX的文件系统接口可以极大地简化上层应用的开发,但POSIX I/O标准中定义的强一致语义会极大地影响性能。大多数文件系统通过提供宽松的POSIX语义来缓解这个问题,但同一文件的inode和dentry之间的原子性要求仍然会限制它们在元数据操作上的性能。
本文方法
本文提出了Chubao文件系统(CFS),用于大型容器平台的分布式文件系统。
-
通用和高性能存储引擎。在不同的文件访问模式下以优化的性能高效地存储大小文件。利用Linux[22]中的punch hole接口异步释放被删除的小文件占用的磁盘空间,大大简化了处理小文件删除的工程工作。
-
场景感知复制。基于不同的写入场景(即附加和覆盖)采用了两种强一致的复制协议来提高复制性能。
-
基于利用率的元数据放置。使用一个单独的集群来根据内存使用情况在不同的存储节点上存储和分发文件元数据,在容量扩展过程中不需要任何元数据再平衡。每次扩展都根据内存和磁盘利用率,创建一个新的元分区存储后续的元数据,因此扩展过程中没有再平衡。
-
宽松的POSIX语义和元数据原子性。提供符合POSIX的API,放松POSIX一致性语义以及同一文件的inode和dentry之间的原子性要求,为了更好地满足应用程序的需求并提高系统性能。
开源代码:https://github.com/cubefs/cubefs
与Ceph进行了全面的比较,实验结果表明,在测试7种常用的元数据操作时,CFS的性能平均提高了约3倍。此外,CFS在具有多个客户端和进程的高度并发环境中表现出更好的随机读/写性能。
元数据存储
元数据子系统由一组元数据节点组成,每个元数据节点可以有数百个元分区。每个元分区将来自同一卷的文件的inode和dentry存储在内存中,并使用两个名为inodeTree和dentryTree的b树进行快速查找。inodeTree由inode id索引,dentryTree由父inode id和dentry名称索引。
基于利用率的放置
在创建卷之后,客户端向资源管理器请求一定数量的可用元分区和数据分区,这些分区通常位于内存/磁盘利用率最低的节点上。在写入文件时,客户端以随机的方式从资源管理器分配的分区中选择元分区和数据分区。客户端不采用基于利用率的方法是为了避免与资源管理器通信,无需获得每个分配节点的最新利用率信息。
当资源管理器发现卷中的所有分区都将满时,它会自动向该卷添加一组新分区。这些分区通常位于内存/磁盘利用率最低的节点上。当分区已满,或者达到阈值(即,元分区上的文件数或数据分区上的扩展数据块数)时,尽管仍然可以修改或删除新数据,但无法在该分区上存储新数据。
元数据拆分
如果元分区即将达到其存储的inode和dentry数量的上限,则需要执行拆分,以确保存储在新分区中的inode id与存储在原分区中的索引节点id是唯一的。
资源管理器首先在上界end预先切断元分区的inode范围,该值大于使用的最大inode id(表示为maxInodeID),然后向元节点发送拆分请求,以(1)更新原始元分区的从1到结束的inode id范围,(2)创建一个新的元分区,其inode范围从结束+1到∞。结果,这两个元分区的inode范围分别变为[1,end]和[end+1,∞]。如果需要创建另一个文件,那么它的inode id将在原始元分区中被选择为maxInodeID+1,在新创建的元分区中选择为end+1。
实验
数据集:mdtest,fio(直接IO模式)
实验对比:IOPS
实验参数:元数据操作、进程数、客户端数、顺序/随机读/写、文件大小
总结
介绍为京东电子商务服务的分布式文件系统CFS。包括4个技术:(1)在不同的文件访问模式下高效地存储大小文件,利用Linux punch hole接口异步释放被删除的小文件占用的磁盘空间,简化了处理小文件删除的工程工作。(2)采用了两种基于不同写入场景的强一致复制协议(即附加和覆盖)来提高复制性能。(3)基于利用率的元数据放置。每次扩展都根据内存和磁盘利用率,创建一个新的元分区存储后续的元数据,因此扩展过程中没有再平衡。(4)放松POSIX语义和同一文件的inode和dentry之间的原子性,从而更好地满足应用程序的需求并提高系统性能。