美团、快手、去哪儿网是如何构建测试环境的?点击查看实践案例>> 了解详情
写点什么

揭秘淘宝自主研发的文件系统——TFS

  • 2010 年 7 月 07 日
  • 本文字数:5344 字

    阅读完需:约 18 分钟

目前,国内自主研发的文件系统可谓凤毛麟角。淘宝在这一领域做了有效的探索和实践,Taobao File System(TFS)作为淘宝内部使用的分布式文件系统,针对海量小文件的随机读写访问性能做了特殊优化,承载着淘宝主站所有图片、商品描述等数据存储。

最近,淘宝核心系统团队工程师楚材(李震)在其官方博客上撰文(《TFS 简介》,以下简称文章)简要介绍了 TFS 系统的基本情况,引起了社区的关注。

文章首先概括了 TFS 的特点:

  • 完全扁平化的数据组织结构,抛弃了传统文件系统的目录结构。
  • 在块设备基础上建立自有的文件系统,减少 EXT3 等文件系统数据碎片带来的性能损耗。
  • 单进程管理单块磁盘的方式,摒除 RAID5 机制。
  • 带有 HA 机制的中央控制节点,在安全稳定和性能复杂度之间取得平衡。
  • 尽量缩减元数据大小,将元数据全部加载入内存,提升访问速度。
  • 跨机架和 IDC 的负载均衡和冗余安全策略。
  • 完全平滑扩容。

当前,TFS 在淘宝的应用规模达到“数百台 PCServer,PB 级数据量,百亿数据级别”,对于其性能参数,楚材透漏:

TFS 在淘宝的部署环境中前端有两层缓冲,到达 TFS 系统的请求非常离散,所以 TFS 内部是没有任何数据的内存缓冲的,包括传统文件系统的内存缓冲也不存在…基本上我们可以达到单块磁盘随机 IOPS(即 I/O per second)理论最大值的 60% 左右,整机的输出随盘数增加而线性增加。

TFS 的逻辑架构图 1 如下所示:

图 1. TFS 逻辑架构图(来源:淘宝核心系统团队博客)

楚材结合架构图做了进一步说明:

  1. TFS 尚未对最终用户提供传统文件系统 API,需要通过 TFSClient 进行接口访问,现有 JAVA、JNI、C、PHP 的客户端
  2. TFS 的 NameServer 作为中心控制节点,监控所有数据节点的运行状况,负责读写调度的负载均衡,同时管理一级元数据用来帮助客户端定位需要访问的数据节点
  3. TFS 的 DataServer 作为数据节点,负责数据实际发生的负载均衡和数据冗余,同时管理二级元数据帮助客户端获取真实的业务数据。

文章发表以后,读者反响热烈,在评论中提出了各种问题与作者楚材进行技术交流,由此可见国内社区对自主研发文件系统的关注程度。

为了让读者更深入地了解TFS 的奥秘, InfoQ 中文站针对 TFS 的来由、运行环境、扩展性、架构、发展规划及开源事宜等问题对楚材(李震)进行了专访。

InfoQ:淘宝为何会选择自主研发文件系统?

TFS(Taobao File System),是淘宝自主研发的一套分布式文件系统,用于存储淘宝网主站的数据,例如商品图片、商品描述、交易快照、社区图片等等等等。 这些数据的一个突出特点是单个文件尺寸较小,通常不大于 1MB,但是数量巨大,传统的文件系统或者网络存储设备很难解决类似的问题。

淘宝网最早采用 NetApp 提供的网络存储设备,但是在 2006~2007 年期间,由于数据量的急剧膨胀,我们面临着系统更新换代的压力,而由于应用连接数量和文件数量的限制,实际上简单的升级已经变得非常昂贵且得不偿失了。

数据是淘宝应用的核心,在这方面我们需要提供更加安全、高效、廉价的解决方案,需要发展自己的技术,更加适应淘宝网自身的应用特性。经过评估,已有的一些开源分布式文件系统都无法完全满足我们需求。淘宝网也许是当时国内互联网最先遇到类似问题的公司,当然也可能是其他公司遇到但未进行相关的宣传,总之,当时并不像现在一样有一些相对可靠的开源系统可以选择。

InfoQ:TFS 系统的运行环境如何?

