TOCS 2022 Paper 分布式元数据论文阅读笔记整理
问题
传统上文件系统(FS)由操作系统内核中的驱动程序实现,但目前越来越多的FS,特别是用于云的DFS,其接口仅在用户空间中实现,以(1)隔离FS逻辑,(2)利用用户空间库,(3)用于快速FS原型制作。但用户空间的FS并不能保证在所有情况下都符合POSIX标准,或者由于进程在内核和用户空间的上下文切换而遭受相当大的性能损失,难以同时实现灵活性、效率、访存一致性。
现有工作使用以下方法提供用户空间FS接口:
-
用户空间FS库:通过编译时绑定到驱动程序API为FS提供接口。但不灵活,因为每个API都是唯一的,需要编译时绑定,且不一致,因为用户空间FS库不符合一致文件行为的标准。
-
LD_PRELOAD加载的库[96]:通过预加载具有相同接口的另一个库来转移通常由库(例如libc[51])包装的系统调用,从而重新定义系统调用包装器。但会受到不正确行为的影响,导致分布式环境中的故障(例如:数据丢失、级联错误、中断[14]),特别是对于继承了FD的文件(例如,Spark[99]通过FS在管理器和分支工作器之间传递数据)。
-
用户空间文件系统(FUSE)[48]:为用户空间FS驱动程序提供了一个通用接口,同时允许应用程序使用内核空间系统调用访问FS。但使用FUSE执行的FS访问会受其设计严重减慢速度[93]。
本文方法
本文提出了DEFUSE,一个用户空间FS的接口,提供快速访问、正确性、对应用程序少量修改。
-
绕过文件描述符(FD)查找。正常文件系统中,每次访问文件都需要首先查找文件描述符,但需要涉及用户空间和内核的切换。文章通过缓存FD,减少上下文切换数量,并确保FD由内核管理。
-
FD缓存。确保FD在fork/exec后继续保持正确的行为。利用共享内存,在进程结束前保存FD状态,并由其他进程继续使用,从而避免FD丢失。
-
用户空间分页。传统mmap请求映射文件到内存时,需要上下文切换且无法拦截。通过userfaulted管理用户空间的页错误,拦截mmap和munmap请求,并通过内存区域映射表存储拦截的内存空间,从而在用户空间处理页错误。
开源代码:https://github.com/jalembke/defuse
对各种工作负载的评估表明,DEFUSE将每个工作负载的等待上下文切换次数减少到平均9次,性能比现有接口提高了2倍,在某些情况下提高了10倍。
总结
针对用户空间文件系统接口的实现,现有方法如:用户空间库、LD_PRELOAD库、FUSE,难以实现灵活性、效率、访存一致性。本文提出DEFUSE,实现用户空间FS访问接口,包括3个技术:(1)绕过文件描述符(FD)查找,利用FD缓存,减少FD查找时上下文切换数量,并确保FD由内核管理。(2)FD缓存。利用共享内存,在进程结束前保存FD状态,并由其他进程继续使用,从而避免FD丢失。(3)用户空间分页。通过userfaulted管理页错误,拦截mmap和munmap请求,从而在用户空间处理页错误。