OPPO离线HDFS集群演进与优化实践

原创
2024/01/02 18:20
阅读数 356

01

背景

HDFS 承载了 OPPO 近 EB 的存储数据,其中线上 PB 级别集群占比近49%,超过85% 水位线的PB级集群占23%,大集群日增 PB 数据量。本次分享内容主要介绍 OPPO 在离线 HDFS 集群的建设和实践。

02

规范化治理

早期 HDFS 业务集群较多,经过梳理和分析,我们发现存在较多规范化问题:
  1. 集群部署方式不统一,有 CM 管理和手动搭建;各集群的 HADOOP 安装、配置、日志目录不统一;
  2. 无统一且全面的监控面板,指标散落在多套系统,定位问题需来回跳转,监控和告警覆盖不完整;
  3. 线上有多套 HDFS 集群,小集群占比高,一些集群机器异构严重,小盘机器掉线频繁;
  4. DN 坏盘维修流程长,人工参与度高,效率低。
针对上述问题,我们进行了集中整治。统一监控入口、完善 HDFS监控告警、配置 HDFS 日志采集和预警、下线不合理机型、上线自动化坏盘维修、重规划和收敛 HDFS 小集群、废弃 CM 和手动部署,统一运维入口到内部的智能运维平台。

03

稳定性建设

3.1 功能优化
早期内部版本是2.6,存在较多性能问题,我们针对 HDFS 进行了大量参数调优,同时也从源码层面,结合社区 Patch 和内部需求,进行了一系列功能迭代优化,提升集群性能、稳定性、易用性、抗风险能力:
  • 优化 NN 和 DN 锁;
  • 支持目录保护,防止业务误删;
  • 支持 Client 禁用 skipTrash,expunge 等命令;
  • 支持 TraceId,方便定位用户 job;
  • 完善 NN 处理 FBR 上报功能;
  • 支持查看某个路径下的 OpenFiles,便于快速定位问题;
  • 支持查找阻塞 DN 退役的未释放租约文件命令;
  • 支持动态刷新 RACK信息;
  • 支持 DN 重入役后移除待复制 blocks 功能;
  • 支持动态获取配置的 Client 允许设置副本数;
  • 支持 WEB UI 统计和展示退役时间;
  • 支持 WEB UI 禁用 Browse Directory 页面;
  • 支持DN jmx获取CompileInfo信息。
3.2 架构升级
由于3.x和2.6版本的代码变化较大,合入风险、周期、代价逐渐加大,甚至一些 patch 几乎无法合入;内部的一些优化和改动,也不易推入社区,整个环节存在脱节。于是我们调研和选型了3.3.1版本进行升级。针对线上集群的情况,我们准备了迁移升级和原地升级两套方案。优先挑选了几个中等规模的业务集群进行升级,验证了3.3.1版本在线上的大规模稳定运行,并基于升级后的3.3.1版本进行二次优化:
  • 避开慢节点;
  • 避开慢盘;
  • 优化 Balance 请求 Standby NameNode;
  • 优化 DN DirectoryScanner 效率和 IO 影响;
  • 支持 DN 快速感知 blk 文件变化;
  • 优化心跳逻辑,减少不必要循环;
  • 删除 Block 流程锁优化功能,减少占锁时间,避免长时间占锁影响性能;
  • 支持 Balance 跳过回收站数据。
3.3 抗风险能力建设
除了稳定性和性能优化,我们从风险预防和治理两个维度,对HDFS进行了大量抗风险能力建设,提升数据和服务安全性:
  • 支持 HDFS 超级账户白名单;
  • 支持 path 禁用特殊字符;
  • 支持禁用1副本;
  • 支持大目录 DU/Count 跳过鉴权;
  • 支持 Owner 设置 Quota,方便 job 层面限制中间产生大目录;
  • HDFS 的自建 zk 迁至云平台;
  • HDFS 机器禁用 SWAP;
  • 制定极端故障预案,覆盖 NN 机器故障、NN元数据目录被误删、JN 机器故障/替换、ZK 路径被删、ZK 服务不可用等场景。

04

精细化运营

随着业务数据量的增长,我们面临着三个方面的挑战:
  1. 集群长期处于较高水位,存储压力大,业务成本高;
  2. 个别业务超预算占用严重,挤占其他业务存储资源,预算机制无强力管控;
  3. 零采购且机器过保率逐年升高。