在做 TFS 选型的时候,我们依照当时淘宝网使用的主流操作系统使用了 REHL,并构建在 LINUX 的 EXT3 文件系统上。选择 REHL 的理由是开源操作系统,我们有更多的自由度,同时成本也更加节省。 关于硬件平台,随着硬件的发展和我们认识的变化,经过了一个相对比较长的变迁。分布式文件系统对 CPU 的要求并不高,同时由于我们采用了一些特殊的手段,也使得系统元数据减少,那么对内存大小的要求也并不高了,所有的性能和成本瓶颈都集中在了磁盘 IO 上。我们所有硬件架构的演变也都体现在磁盘的使用方式上。

最早我们使用 SAS146G×6 的磁盘进行存储,后来换成了 SAS300G×6 的磁盘,使用了 RAID5 机制,这也是当时硬件平台的主流。当我们积累了一定的经验并逐步对系统稳定性有了信心之后,这种方式就逐步落后了。RAID5 机制的备份和我们已经在应用层实现的数据冗余功能重复,磁盘空间被大量浪费,RAID 卡的工作原理也无法优化 TFS 更加注重随机 IO 的特性,最终我们去除了 RAID 卡,并使用多进程,每个进程管理一块磁盘的方式,充分发挥磁盘的随机读写性能。

SAS300G×6 的磁盘我们使用了一段时间,相对比较稳定,这让我们有信心使用更大容量的节点而不会过于担心服务器失效带来的数据迁移对系统性能的影响,当前 TFS 主要的机型使用 SAS300G×12 的磁盘配置。

随着淘宝网前端的 CDN 越来越高效、稳定,到达 TFS 的请求流量也更加平缓,这让我们有可能对单个节点的服务能力做出更加可靠的规划,也可以使用更加廉价的存储设备,未来我们的主要存储节点将使用 1TSATA×12 甚至更大的磁盘设备,进一步降低成本。

InfoQ:TFS 的应用规模达到数百台 PC server 和 PB 级数据量,其扩展性如何?架构上是如何保证的?

在 TFS 中我们将大量的小文件合并成为一个大文件,类似 GFS 中 Chunk 的概念,而 Chunk 的定位信息我们称之为一级索引,而 chunk 内部具体的文件定位信息我们称之为二级索引,同时在 TFS 文件名称中包含这些索引信息,在用户写入一个文件之前,他必须向 TFS 系统申请一个文件名称。这种方式虽然在某些情况下显得不像传统文件系统那样灵活,但也给了我们系统更大的可扩展性。我们保证可以中心控制节点的内存可以支撑 PB 级别的一级索引,而二级索引仅需要针对单台数据量。这样,我们就避免了数据量膨胀带来的扩容难度。 当存储容量出现不足,我们需要进行系统扩容的时候,可以根据数据增长情况进行规划,任意数量的加入提供相应存储的服务器。而这些新的存储服务器会向中心控制节点进行报告。而中心控制节点在有数据写入时,将根据已存储容量的百分比、系统当前负载等参数动态地分配写入的服务器。同时,在系统空闲时间段,中心控制节点也会根据当前的数据分布情况制定数据迁移计划,并逐步完成数据平衡。与此类似,当发生服务器崩溃时,中心控制节点也会进行数据迁移以保证足够的备份,同时也会进行数据均衡操作。这些操作都是自动进行的,不需要人工干预。

这种方式在 1000 台以内的集群基本上能够工作良好,如果集群规模更大,中心控制节点可能会出现一些性能瓶颈,届时我们可以使用一个分布式集群来解决,相应已经比较成熟的技术方案现在已经比较多了。

InfoQ: 您在介绍 TFS 的特点时,多次提到“性能”这个关键词,请问对于一个文件系统来说,性能一般应该考虑哪些因素?目前,提高文件系统性能的通用方法有哪些?

现在我们可以讨论一下 TFS 的性能考量的维度了。其实当前每个流行的分布式文件系统都有自己的侧重点,分别针对自己不同的应用场景。 对于离线型的数据分析需求,由于数据总量巨大,底层分布式文件系统更加注重系统的整体吞吐率,为了适应当前流行的 map_reduce 模型,这一类的文件系统会将文件切成多份,分而治之。同时和上层的逻辑配合,采用大块顺序写入、读出的方式来提升性能,典型的代表就是 Hadoop 使用的 HDFS。

实际提供线上服务的分布式文件系统中,也根据服务类型的不同而采用差异化的存储方式,例如针对音、视频等相对比较大的文件,可能采用和离线应用相同的方式将文件切片并发读写访问,从而达到更高的传输速度。由于相同容量下文件数量比较少,甚至有可能完全实现类似传统文件系统的目录、权限等功能,而不会受到 inode 的限制。如果面临淘宝相同的海量小文件存储,这种方式就完全无法提供性能的支持了,inode 数量的膨胀会很快吃掉大量的昂贵内存,如果要平衡成本将部分 inode 放入磁盘,面对基本上完全随机、没有热点的访问又无法保证寻址的效率,我们只能通过减少元数据的方式来解决这个问题。

