动手点关注 干货不迷路 👆
背景介绍
在一个典型的分布式文件系统中,目录文件元数据操作(包括创建目录或文件,重命名,修改权限等)在整个文件系统操作中占很大比例,因此元数据服务在整个文件系统中扮演着重要的角色,随着大规模机器学习、大数据分析和企业级数据湖等应用,分布式文件系统数据规模已经从 PB 级到 EB 级,当前多数分布式文件系统(如 HDFS 等)面临着元数据扩展性的挑战。
以 Google、Facebook 和 Microsoft 等为代表的公司基本实现了能够管理 EB 级数据规模的分布式文件系统,这些系统的共同架构特征是依赖于底层分布式数据库能力来实现元数据性能的水平扩展,如 Google Colossus 基于 BigTable,Facebook 基于 ZippyDB,Microsoft ADLSv2 基于 Table Storage,还有一些开源文件系统包括 CephFS 和 HopsFS 等也基本实现了水平扩展的能力。
这些文件系统实现由于对底层分布式数据库的依赖,对文件系统的语义支持程度也各有不同,如大多数基于分布式文件系统的计算分析框架依赖底层目录原子 Rename 操作来提供数据的原子更新,而 Tectonic 和 Colossus 因为底层数据库不支持跨分区事务所以不保证跨目录 Rename 的原子性,而 ADLSv2 支持对任意目录的原子 Rename。
DanceNN 是公司自研的一个目录树元信息存储系统,致力于解决所有分布式存储系统的目录树需求(包括不限于 HDFS,NAS 等),极大简化上层存储系统依赖的目录树操作复杂性,包括不限于原子 Rename、递归删除等。解决超大规模目录树存储场景下的扩展性、性能、异构系统间的全局统一命名空间等问题,打造全球领先的通用分布式目录树服务。
当前 DanceNN 已经为公司在线 ByteNAS,离线 HDFS 两大分布式文件系统提供目录树元数据服务。
(本篇主要介绍在离线大数据场景 HDFS 文件系统下 DanceNN 的应用,考虑篇幅,DanceNN 在 ByteNAS 的应用会在后续系列文章介绍,敬请期待)
元数据演进
字节 HDFS 元数据系统分三个阶段演进:

NameNode
最开始公司使用 HDFS 原生 NameNode,虽然进行了大量优化,依然面临下列问题:
元数据(包括目录树,文件和 Block 副本等)全内存存储,单机承载能力有限
基于 Java 语言实现,在大内存场景 GC 停顿时间比较长,严重影响 SLA
使用全局一把读写锁,读写吞吐性能较差
随着集群数据规模增加,重启恢复时间达到小时级别
DanceNN v1
DanceNN v1 的设计目标是为了解决上述 NameNode 遇到的问题。
主要设计点包括:
重新实现 HDFS 协议层,将目录树文件相关元数据存储到 RocksDB 存储引擎,提供 10 倍元数据承载
使用 C++ 实现,避免 GC 问题,同时使用高效数据结构组织内存 Block 信息,减少内存使用
实现一套细粒度目录锁机制,极大提升不同目录文件操作间的并发
请求路径全异步化,支持请求优先级处理
重点优化块汇报和重启加载流程,降低不可用时间
DanceNNv1 最终在 2019 年完成全量上线,线上效果基本达到设计目标。
下面是一个十几亿文件数规模集群,切换后大致性能对比:

DanceNN v1 开发中遇到很多技术挑战,如为了保证上线过程对业务无感知,支持现有多种 HDFS 客户端访问,后端需要完全兼容原有的 Hadoop HDFS 协议。
Distributed DanceNN
一直以来 HDFS 都是使用 Federation 方式来管理目录树,将全局 Namespace 按 path 映射到多组元数据独立的 DanceNN v1 集群,单组 DanceNN v1 集群有单机瓶颈,能处理的吞吐和容量有限,随着公司业务数据的增长,单组 DanceNN v1 集群达到性能极限,就需要在两个集群之间频繁迁移数据,为了保证数据一致性需要在迁移过程中上层业务停写,对业务影响比较大,并且当数据量大的情况下迁移比较慢,这些问题给整个系统带来非常大的运维压力,降低服务的稳定性。
Distributed 版本主要设计目标:
通用目录树服务,支持多协议包括 HDFS,POSIX 等
单一全局 Namespace
容量、吞吐支持水平扩展
高可用,故障恢复时间在秒级内
包括跨目录 Rename 等写操作支持事务
高性能,基于 C++ 实现,依赖 Brpc 等高性能框架
Distributed DanceNN 目前已经在 HDFS 部分集群上线,正在进行存量集群的平滑迁移。
文件系统概览
分层架构
最新 HDFS 分布式