QCon-OPPO 数据平台 Cloud Lake 降本增效实践
1. 背景
OPPO 从 19 年开始,用了两年时间,以 K8S,容器化为核心,完成了公司混合云建设,并实现 100%在线业务上云。OPPO 的业务,目前覆盖国内,南亚,欧洲,美洲,在国内我们有自己的机房,在海外,更多是和公有云合作 ,有 AWS,Google。 OPPO 的云是朵云上云,与共有云的合作,更多只是采购机器资源,部署我们自己的服务。OPPO 云给我司带来了数亿的降本红利,得到了公司的广泛认可。
目前 OPPO 的数据平台规模, 计算资源近万台,存储接近 1 个 EB,离线任务数近百万,实时任务数千。统计我们过去几年的增速,平均下来,每年大概有 30%的规模增长。 如此的一个规模增长下,系统 SLA 三个 9, 任务 100%准点,是我们必须要保障的,同时,公司希望数据平台能够把过往快速增长的成本降下来。所以 业务快速增长、系统 SLA 和任务准点率保持高水平的前提下,如何进一步降本增效是我们必须要解决的问题。
对于这样一个问题,我们的解法是进行一系列的技术升级,主要包括批流一体、云数融合调度、数据湖存储三个方面。
2. 批流一体
如上图,上半部分,典型的 Lambda 架构。 批流两条计算链路,元数据分开。应用侧的多种 OLAP 引擎,也有各自的存储方法与元数据管理。
我们通常说的批流一体,一般涉及到三个方面的统一,元数据,存储,引擎。这三方面,OPPO 更看重前两点。为了元数据的统一,我们以 HMS 服务为主,同时通过 Waggle-Dance 进行了加固。为了存储的统一,我们引入了 Iceberg ,打破实时数仓,离线数据的存储边界,同时提高数据仓库的实时性。
最近两年,开源界以 Delta, Hudi, Iceberg 为代表的 Data Lake Format 非常流行。他们近实时,ACID 语意,支持快照语回溯等特性,吸引的不少开发者。刚才的介绍,大家也看到了,OPPO 的选择是 Iceberg,其中最重要的是支持 CDC 的近实时特性。 但是近实时的特性在我们做业务推广是,却显得有些鸡肋。离线场景,小时任务可以满足大部分场景的时效要求。实时场景 ,对退化为成本更低的近实时,业务上对延时很难接受。
为了实现 Iceberg 的实时化,我们对它做了一些技术改进,下面分两个场景介绍。
场景一:是数据库的 CDC 入湖场景,需要支持数据变更。大数据领域,解决数据实时写入问题,通查会使用 LSM 结构。因此我们在架构上引入了 Parker,一个支持分布式 LSM 的 KV,在 Iceberg 前,承担数据缓冲。KV 的引入,对基于主键的 upsert 也能够得到比较好的支持。
场景二:基于手机埋点的数据上报,每天的数据上报量非常庞大,万亿级别。 这条链路中,使用了大量的 Kafka 资源。我们实时数仓的链路,Kafka 的数据存储周期是 T+3 ~ T+1 天,这个过程中,我们选择通过 Iceberg,使用效率更高的列式存储,降低 Kafka 的存储水位,使 Kafka 的数据存储周期变为 T+3 小时。既保障实时性,同时又降低 Kafka 存储成本。
3. 云数融合调度
OPPO 每年 30%的算力增长,评估下来,2022 年大概有 8w 核算力缺口。如果不外采,算力缺口是否有补齐途径。有平台经验的伙伴,一般都了解,白天,通常是在线业务高峰。而夜间,往往离线计算会把集群计算资源打的很满,白天的负载,通常在 50%左右。实现潮汐调度,在线、离线算力融合,是我们的必然选择。
实现算力融合,我们并没有完全走云原生的路径,计算资源完全由 K8S 调度。 因为 YARN 的调度逻辑比 K8S 简单,对于大数据任务资源频繁释放回收的场景,效率上远高于 K8S。因此,我们选择了 YARN+K8S 的调度逻辑,在 K8S 上实现 yarn-operator。任务高峰,有 K8S 给大数据集群释放资源,过了高峰期,则自动回收。
云数融合调度中,大家可能会担心一个问题,就是容器释放的算力,性能上是否能够满足计算要求。这里可以得大家看下我们的一些测试。测试对比项是物理机、SSD 容器,SATA 容器,VM 容器。 从测试中可以看到,同等配置条件下,物理机性能最好,SSD 容器和 SATA 容器性能次之。VM 上的容器性能下降的比较厉害。所有,SSD 容器和 SATA 容器性能损耗,是可以接受的。
云数融合调度中,大家通常会面临一个问题,就是如何稳定保障计算引擎的 Shuffle 效率。我们使用的是 OPPO 自研 Shuffle Service。OPPO 自研 Shuffle Service 的初衷,是为了降低大任务的 Shuffle 失败率。我们的平台推出计算账单后,时不时会有用户因为 Shuffle 失败,希望我们减免计算费用。因为要知道 Shuffle 跑失败的任务通常规模不会小,费用可能是成百上千元。从平台的角度,当然不希望任务失败,就减免费用。云数融合中,Shuffle Service 也起到了很好的作用,远程的 Shuffle 服务,有效降低了本地存储压力,在资源扩缩容过程中,也能够保障计算稳定。
这里,可以给大家,看一下 Shuffle Service 的测试数据。 这是 TPC-H ,1TB 数据下的测试结果。Shuffle Service 并不是说对所有的 SQL 任务,都能提高执行效率。但对 Q16,Q21 这样的大任务,效率提升还是非常明显的。 平均下来,大概有 16%左右的提升。
4.数据湖存储
OPPO 的数据存储,经历了三个阶段。
阶段一:全 HDFS 存储。 阶段二: 引入对象存储 。阶段三: 自研 ADLS 数据湖存储。
阶段一到阶段二,主要是将数据通过数据资产平台的周期设定,在达到某个时间点后,自动作为冷数据迁移到对象存储。阶段二到阶段三,则是统一文件,对象存储,由升级后的文件系统解决元数据瓶颈,冷热温分层存储。自研存储,关键技术有多协议适配,分布式元数据,扁平命令空间加速,多级缓存等。下面我逐一做下介绍。
文件系统提供的是层次命名空间视图,整个文件系统的逻辑目录树分成多层,如上图所示,每个元数据节点(MetaNode)包含成百上千的元数据分片(MetaPartition),每个分片由 InodeTree(BTree)和 DentryTree(BTree)组成,每个 dentry 代表一个目录项,dentry 由 parentId 和 name 组成。在 DentryTree 中,以 PartentId 和 name 组成索引,进行存储和检索;在 InodeTree 中,则以 inode id 进行索引。使用 multiRaft 协议保障高可用性和数据一致性复制, 且每个节点集合会包含大量的分片组,每个分片组对应一个 raft group;每个分片组隶属于某个 volume;每个分片组都是某个 volume 的一段元数据范围(一段 inode id ); 元数据子系统通过分裂来完成动态扩容;当一分片组资源(性能、容量)紧接临近值时,资源管理器服务会预估一个结束点,并通知此组节点设备,只服务到此点之前的数据,同时也会新选出一组节点,并动态加入到当前业务系统中。
单个目录支持百万级别容量,元数据全内存化,保证优秀的读写性能,内存元数据分片通过 snapshot 方式持久化到磁盘以作备份及恢复使用。
而对象存储提供的是扁平命名空间;以访问 objectkey 为/bucket/a/b/c 的对象为例,从根目录开始,通过”/”分隔符层层解析,找到最后一层目录(/bucket/a/b)的 Dentry,最后找到的/bucket/a/b/c 对于的 Inode,此过程涉及多次节点间交互,层次越深,性能较差;因此我们引入 PathCache 模块用于加速 ObjectKey 解析,简单做法是在 PathCache 中对 ObjectKey 的父目录(/bucket/a/b)的 Dentry 做缓存;分析线上集群我们发现,目录平均大小约为 100,假设存储集群规模在千亿级别,目录条目也才 10 亿个,单机缓存效率很高,同时可通过节点扩容来提升读性能;在同时支持"扁平"和"层次"命名空间管理的设计,与业界其他系统相比,CBFS 实现得更简洁,更高效,无需任何转换即可轻松实现一份数据,多种协议访问互通,且不存在数据一致性问题。
数据湖架构带来显著的收益之一是成本节约,但存算分离架构也会遇到带宽瓶颈和性能挑战,因此我们也提供了一系列访问加速技术:
一. 多级缓存能力
第一级缓存:本地缓存,其与计算节点同机部署,支持元数据和数据缓存,支持内存、PMem、NVme、HDD 不同类型介质,特点是访问时延低,但容量少.
第二级缓存:分布式缓存,副本数目弹性可变,提供位置感知能力,支持用户/桶/对象级的主动预热和被动缓存,数据淘汰策略也可配置
多级缓存策略在我们的机器学习训练场景有不错的加速效果。
二. 谓语下推操作
另外存储数据层还支持了谓语下推操作,可显著减少存储与计算节点间大量的数据流动,降低资源开销并提升计算性能;
数据湖加速有还很多细致的工作,我们也在持续完善的过程中。
5.展望
最后,结合刚才提到的三点技术方向,说下我们未来的一些规划和展望。
批流一体的计算,我们做到了元数据统一,存储统一。计算引擎统一,是可以积极探索的方向。虽然以 Flink 为代表的计算引擎,不断地宣称自己能做到批流一体,但是从实践角度,一个系统想做得多,往往不能再每个方向上都做到极致。统一的计算引擎我持保留意见,但不排斥这个方向的探索。这点上,我个人更倾于在批、流和交互式计算引擎上有一个公共层,通过这个公共层屏蔽不同引擎带来的适配成本,而非在引擎层实现完全的计算统一。
云数融合调度,目的是实现资源弹性,目前主要通过定时机制实现。因为我们知道业务资源利用规律,把这样的规律通过规则配置到我们弹性策略中。但是,弹性调度应该是更敏捷型,更灵活的,系统可以感知负载情况,自动进行资源的释放和回收。因为日常业务中会经常会有大规模任务重跑,任务突增等情况。这种情况下,灵活自主的扩缩容策略会对我们的业务有更好的帮助。
存储方面,刚才我们提到的冷、热、温分层存储目前还需要用户来定义。如某张事实表数据多久变冷存,某张维表是否一直需要热缓存加速。随着业务的变化,冷数据可能变成热数据,也需要手动做参数调整。其实,数据冷、热、温的划分,可以根据动态监测到的一些指标数据,通过算法自动地进行标识,转化,以达到不同数据使用不同存储介质,进而拥有更合理的存储成本。
最后还想说一点,数据平台我们会持续与云的融合。近年来广泛讨论的 Snowflake ,将数据仓库搬到云上,同时支持多云部署,非常有代表性。我们的产品和能力嫁接到云上,可以更广泛的输出我们的服务。
作者简介
Keung Chau OPPO 数据架构负责人
负责 OPPO 数据平台的建设与技术演进。
获取更多精彩内容,搜索关注[OPPO 数智技术]公众号
版权声明: 本文为 InfoQ 作者【OPPO数智技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/0ec3288f7dd1dc278fe5a73d1】。文章转载请联系作者。
评论