JuiceFS 如何帮助趣头条超大规模 HDFS 降负载
作者简介
- 王振华,趣头条大数据总监,趣头条大数据负责人。
- 王海胜,趣头条大数据工程师,10 年互联网工作经验,曾在 eBay、唯品会等公司从事大数据开发相关工作,有丰富的大数据落地经验。
- 高昌健,Juicedata 解决方案架构师,十年互联网行业从业经历,曾在知乎、即刻、小红书多个团队担任架构师职位,专注于分布式系统、大数据、AI 领域的技术研究。
背景
趣头条大数据平台目前有一个近千节点的 HDFS 集群,承载着存储最近几个月热数据的功能,每日新增数据达到了百 TB 规模。日常的 ETL 和 ad-hoc 任务都会依赖这个 HDFS 集群,导致集群负载持续攀升。特别是 ad-hoc 任务,因为趣头条的业务模式需要频繁查询最新的数据,每天大量的 ad-hoc 查询请求进一步加重了 HDFS 集群的压力,也影响了 ad-hoc 查询的性能,长尾现象明显。集群负载高居不下,对很多业务组件的稳定性也造成了影响,如 Flink 任务 checkpoint 失败、Spark 任务 executor 丢失等。
因此需要一种方案使得 ad-hoc 查询尽量不依赖 HDFS 集群的数据,一方面可以降低 HDFS 集群的整体压力,保障日常 ETL 任务的稳定性,另一方面也能减少 ad-hoc 查询耗时的波动,优化长尾现象。
方案设计
趣头条的 ad-hoc 查询主要依靠 Presto 计算引擎,JuiceFS 的 Hadoop SDK 可以无缝集成到 Presto 中,无需改动任何代码,以不侵入业务的方式自动分析每一个查询,将需要频繁读取的数据自动从 HDFS 拷贝至 JuiceFS,后续的 ad-hoc 查询就可以直接获取 JuiceFS 上已有的缓存数据,避免对 HDFS 产生请求,从而降低 HDFS 集群压力。
另外由于 Presto 集群是部署在 Kubernetes 上,有弹性伸缩集群的需求,因此需要能够将缓存数据持久化。如果使用独立的 HDFS 或者某些缓存方案的话,成本会很高,此时 OSS 成为最理想的选择。
整体方案设计如下图所示。绿色部分表示 JuiceFS 的组件,主要包含两部分:JuiceFS 元数据服务(下图中的 JuiceFS Cluster)及 JuiceFS Hadoop SDK(下图与 Presto worker 关联的组件)。
JuiceFS 元数据服务用于管理文件系统中所有文件的元信息,如文件名、目录结构、文件大小、修改时间等。元数据服务是一个分布式集群,基于 Raft 一致性协议,保证元数据强一致性的同时,还能确保集群的可用性。
JuiceFS Hadoop SDK(以下简称 SDK)是一个客户端库,可以无缝集成到所有 Hadoop 生态组件中,这里的方案即是集成到 Presto worker 中。SDK 支持多种使用模式,既可以替代 HDFS 将 JuiceFS 作为大数据平台的底层存储,也可以作为 HDFS 的缓存系统。这个方案使用的便是后一种模式,SDK 支持在不改动 Hive Metastore 的前提下,将 HDFS 中的数据透明缓存到 JuiceFS 中,ad-hoc 查询的数据如果命中缓存将不再需要请求 HDFS。同时 SDK 还能保证 HDFS 与 JuiceFS 间数据的一致性,也就是说当 HDFS 中的数据发生变更时,JuiceFS 这边的缓存数据也能同步更新,不会对业务造成影响。这是通过比较 HDFS 与 JuiceFS 中文件的修改时间(mtime)来实现的,因为 JuiceFS 实现了完整的文件系统功能,所以文件具有 mtime 这个属性,通过比较 mtime 保证了缓存数据的一致性。
为了防止缓存占用过多空间,需要定期清理缓存数据,JuiceFS 支持根据文件的访问时间(atime)来清理 N 天前的数据,之所以选择用 atime 是为了确保那些经常被访问的数据不会被误删除。需要注意的是,很多文件系统为了保证性能都不会实时更新 atime,例如 HDFS 是通过设置 dfs.namenode.accesstime.precision
来控制更新 atime 的时间间隔,默认是最快 1 小时更新 1 次。缓存的建立也有一定的规则,会结合文件的 atime、mtime 和大小这些属性来决定是否缓存,避免缓存一些不必要的数据。
测试方案
为了验证以上方案的整体效果,包括但不限于稳定性、性能、HDFS 集群的负载等,我们将测试流程分为了多个阶段,每个阶段负责收集及验证不同的指标,不同阶段之间可能也会进行数据的横向比较。
测试结果
HDFS 集群负载
我们设计了两个阶段分别开启和关闭 JuiceFS 的功能。在开启阶段随机选取 10 台 HDFS DataNode,统计这一阶段每台 DataNode 平均每天的磁盘读 I/O 吞吐,平均值约为 3.5TB。在关闭阶段同样选择这 10 个节点,统计下来的平均值约为 4.8TB。因此使用 JuiceFS 以后可以降低 HDFS 集群约 26% 的负载,如下图所示。
从另一个维度也能反映 HDFS 集群负载降低的效果,在这两个阶段我们都统计了读取及写入 JuiceFS 的 I/O 总量。JuiceFS 的读 I/O 表示为 HDFS 集群降低的 I/O 量,如果没有使用 JuiceFS 那么这些请求将会直接查询 HDFS。JuiceFS 的写 I/O 表示从 HDFS 拷贝的数据量,这些请求会增大 HDFS 的压力。读 I/O 总量应该越大越好,而写 I/O 总量越小越好。下图展示了某几天的读写 I/O 总量,可以看到读 I/O 基本是写 I/O 的 10 倍以上,也就是说 JuiceFS 数据的命中率在 90% 以上,即超过 90% 的 ad-hoc 查询都不需要请求 HDFS。
平均查询耗时
在某一阶段将各 50% 流量的查询请求分配给未对接和已对接 JuiceFS 的两个集群,并分别统计平均查询耗时。从下图可以看到,使用 JuiceFS 以后平均查询耗时降低约 13%。
测试总结
JuiceFS 的方案在不改动业务配置的前提下,以对业务透明的方式大幅降低了 HDFS 集群的负载,超过 90% 的 Presto 查询不再需要请求 HDFS,同时还降低了 13% 的 Presto 平均查询耗时,超出最初设定的测试目标预期。之前长期存在的大数据组件不稳定的问题也得到解决。
值得注意的是,整个测试流程也很顺畅,JuiceFS 仅用数天就完成了测试环境的基础功能和性能验证,很快进入到生产环境灰度测试阶段。在生产环境中 JuiceFS 的运行也非常平稳,承受住了全量请求的压力,过程中遇到的一些问题都能很快得到修复。
未来展望
展望未来还有更多值得尝试和优化的地方:
- 进一步提升 JuiceFS 缓存数据的命中率,降低 HDFS 集群负载。
- 增大 Presto worker 本地缓存盘的空间,提升本地缓存的命中率,优化长尾问题。
- Spark 集群接入 JuiceFS,覆盖更多 ad-hoc 查询场景。
- 将 HDFS 平滑迁移至 JuiceFS,完全实现存储和计算分离,降低运维成本,提升资源利用率。
项目地址: Github (https://github.com/juicedata/juicefs)如有帮助的话欢迎 star (0ᴗ0✿),鼓励鼓励我们哟!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
鸿蒙轻内核源码分析:异常钩子模块系统中断异常,如何转储异常信息
摘要:本篇介绍下鸿蒙轻内核中异常钩子模块发生系统中断异常时如何转储异常信息。 本文分享自华为云社区《鸿蒙轻内核M核源码分析系列十七(3) 异常信息ExcInfo》,作者: zhushy。 ExcHook异常钩子模块是OpenHarmony LiteOS-M内核的一个可选组件,提供注册钩子函数LOS_RegExcHook、解除注册钩子函数LOS_UnRegExcHook等操作接口。发生系统时,支持保存异常上下文、任务信息、队列信息、中断寄存器状态、任务切换信息、内存分配等信息。由于异常钩子模块内容较多,我们分为几篇进行分析源码,分别介绍异常钩子函数的类型,如何注册和解除注册钩子函数,如何转储异常信息等。本篇介绍下异常钩子模块发生系统中断异常时如何转储异常信息。 本文中所涉及的源码,以OpenHarmony LiteOS-M内核为例,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m获取。鸿蒙轻内核异常钩子模块代码主要在components\exchook目录下。 1、异常信息的宏定义、枚举和结构体 在文件components\exc...
- 下一篇
新一代日志型系统在 SOFAJRaft 中的应用
📄 文|黄章衡(SOFAJRaft 项目组) 福州大学 19 级计算机系 研究方向|分布式中间件、分布式数据库 Github 主页|https://github.com/hzh0425 校对|冯家纯(SOFAJRaft 开源社区负责人) 本文 9402 字 阅读 18 分钟 ▼ PART. 1 项目介绍 1.1 SOFAJRaft 介绍 SOFAJRaft 是一个基于 RAFT 一致性算法的生产级高性能 Java 实现,支持 MULTI-RAFT-GROUP,适用于高负载低延迟的场景。使用 SOFAJRaft 你可以专注于自己的业务领域,由 SOFAJRaft 负责处理所有与 RAFT 相关的技术难题,并且 SOFAJRaft 非常易于使用,你可以通过几个示例在很短的时间内掌握它。 Github 地址: https://github.com/sofastack/sofa-jraft 1.2 任务要求 **目标:*当前 LogStorage 的实现,采用 index 与 data 分离的设计,我们将 key 和 value 的 offset 作为索引写入 rocksdb,同时日志条目(...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合Redis,开启缓存,提高访问速度