为什么说我们的 TFS 面临着完全随机、基本上没有热点的数据访问?在淘宝的数据部署中,TFS 前端有两层更加靠近用户的缓存系统来保证用户展示页面的速度,最终到达 TFS 的请求大概只有总请求数量的 2% 左右,随着前端缓冲的效率不断提升,这个比例还会继续下降,我们可以想象一下是否仍然有热点数据存在。与此同时,淘宝网的业务特点决定了相对于读取请求,写入请求量不在一个数量级上,而修改操作量就更少,这就决定了我们使用进行随机修改、随机写入的方式来避免顺序写入不进行修改给随机读取带来的成本。

不同的应用场景,不同的存储架构,不同的性能考量,有什么通用的性能优化手段吗?从我们的实践经验来看,似乎没有,很难有一种方法解决所有的问题,或者说解决了这些问题之后,大家会发现相对专用的文件系统,通用系统总是不能达到你预期的性能,同时也带来了大量开发和调优方面的复杂性。这种情况下,也许我们建立不同的集群解决不同的问题更加高效,这一切都取决于你支撑的业务需求是怎么样的,Google 级别集群规模的架构和简单搭建起来的 NFS 都有其存在的价值。

当然,还是有一些通用的规则的。如果你需要支持的是一个线上服务,那你就要尽量减少一次请求引发的 IO 数量,IO 包括网络及物理磁盘,这些操作引发的性能开销是由物理结构决定,无法用技术手段去优化的。也就是说,这些操作的数量实质上形成了你这个系统的性能天花板,当你设计一个文件系统的架构时,你可以根据这个天花板预估到在不同情况下这套系统的性能表现是怎么样的。

其次,你需要在并发和同步开销之间做出平衡,根据业务的特点选择更适合于你自己的方案,例如从一块磁盘上连续读 1MB 数据和通过网络并发从 10 块磁盘上分别读取 100KB 数据返回给用户,你会选择哪种?那么从一块磁盘上连续读取 100MB 数据和 100 并发分别读取读取 1MB 呢,系统是否有能力支撑这样的并发?绝大部分时候,我们是在做类似的选择。

第三,你需要在成本和性能之间做出平衡,我们可以很方便的使用内存型缓冲来极大地提升系统性能,如果你的系统热点数据集中的话。随着 SSD 技术的成熟,它可以提供的随机读性能相对传统机械磁盘让人兴奋,随机写性能也有了极大的改善,虽然不像读取提升的那样夸张。如果你的应用读写比例比较高,又可以承受成本,尽量使用 SSD 吧,虽然当前的成本还是相对昂贵的。

InfoQ:从 TFS 的逻辑架构图来看,NameServer 作为中心控制节点,DataServer 作为数据节点,这样的架构基于哪些因素或者需求的考虑?

TFS 有中心控制节点和数据节点的区分,分别管理两级索引解决数据访问的寻址和传输。相对当前一些开源分布式系统的去中心化趋势,似乎不是非常优秀。但如同对性能的论述一样,每种系统架构都有其存在的价值,中心节点的存在可以保证事务性,我们在某些情况下必须保证写入数据的强一致性,同时在当前的应用规模中也可以非常安全、高效的解决问题。如果有更高的可用性、扩展性需求,我们会在 TFS 部分中部分体现去中心化的思想。

InfoQ:未来 TFS 的发展计划如何?

TFS 未来的开发首先仍然会立足于淘宝网自身的业务需求,同时会照顾开发社区中的需求。我们会逐步支持大文件的存储,也会支持目录和用户权限,同时计划实现按照访问特性分布的分级存储,尽量在性能和成本之间达到一个平衡,还有一些更加精细化的管理功能,例如数据量配额的管理等等。从上面的一些讨论来看,我们不大会做一个通用的分布式文件系统,始终会专注解决当前尚无很好解决方案的问题。

InfoQ:您在博客中提到 9 月份建立 TFS 开源社区,这对国内社区是个绝佳的学习机会,请问目能否再描述一点开源的细节?

TFS 计划在 9 月底开源,而今年 6 月底,淘宝网将推出自己的开源社区—— code.taobao.org ,TFS 将完全基于这个开源社区进行开源,大家马上就可以看到。同时已经基本确定使用 GPL V2 开源版权协议。

InfoQ:对于有志于参与到 TFS 或者目前从事其他类似系统级核心应用的开发人员来说,请问有什么好的建议?

