本文共 3435 字,大约阅读时间需要 11 分钟。
文件系统是计算机中一个非常重要的组件,为存储设备提供一致的访问和管理方式。在不同的操作系统中,文件系统会有一些差别,但也有一些共性几十年都没怎么变化:数据是以文件的形式存在,提供 Open、Read、Write、Seek、Close 等 API 进行访问;文件以树形目录进行组织,提供原子的重命名(Rename)操作改变文件或者目录的位置。
文件系统提供的访问和管理方法支撑了绝大部分的计算机应用,Unix 的“万物皆文件”的理念更是凸显了它的重要地位。然而,文件系统的复杂性使得它的可扩展性未能跟得上互联网的高速发展,极大简化的对象存储及时填补了空缺得以快速发展起来。因为对象存储缺乏树状结构也不支持原子重命名操作,跟文件系统有很大的差别,本文暂不讨论。
绝大多数文件系统都是单机的,在单机操作系统内为一个或者多个存储设备提供访问和管理。随着互联网的高速发展,单机文件系统面临很多的挑战:
随着互联网的高速发展,这些问题变得日益突出,涌现出了一些分布式文件系统来应对这些挑战。
GlusterFS 是由美国的 Gluster 公司开发的 POSIX 分布式文件系统(以 GPL 开源),2007 年发布第一个公开版本,2011 年被 Redhat 收购。它的基本思路就是通过一个无状态的中间件把多个单机文件系统融合成统一的名字空间(namespace)提供给用户。这个中间件是由一系列可叠加的转换器(Translator)实现,每个转换器解决一个问题,比如数据分布、复制、拆分、缓存、锁等等,用户可以根据具体的应用场景需要灵活配置。
GlusterFS 的优点是数据文件最终以相同的目录结构保存在单机文件系统上,不用担心 GlusterFS 的不可用导致数据丢失,没有明显的单点问题,可线性扩展,对大量小文件的支撑能力还不错。
它的挑战在于这种结构是相对静态的,不容易调整,也要求各个存储节点有相同的配置,当数据或者访问不均衡时没法进行空间或者负载调整。故障恢复能力也比较弱,比如 Server1 故障时,Server2 上的文件就没办法在健康的 3 或者 4 上增加拷贝保障数据可靠。
CephFS 始于 Sage Weil 的博士论文研究,目标是实现分布式的元数据管理以支持 EB 级别数据规模。2012 年,Sage Weil 成立了 InkTank 继续支持 CephFS 的开发,于 2014 年被 Redhat 收购。直到 2016 年,CephFS 才发布可用于生产环境的稳定版(CephFS 的元数据部分仍然是单机的)。现在,CephFS 的分布式元数据仍然不成熟。
Ceph 是一个分层的架构,底层是一个基于 CRUSH(哈希)的分布式对象存储,上层提供对象存储(RADOSGW)、块存储(RDB)和文件系统(CephFS)三个 API。CephFS 是由 MDS(Metadata Daemon)实现的,它是一个或者多个无状态的元数据服务,从底层的 OSD 加载文件系统的元信息并缓存到内存中以提高访问速度。MDS 是无状态的,可以配置多个备用节点来实现 HA,相对比较容易。不过备份节点没有缓存,需要重新预热,有可能故障恢复时间会比较长。
Google 的 GFS 是分布式文件系统中的先驱和典型代表,由早期的 BigFiles 发展而来。在 2003 年发表的论文中详细阐述了它的设计理念和细节,对业界影响非常大,后来很多分布式文件系统都是参照它的设计。GFS 的架构入下图所示。
GFS 有一个 Master 节点来管理元数据(全部加载到内存,快照和更新日志写到磁盘),文件划分成 64MB 的 Chunk 存储到几个 ChunkServer 上(直接使用单机文件系统)。文件只能追加写,不用担心 Chunk 的版本和一致性问题(可以用长度当做版本)。
出自 Yahoo 的 Hadoop 简直是 Google 的 GFS、MapReduce 等的开源 Java 实现版,HDFS 也是基本照搬 GFS 的设计,这里就不再重复了。下图是 HDFS 的架构图。
HDFS 的可靠性和可扩展能力还是非常不错的,有不少几千节点和 100PB 级别的部署,支撑大数据应用表现还是很不错的,少有听说丢数据的案例。HDFS 的 HA 方案是后来补上的,做得比较复杂,以至于最早做这个 HA 方案的 Facebook 在很长一段时间(至少 3 年)内都是手动做故障切换(不信任自动故障切换)。
MooseFS 是来自波兰的开源分布式 POSIX 文件系统,也是参照了 GFS 的架构,实现了绝大部分 POSIX 语义和 API,通过一个非常成熟的 FUSE 客户端挂载后可以像本地文件系统一样访问。MooseFS 支持快照,用它来做数据备份或者备份恢复等还是恢复方便的。
MooseFS 是由 C 实现的,Master 是个异步事件驱动的单线程,类似于 Redis。不过网络部分使用的是 poll 而不是更高效的 epoll,导致并发到 1000 左右时 CPU 消耗非常厉害。
上面说的 GFS、HDFS 和 MooseFS 都是针对自建机房这种软硬件环境设计的,将数据的可靠性和节点可用性合在一起用多机多副本的方式解决。但是在公有云或者私有云的虚拟机里,块设备已经是具有三副本可靠性设计的虚拟块设备,如果再通过多机多副本的方式来做,会导致数据的成本居高不下(实际上是 9 个拷贝)。于是我们针对公有云,改进 HDFS 和 MooseFS 的架构,设计了 JuiceFS,架构如下图所示。
简要介绍了下我所了解的几个分布式文件系统的架构,把他们按照出现的时间顺序放在下面的图里(箭头表示后参考了前者或者是新一代版本)。上图中上部分蓝色的几个文件下主要是给大数据场景使用的,实现的是 POSIX 的子集,而下面绿色的几个是 POSIX 兼容的文件系统。他们中以 GFS 为代表的元数据和数据分离的系统设计能够有效平衡系统的复杂度,有效解决大规模数据的存储问题(通常也都是大文件),有更好的可扩展性。这个架构下支持元数据的分布式存储的 Colossus 和 WarmStorage 更是具有无限的可扩展能力。
JuiceFS 作为后来者,学习了 MooseFS 实现分布式 POSIX 文件系统的方式,也学习了 Facebook 的 WarmStorage 等元数据和数据彻底分开的思路,希望为公有云或者私有云等场景下提供最好的分布式存储体验。
JuiceFS 使用公有云中已有的对象存储来替换 DataNode 和 ChunkServer,实现一个完全弹性的 Serverless 的存储系统。公有云的对象存储已经很好地解决了大规模数据的安全高效存储,JuiceFS 只需要专注元数据的管理,也大大降低了元数据服务的复杂度(GFS 和 MooseFS 的 master 要同时解决元数据的存储和数据块的健康管理)。
我们也对元数据部分做了很多改进,从一开始就实现了基于 Raft 的高可用。要真正提供一个高可用高性能的服务,元数据的管理和运维仍然是很有挑战的,元数据是以服务的形式提供给用户。因为 POSIX 文件系统 API 是应用最最广泛的 API,我们基于 FUSE 实现了高度 POSIX 兼容的客户端,用户可以通过一个命令行工具把 JuiceFS 挂载到 Linux 或者 macOS 中,像本地文件系统一样快速访问。
如果你手上有公有云账号,来 JuiceFS 注册一下,5 分钟就可以给你的虚拟机或者自己的 Mac 上挂载一个 PB 级容量的文件系统了。
转载地址:http://xgzlz.baihongyu.com/