一、
HDFS 架构介绍
HDFS离线存储平台是Hadoop大数据计算的底层架构,在B站应用已经超过5年的时间。经过多年的发展,HDFS存储平台目前已经发展成为总存储数据量近EB级,元数据总量近百亿级,NameSpace 数量近20组,节点数量近万台,日均吞吐几十PB数据量的大型分布式文件存储系统。
首先我们来介绍一下B站的HDFS离线存储平台的总体架构。
图 1-1 HDFS 总体架构
HDFS离线存储平台之前主要有元数据层和数据层,近年来我们引入了HDFS Router 扩展了接入层,形成当前的三层架构,如图1-1所示。
接下来将介绍我们在接入层、元数据层、数据层的探索与实践。
二、
接入层
(一)基于MergeFs的元数据快速扩展
由于HDFS集群存储数据量的迅猛增长,单个NameSpace已经无法满足元数据量的快速增长,我们在经历了HDFS 联邦机制后扩展成多NameSpace,满足了一段时间的需求。但是随着集群元数据量的指数级增长,特别是小文件数量的猛增,HDFS 联邦机制逐渐无法满足当时的需求。
为了能够快速新增NameSpace以及让新增的NameSpace迅速接入已有的集群,负载新增的元数据,现有的联邦机制和社区版本的RBF也无法满足当前的要求,我们决定在RBF的基础上,深度定制开发,来解决主节点扩展性问题。
当时元数据层的压力主要来源于3个方面:
为了解决元数据层扩展能力不足的问题,经过调研社区3.0的HDFS Router和业界相关方案后,我们决定在社区3.3版本的HDFS Router 的基础上,进行定制开发MergeFs来解决集群元数据层扩展性能问题,整体架构如图2-1所示:
图 2-1 HDFS MergeFS 整体架构
在支持了接入层的MergeFS后,元数据扩张不再成为瓶颈,我们扩容了14组NameSpace,支持了90亿左右的元数据总量,迁移了54亿左右的元数据。与此同时,整个集群的元数据层QPS得到了极大的提升,整体QPS从50K/s上涨到177.8K/s,整个数据迁移工作对上层数据计算任务透明,极大的减少了迁移的工作量,迁移工作量从1人/week,下降到0.1人/week。
(二)接入层限流策略
随着集群规模的日益增长,集群任务的读写数据量也有数量级的上涨,对集群元数据层的请求如果不加以限制,往往会造成热点NameSpace,针对HDFS存储这种多租户场景,往往会影响高优先级任务的运行,因此我们对接入层Router和元数据层NameNode都做了限流策略,来保障资源向高优先级任务倾斜,如图2-2所示:
图 2-2 HDFS 流量限制
通过上述的限流策略,我们对Hive,Spark计算引擎的动态分区任务等这类短时间大量读写请求的任务有了很大的防御能力,从监控上看,Router上单个NameSpace的Permit耗尽的情况出现的概率大大下降。
(三)接入层Quota 策略
存储数据的迅猛增长,以及数据治理推动耗时耗力,对租户数据进行Quota限制也是急需解决的问题。由于之前为了提升NameNode RPC性能,我们在NameNode上进行改造跳过了部分Quota计算的逻辑,极大的降低了NameNode在处理存在大量文件目录时的持锁时间。我们设计了基于接入层Router的quota机制如图2-3所示,将NameNode中Quota计算和校验的逻辑前置到Router中。Router中缓存了来源于HDFS元仓的路径Quota信息,目前是T+1更新,实效性不高,因此我们也正在开发基于NameNode Observer节点的准实时Quota功能,如图2-4所示。
图 2-3 基于HDFS元仓的Quota机制
图 2-4 近实时的Quota计算服务
(四)基于Router的Staging目录分流
由于业务的扩张,集群上并行的任务数量也迅猛增长,各种任务运行的临时文件目录如:Yarn Staing路径、Spark Staing路径、Hive scratchdir路径、Yarn Logs路径的QPS请求非常大,需要多组NameSpace进行分担才能承载,我们通过对这些路径配置HASH_ALL挂载点。
通过一致性HASH实现多组NameSpace之间的QPS负载均衡,将这些目录隔离在单独的NameSpace中,减少主集群NameNode的读写压力。
三、
元数据层
(一)基于RBF的Observer NameNode策略
HDFS 架构中元数据节点NameNode 的实现中存在针对目录树的全局锁,很容易就达到读写请求处理瓶颈。社区3.0版本中提出了一个Observer Read架构,通过读写分离的架构,尝试提升单个NameService的处理能力。为了提升NameNode请求处理能力,我们在社区版本的Observer机制的基础上也经过了定制化开发,基于最新的RBF框架,实现动态负载读请求路由,提升NameNode读写效率,如图3-1所示:
图 3-1 Observer NameNode 基础架构
在Observer NameNode功能落地过程中,我们做了许多的工作:
通过Observer NameNode的扩容,单个NameSpace的处理能力迅速上涨,由于当前只有部分Adhoc查询接入Observer节点,单组NameSpace Observer节点增加平均4.5k/s左右QPS,Active NameNode 峰值QPS下降40k/s,此外Active NameNode QueueTime 峰值和平均值均有所下降,均值从23ms下降到11ms ,如图3-2,图3-3 所示:
图 3-2 Observer NameNode 发布前Active NameNode QueueTime
图 3-3 Observer NameNode 发布后Active NameNode QueueTime
(二)NameNode动态负载均衡策略
当前集群由于DataNode节点和NodeManager节点混合部署,而NodeManager上运行的任务对节点负载造成的影响大小不一,HDFS文件的读写受到DataNode节点的负载影响较大,常常有慢读慢写的情况发生。为提高HDFS系统的稳定性,我们在NameNode端加以改造,实现动态的负载均衡策略,如图 3-4所示:
图 3-4 NameNode 负载均衡策略
(三)NameNode 删除保护策略
在管理数据的过程中,由于多次出现数据误删的操作,HDFS原生的回收站功能不足,且事后恢复数据的工作非常困难,我们针对删除操作进行了限制,用于保护集群中存储的数据,主要有以下几点:
(四)NameNode 大删除优化策略
由于集群文件大小不一,存在部分目录文件数量较多,同时开启了上述介绍的删除保护策略,每日回收站清理时会有大量的删除操作。删除操作持写锁时间长,特别是删除存在大量文件的目录时,可能持写锁达到分钟级,造成NameNode无法处理其他读写请求,因此我们参照社区实现了大删除异步化策略。从图3-5的火焰图中可以看出,删除操作持锁时间主要由removeBlocks占据,因此我们做了如下优化措施:
通过上述方式,有效的减少了大量文件目录删除时持锁时间,耗时从分钟级下降到了秒级。
图 3-5 NameNode delete操作火焰图
(五)NameNode FsImage并行加载
由于HDFS单NameSpace的元数据总量上升,我们发现生产环境中NameNode节点启动时间过长(最长约80min),不仅影响运维效率, 还增加了运维重启过程中的单点风险, 一旦出现宕机等异常情况,服务将长时间不可用。因此,如何加快NameNode重启速度是我们亟待解决的问题。
经分析发现,NameNode启动信息主要包括以下四个阶段:
图 3-6 NameNode Fsimage 构成图
由于DataNode BlockReport存在一些方法可以进行加速汇报,我们当前只做了加载fsimage的优化加速。我们对fsimage中占比最大(90%以上)的部分为INodeSection / INodeDirectorySection进行并行(多线程)加载改造,如上图3-6所示:
通过采用FSimage并行加载机制,NameNode启动时间有了明显的下降,从大约80min下降到了50min 左右,后续我们也会继续优化BlockReport时间,进一步降低启动耗时。
(六)HDFS数据元仓
HDFS元仓是HDFS所有文件路径的大小信息,读写信息和对应表信息的汇总,基于每日凌晨产出的HDFS文件镜像和HDFS 审计日志以及Hive元数据信息,通过一系列ETL任务,生成HDFS 文件信息宽表,积累一定时间段数据后,我们可以获取目录文件增长,文件访问信息等数据,用于指导数据治理和数据冷存等业务的开展,具体架构如图3-7所示:
图 3-7 HDFS 元仓模型架构
用数据思维指导数据治理,在HDFS元仓搭建完成后,我们和公司内数仓数据治理团队,SRE团队一起,多次推动数据治理,建设HDFS水位预警机制,输出数据使用报表,推动用户数据自治。
(七)Smart Storage Manager 管理工具
Smart Storage Manager是Intel开源的智能存储管理系统,可以智能的管理HDFS上的数据,包括自动化使用异构存储,HDFS Cache,小文件合并,块级别的EC和数据压缩等,主要架构如图3-6所示。我们引入了SSM服务结合HDFS元仓建设了B站自己的HDFS数据管理服务,当前主要用于冷存数据转换服务。
图 3-8 HDFS Smart Storage Manager 架构
四、
数据层
HDFS 数据层的问题主要是Client写入的问题,在一个复杂的分布式系统中,热点的存在始终无法避免,我们所做的就是尽力保障整个HDFS读写的稳定性。
(一)HDFS Client写入慢节点处理策略
HDFS是一个复杂的分布式存储系统,其中各个节点负载不一,写入非常容易遇到慢节点问题。为解决此类问题,我们陆续推出了Pipline Recovery策略和FastFailover策略提升写入的效率。
图 4-1 HDFS Client Pipeline Recovery 策略
图 4-2 HDFS Client FastFailover 策略
通过上述的Pipeline Recovery策略和FastFailover策略,HDFS客户端的读写能力有了很大的提升。写入packet长尾时间从分钟级下降到秒级,平均耗时(遇到慢节点的情况)从秒级下降到毫秒级如图4-3、图4-4所示。目前Pipline Recovery策略触发次数大约在50次/s,触发FastFailover策略大约在100次/24H。
图 4-3 未进行优化措施
图 4-4 支持Pipeline Recovery策略和FastFailover策略后
(二)HDFS Client FastSwitchRead功能
客户端访问HDFS存储系统读取文件时,会访问NameNode获取文件的全部或者部分block列表,每个block上带有按距离排好序的datanode地址,客户端拿到block的位置信息后,对于每个block,选择距离客户端最近的datanode,建立连接来读取当前block的数据。如果连接的DataNode正好属于慢节点,则极有可能导致读取文件速度变慢。因此我们采用以下两种方式优化HDFS Client读取数据。
每个block包含多个packet,hdfs client在读取数据的时候,是按照packet来读取的,因此,我们假设block-1有d1,d2两个副本,n个packet,同时,我们设定时间窗口为64ms(即当时间窗口超过64ms计算一次吞吐量),初始吞吐量的阈值为4474bytes/ms,如下图所示:
图 4-5 基于时间窗口吞吐量的慢节点切换
从上述基于时间窗口吞吐量避免慢节点可知,计算吞吐量有个前提是,当前packet必须读取完成,而通常会有在一个慢节点上读一个packet耗时较长(如读一个packet耗时超过1分钟)的现象,为了避免这样情况发生,保证遇到慢节点时切换足够敏感,我们通过动态调整客户端与DataNode的 read socket timeout超时参数,来实现慢节点的切换,我们从一个较小的超时时间(128ms)开始配置,每次切换后超时时间*2,最大时间不超过30s。
图 4-6 基于动态调整超时时间的慢节点切换
(三)DataNode拆锁优化
如下图所示,经过拆锁优化后,WriteBlockAvgTime 有了很大的提升。
图 4-7 升级前DataNode RPC处理均值
图 4-8 升级后DataNode RPC处理均值
五、
多机房专项
随着集群规模的不断扩大,同时由于单个机房机位达到机房上限无法提供更多的机位用于部署HDFS存储节点,而单纯在异地机房部署DataNode节点会带来无法预计的带宽问题。因此为了集群的持续发展,以及跨机房网络的带宽瓶颈和网络抖动问题,我们设计并建设了HDFS多机房体系。
图 5-1 多机房体系架构
整个跨机房体系联动了许多部门,整体架构较复杂,涉及到调度,存储,计算引擎和工具侧改造,在这就不多做赘述了,后续我们会针对跨机房项目单独分享一篇文章介绍。
六、
未来规划
(一)对用户透明的EC策略
由于总体数据量的膨胀,对总体储存的消耗也与日俱增,为了响应公司整体降本增效的战略,我们准备对大量数据进行EC处理。EC即ErasureCoding,通过对存储数据进行编码,能有效降低总存储量,提升存储的稳健性。为了尽快开展EC工作,并且做到对各种用户的读写方式透明,我们预期做到以下几点:
(二)冷热温三级数据路由策略
由于数据热点的存在(如部分公共Hive维表等)经常导致DataNode节点整体IO打高,影响该DataNode上其他的数据读写受阻,我们计划引入Alluxio组件,支持热点数据缓存,在Router改造挂载点,使其支持挂载点冷热温三级数据类型,自动化路由到对应的目录。同时支持HDFS元仓自动化分析数据访问热度,数据按访问热度自动降级为冷存或EC数据。
(三)NameNode拆锁
随着元数据层的扩展,我们当前已经扩展到十几组的规模。但元数据层的扩容不可能是无限制的,同时各组NameNode的qps请求不均衡,非常出现热点NameSpace的存在,因此对NameNode进行优化的工作也是必不可少的。考虑到NameNode锁机制,写操作会锁住整个目录树,我们计划对NameNode目录锁进行优化,提升NameNode读写能力。
(四)Hadoop 3.x版本升级
为了支持HDFS的EC策略,我们计划新建3.x版本HDFS集群,用于存储EC数据,由于3.x版本集成了很多HDFS相关优化,在读写兼容的情况下,我们计划用3.x版本慢慢替换掉现有的2.x版本的HDFS集群。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://iteblog.blog.csdn.net/article/details/123887623
内容来源于网络,如有侵权,请联系作者删除!