为了解决这些问题,我们从 HDFS智能元仓、预算管控两个方面,对集群资源进行精细化管控。
4.1 HDFS智能元仓
元仓作为 HDFS 精细化运营入口,提供数据可视化、风险提醒、智能决策、效率和进展跟进等能力。
基于元仓,可以方便快速的识别到 HDFS 坏盘、工单流、异构、过保、版本差异、副本分布、冷热分布、存储量分布、预算占用等问题。
4.2 预算管控

针对超预算的业务,我们拉通了业务方负责人和 HDFS 管理人员,建立了 HDFS 空间管控共治群。同时也对业务数据每日使用详情,产出分析报表,帮助用户快速识别 HDFS 用量情况。经过一段时间的共治,业务累计优化释放了数十 PB 空间。

05

统一存储

CubeFS 是一套兼容 HADOOP 接口的分布式文件系统,作为 OPPO 内部主推的统一存储系统,在 AI 等领域已经大规模落地 。它由如下两部分构成:
数据存储层
存储层 CubeFS EC是 OPPO 自研的分布式纠删码存储系统,成本较低,支持 EB 级规模。
数据加速层
加速层采用两级 Cache 设计:
  • 第一级是计算节点端的本地 Cache(计算节点需提供本地磁盘),节省计算和远程访问的带宽,提升本地读写性能;
  • 第二级是高性能的分布式 Cache,主要解决一级 Cache 容量有限和不能共享的问题。
我们基于内部 HDFS 的数据热度分布,将统一存储方案落地分为四个阶段:
  • s1:CubeFS EC 灰度,初步替代旧的冷存底座;
  • s2:CubeFS EC 成为唯一冷存底座;
  • s3:CubeFS 灰度,承接部分温热数据;
  • s4:CubeFS 统一存储,完全替代 HDFS。
我们优先上线了冷存 CubeFS EC,用户入口统一集成到内部资产管理平台,实现生命周期和冷存周期的双重设置和集中管控;覆盖了一次性搬迁和滚动搬迁两种主要业务降冷场景;屏蔽底层复杂流程,简化用户接入,一键降冷。

上线至今,HDFS 已降冷数百 PB 到 CubeFS EC,大幅节省用户存储成本。目前,我们正逐步推进 s3 阶段的落地。

06

问题案例

由于早期的 HDFS 集群版本低、管理和运营不规范,我们踩了大量的坑。经过长期的治理和优化,线上 HDFS 集群的规范性、稳定性和性能得到大幅提升。
6.1 RPC问题
维护集群的过程中,nn rpc卡顿问题是个比较常见的问题。
(1)大查询
查看审计日志,发现有业务表被大量扫描,影响了集群 rpc,kill 掉 job 后恢复。

(2)中间 staging 产生大量 blocks

job 中间 staging 数据产生大量 blocks 影响 rpc 有两种情况:
  • 第一种是大量删除
  • 第二种场景是块增长非常快,nn 处理不过来

我们对集群 rpc 和 dn 块汇报等参数进行了调优;同时和引擎侧配合支持了对 job目录设置quota,限制不合理的中间目录使用;上线 TraceId 功能,方便快速定位 jobid。

(3)实时 flink checkpoint hdfs 集群调优。

内部 flink 的 checkpoint 由单独的HDFS集群进行存储,每个任务只保留几个最近的目录,过期的会自动清理掉。因此该集群存储的数据量不大,但是IO比较密集。这个集群存在严重的异构问题,小盘节点经常掉线,我们做了异构治理,踢掉小盘机器,解决了频繁掉线问题。针对突发流量增多,导致的 RPC 卡顿的情况,对集群进行参数调优,增大handler、调整 NN 日志级别、开启异步 auditlog 等操作,性能得到恢复。
6.2 ZK问题
HDFS 集群用到的 zk 大多数都是 CDH 上自建的,长期以来存在如下痛点和风险:缺少监控和专业运维保障、HDFS 服务端 zk 和客户端混用,影响服务 HDFS 服务稳定性。线上出现过几次影响 HDFS 的案例,我们对 zk 进行治理,客户端使用的 zk 和 HDFS 服务端分开,服务端 zk 全部由 CM 迁至云平台专业看护。

(1)zk故障导致zkfc挂掉

早期的 hdfs zk 是 cm 上自建的,我们查看 zkfc 日志发现 zk 连接有问题,坏的时间点 zk 在做 sync,落盘很慢,影响到客户端访问。我们优先恢复了 zkfc 服务,增加 zk 相关监控,进行机器维修。

(2)zk path 被误删

线上某集群的 zkfc 用到的 zk path 发生过被误删,整个恢复流程如下:

1.先停止 snn 上的 zkfc2.再停止 ann 上的 zkfc3.snn 机器上执行 hdfs zkfc -formatZK 4.重启 ann 上的 zkfc5.检查 ann 机器的 zkfc 日志和进程6.重启 snn 上的 zkfc7.检查 snn 机器的 zkfc 日志和进程

(3)zk 导致主备切换

线上 HDFS 用到的 zk 版本都是 3.4.5 的,HDFS 客户端有个动态识别集群的功能和 zkfc 用的 zk 是同一组地址,会有大量短链接产生,线上发生过一起 zk sessionid 被 close 导致 HDFS 切主问题。

这个是历史遗留的 zk 使用不当问题,较难从客户端去入手治理,于是我们把 HDFS 服务端的自建 zk 统一迁移到了云平台 zk,和客户端 zk 隔离,迁移流程如下:

1.云平台上申请一组新的 zk2.先停止 snn 上的 zkfc3.再停止 ann 上的 zkfc4.修改 hdfs-site.xml 里面的 ha.zookeeper.quorum 参数,替换为新的 zk 地址,并备份老的 zk 地址5.更新配置文件不重启6.snn 机器上执行 hdfs zkfc -formatZK 7.重启 ann 上的 zkfc8.检查 ann 机器的 zkfc 日志和进程9.重启 snn 上的 zkfc10.检查 snn 机器的 zkfc 日志和进程
6.3 DN退役问题
在日常运营中,坏盘维修、集群间机器腾挪、缩容等场景都会进行 dn 退役。退役过程我们也遇到过一些退役卡住、影响 rpc 性能、dn 打掉线等问题。

(1)阻塞退役

  • 租约未释放
退役节点 namenode 日志会打印下面日志,搜索如下日志,可以发现 blockId。
根据 blockId 找出文件路径(高版本直接使用 hdfs dfsadmin -listOpenFiles  -blockingDecommission 查找),释放租约即可。
  • 副本数不一致

不存在租约未释放问题,hdfs 上查看文件是 2 副本存放,但是 Expected 是 3。设置副本数变为 3,问题解决。

  • snn 上 dn dead 阻塞退役
退役节点在 ann 退役成功。
snn 退役卡住。
查看退役卡住的 block,发现这些 block 有1个共同的 dn 副本节点,在 ann 上是活着的,snn 上是 dead 的,查看日志发现大量 Direct buffer memory 报错,重启该 dn 后,问题解决。
  • snn 上缺失 dn 阻塞退役
ann 已经正常退役,snn 退役卡住。
排查阻塞的 block,发现 rack 信息正常,文件租约正常,但是在 snn 上缺失,ann 和 snn 上 Live Nodes 个数不一致,重启该 dn 后,问题解决。
  • 机架错误阻塞退役
ann 已经退役完毕,dn 是活着的,但是 snn 看 dn 卡着不动。
查看 blocks 都指向同一个 dn 节点,机架是 rack03,复查 ann 和 snn 的配置文件里是 rack02。查看 ann 和 snn 进程启动时间,发现 ann 未重启还是 rack03, 而 snn 最近重启过,加载了机架文件是 rack02。因此 snn 退役不掉,因为 rack 数不对(3 个 rack02),修正 rack 信息后,问题解决。

(2)退役节点导致 dn 掉线

某集群缩容时,引发多个 dn 掉线。分析发现掉线的这批 dn 都是较满的节点。
但是集群整体空闲,写入也不高,仅掉线的 dn 的 io 高,说明大量写入过度集中在这批 dn,这种写入请求分布不符合副本放置策略。
排查集群 rack 信息,发现只剩 2 个 rack,且掉线的机器都分布在 rack02,rack02 机器很少,恢复至 3 个 rack,并控制每个 rack 内机器数均衡,问题得到解决。

(3)退役引起 rpc 毛刺

退役一批 dn,监控 rpc 指标有均匀的毛刺,调大 nn 的退役检测频率,问题解决。
6.4 DN掉线问题

(1)坏盘掉线

早期的一些集群配置参数不合理,坏盘容忍值设为 0,坏盘直接挂掉 dn,调大该参数后问题修复。

(2)Direct buffer OOM

dn 掉线但是进程是活着的,日志里显示 block report 失败,且有大量OutOfMemoryError: Direct buffer memory 日志。
分析报错的 java.nio.Bits 代码,显示调用了  System.gc() ,而 dn 启动命令里开启了 +DisableExplicitGC 会影响 System.gc() ,容易引发 OOM 问题。去掉该参数重启后,未在复现。