对于有志于参加 TFS 开发,或者自身已经在从事基础平台、核心系统研发的同行,我相信大家都有相同的感受,在当今计算机体系结构内,我们很难有革命性的技术进展。当前已知的大规模的分布式文件系统都构建在 Unix 类操作系统之上,或者说绝大部分都构建在 Linux 之上,这也是从成本方面进行的考量。而各种分布式文件系统架构也大同小异,决定是否成功的关键在于细节,这些细节包括操作系统级别的特化、文件系统级别的特化、实现方面是否足够优秀、足够稳定等等。因此你需要对系统内核有所了解,对文件系统有所了解,比如你知道 EXT3 的组织方式才可能尽量避免读取一段数据却引发多次磁盘磁头移动的情况,这样你才能最大化的利用好系统资源。而实现的特化可能体现在一个优秀算法的编写、一个高效的通信机制等等,这就要求你有扎实的代码编写能力,对算法和数据结构有颇深的造诣。大家都知道,细节决定成败!

InfoQ 中文站将继续关注 TFS 等国内自主研发文件系统的发展,也欢迎大家发表自己的看法。

专家介绍

李震,花名楚材,工作于淘宝技术研发部核心系统研发,负责存储组的开发,关注领域主要包括大集群分布式系统的研发、海量数据处理、海量数据检索等等。


给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2010 年 7 月 07 日 01:0025975
用户头像

发布了 501 篇内容, 共 231.1 次阅读, 收获喜欢 53 次。

关注

评论

发布
暂无评论
发现更多内容

都前后端分离了,咱就别做页面跳转了!统统 JSON 交互

江南一点雨

spring Spring Boot spring security

发布Maven包的正确姿势

廖雪峰

maven 开源

2020第一篇技术博客

java劝退师首席大弟子

生活

Collaboration on SaaS

zhenglei

SaaS Collaboration Cisco Webex

【高级进阶】写给大忙人看的JDK14新特性

知春秋

Java java 14 java 14 新特性

写作对我的意义

Neco.W

总结 思考 写作 感悟

JAVA内存模型与线程

颇风

Java 内存模型 JVM

如何用一套引擎搞定机器学习全流程?

Apache Flink

大数据 flink 流计算 实时计算

Design Sprint 教你五天完成产品迭代

Yanel 说敏捷产品

产品 敏捷 设计 产品设计 团队

回“疫”录(19):都什么时候了,还在搞“填表抗疫”

小天同学

疫情 回忆录 现实纪录 纪实 形式主义

走进Golang之编译器原理

何磊

编译原理 Go 语言

从连续两届图灵奖(2018-2019)看GPU发展史

GPU

人工智能 gpu 计算机基础 计算机图形学 计算机体系结构

Docker 镜像制作教程:针对不同语言的精简策略

米开朗基杨

Docker Dockerfile

从零到部署:用 Vue 和 Express 实现迷你全栈电商应用(一)

图雀社区

node.js vue.js Vue

如何搞定Kafka重复消费?

奈学教育

kafka kafka配置

EasyExcel最权威教程

知春秋

Java Excel EasyExcel

笔记:《如何系统思考》之如何应用系统思考

wiflish

思维方式

Kotlin协程实践之进程、线程、协程

陈吉米

Java kotlin 协程 Coroutine

2020年比以往任何时候更想做成的使命感

乐少

有问必答(2020-05-09):如何督促自己做好一件事情?

冯夷

生活

Java如何处理异常情况

Rayjun

Java 异常

机会,是不会让你准备好的

Winann

学习 生活 知识管理 机会

11 万字的字节码编程系列合集放送(ASM、Javassist、Byte-buddy、Javaagent)

小傅哥

Java asm bytebuddy 《字节码编程》

游戏夜读 | Scikit-learn迎来0.21版本

game1night

键入网址后,其间发生了什么?

小林coding

TCP 计算机网络 网络协议 IP HTTP

《零基础学 Java》 FAQ 之 8-Java方法调用是传值还是传引用

臧萌

Java

一种练好英语口语的方法

董一凡

学习

微服务为什么要有服务发现与注册?

周果

微服务

少说废话,先干起来

大辉辉

学习 个人成长 自律

DevOps生命周期,你想知道的全都在这里了!

禅道项目管理

DevOps 测试 持续集成

比AtomicLong更优秀的LongAdder确定不来了解一下吗?

一枝花算不算浪漫

并发编程 jdk源码

揭秘淘宝自主研发的文件系统——TFS_Java_崔康_InfoQ精选文章