(3)锁问题

线上 2.6 版本时,遇到过 dn 经常掉线的问题。
抓取异常期间 dn 堆栈进行分析发现锁被占着,影响了 jmx。
经过几轮抓取,发现所有的问题都指向了 FsVolumeImpl 类。
这个类大量使用 synchronized。
我们对比分析了高版本代码,对这个类进行了锁优化,优化后问题未在复现。
6.5 丢块问题
missing block 也是比较常见的问题,一般伴随着机器坏盘或者坏道导致,也有可能客户端误报。

(1)不可修复

线上遇到过双副本文件 missing block 的问题,1个副本 dn 坏盘了,另1个副本 dn 坏道了。登录坏道机器查看,同一个 data dir 下只有这个 block 不能拷贝,报错 Input/output error,其他 block 都可以正常拷贝,且这个机器并未被报告为坏盘。
检查 dmesg 发现该盘有错误日志。
因此我们增加了基于 dmesg 和 jmx 的坏道坏盘检测程序,并结合工单系统,实现了 dn 自动化维修。及时发现机器故障,保障数据安全,减少人力成本。

(2)可修复

missing block 也不一定不可修复,一些机器无法登陆或者 I/O error,重启后可能会恢复正常,甚至也可能是客户端误报导致。
missing block 的文件租约正常,三个 dn 上的 blk 和 meta 文件的时间戳和 md5 值完全一致,dn 无错误日志,都是成功接收。查看 reportBadBlocks 源码有两处调用,dn 上报和客户端上报。dn 上报会有一些明确的日志打印出来,但是三个 dn 没有相应日志,都是成功日志,排除 dn 上报。怀疑是客户端上报。将 blk 和 meta 文件拷贝到另外一台新的 dn 的数据目录下,重启新 dn 后问题修复。
6.6 balance问题

(1)balance优化

某 HDFS3 集群 balance 慢,balance 脚本设置了 Top60 最满和 Top100 最空闲节点进行 balance,看日志发现实际 balance 时候,一些空闲的节点也会做作为 source。调整脚本逻辑 source 和 target 个数相当,开启 balance 跳过小块和回收站,上线后满 dn 节点空间快速下降。
对比优化前后,balance 效果提升了 2 倍。
6.7 任务读写变慢

(1)IO 负载问题

Hadoop 服务混部在一起,用户任务大量占用 IO、磁盘故障、磁盘冗余空间分布不均等都会影响到 HDFS 读写性能。针对这些问题,引擎侧在任务调度上进行了优化限制、HDFS 侧上线了社区的避开慢盘和避开慢节点功能,同时严格控制集群水位,进行定期均衡,避免分布不均,可写磁盘过少问题。

(2)机房网络问题

我们也遇到过一次机房网络问题导致的 HDFS 写入慢问题。排查发现所有的 dn 的指标PacketAckRoundTripTimeNanosAvgTime 都慢,进一步排查慢的集群同属于一个机房,其他机房的 HDFS 集群正常无影响,判断是机房网络出了问题,联系相关人员排查修复后,HDFS 恢复正常。

(3)节点坏道

线上也遇过 dn 坏道,SendDataPacketTransferNanosAvgTime 异常,引发用户 job 慢,退役故障节点后,任务性能恢复。

07

未来规划

经过研发、运维、业务三方的紧密合作,整个HDFS集群的稳定性、性能、安全性得到大幅提升。目前HDFS冷数据已大规模迁至CubeFS,未来我们会继续推进温热数据的迁移,最终实现统一存储的目标。
作者介绍

Xiaolong Liu  OPPO高级后端工程师

负责OPPO大数据离线存储HDFS的优化与架构演进。

END
About AndesBrain

安第斯智能云

安第斯智能云(AndesBrain)是服务个人、家庭与开发者的泛终端智能云,致力于“让终端更智能”。安第斯智能云提供端云协同的数据存储与智能计算服务,是万物互融的“数智大脑”。
安第斯大模型(AndesGPT)是OPPO自主训练的、个性专属大模型与智能体。作为驱动OPPO公司AI战略的核心引擎,安第斯大模型全面赋能OPPO智慧终端,持续构建知识、记忆、工具、创作能力,并通过与终端结合的AI智能体和多模态对话范式,给用户带来全新的个性专属智能体验。
基于AndesGPT打造的全新小布1.2 Beta版本目前公测中,欢迎体验。

本文分享自微信公众号 - 安第斯智能云(OPPO_tech)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部