作业帮基于 DeltaLake 的数据湖建设实践

简介:作业帮是一家以科技为载体的在线教育公司,其大数据中台作为基础系统中台,主要负责建设公司级数仓,向各个产品线提供面向业务主题的数据信息。本文主要分享了作业帮基于 DeltaLake 的数据湖建设最佳实践。

作者:

刘晋  作业帮-大数据平台技术部负责人

王滨  作业帮-大数据平台技术部高级架构师

毕岩  阿里云-计算平台开源大数据平台技术专家

内容框架:

  • 业务背景
  • 问题&痛点
  • 解决方案
  • 基于 DeltaLake 的离线数仓
  • 未来规划
  • 致谢

一、业务背景

作业帮是一家以科技为载体的在线教育公司。目前旗下拥有工具类产品作业帮、作业帮口算,K12直播课产品作业帮直播课,素质教育产品小鹿编程、小鹿写字、小鹿美术等,以及喵喵机等智能学习硬件。作业帮教研中台、教学中台、辅导运营中台、大数据中台等数个业务系统,持续赋能更多素质教育产品,不断为用户带来更好的学习和使用体验。其中大数据中台作为基础系统中台,主要负责建设公司级数仓,向各个产品线提供面向业务主题的数据信息,如留存率、到课率、活跃人数等,提高运营决策效率和质量。

上图为作业帮数据中台总览。主要分为三层:

  • 第一层是数据产品以及赋能层

主要是基于主题数据域构建的数据工具以及产品,支撑商业智能、趋势分析等应用场景。

  • 第二层是全域数据层

通过OneModel统一建模,我们对接入的数据进行了标准化建模,针对不同时效性的场景构建了业务域的主题数据,提高上层产品的使用效率和质量。

  • 第三层是数据开发层

构建了一系列的系统和平台来支持公司内所有的数据开发工程,包括数据集成、任务开发、数据质量、数据服务、数据治理等。

本次分享的内容主要是面向离线数仓(天级、小时级)解决其生产、使用过程中的性能问题。

二、问题&痛点

作业帮离线数仓基于 Hive 提供从 ODS 层到 ADS 层的数据构建能力,当 ADS 表生成后,会通过数据集成写入 OLAP 系统面向管理人员提供 BI 服务;此外,DWD、DWS、ADS 表,也会面向分析师提供线下的数据探查以及取数服务。

随着业务逐步发展以及对应的数据量越来越多,离线数仓系统突显如下主要问题:

  • ADS 表产出延迟越来越长

由于数据量增多,从 ODS 层到 ADS 层的全链路构建时间越来越长。虽然对于非常核心的 ADS 表链路可以通过倾斜资源的模式来短期解决,但是其实这个本质上就是丢车保帅的模式,该模式无法规模化复制,影响了其他重要的 ADS 表的及时产出,如对于分析师来说,由于数据表的延迟,对于T+1的表最差需等到T+2才可以看到。

  • 小时级表需求难以承接

有些场景是小时级产出的表,如部分活动需要小时级反馈来及时调整运营策略。对于这类场景,随着数据量增多、计算集群的资源紧张,小时级表很多时候难以保障及时性,而为了提高计算性能,往往需要提前预备足够的资源来做,尤其是需要小时级计算天级数据的时候,最差情况下计算资源需要扩大24倍。

  • 数据探查慢、取数稳定性差

数据产出后很多时候是面向分析师使用的,直接访问 Hive 则需要几十分钟甚至小时级,完全不能接受,经常会收到用户的吐槽反馈,而采用 Presto 来加速 Hive 表的查询,由于 Presto 的架构特点,导致查询的数据表不能太大、逻辑不能太复杂,否则会导致 Presto 内存 OOM,且 Hive 已有的 UDF 和 VIEW 等在 Presto 中也没法直接使用,这也非常限制分析师的使用场景。

三、解决方案

问题分析

不论是常规的 ODS 层到 ADS 层全链路产出慢、或者是面对具体表的探查取数慢,本质上都是在说 Hive 层的计算性能不足。从上述场景分析来看:

  • 链路计算慢的原因:由于 Hive 不支持增量更新,而来自业务层数据源的 Mysql-Binlog 则包含大量的更新信息,因此在 ODS 这一层,就需要用增量数据和历史的全量数据做去重后形成新的全量数据,其后 DWD、DWS、ADS 均是类似的原理。这个过程带来了数据的大量重复计算,同时也带来了数据产出的延迟。
  • 数据查询慢的原因:由于 Hive 本身缺少必要的索引数据,因此不论是重吞吐的计算还是希望保障分钟级延迟的查询,均会翻译为 MR-Job 进行计算,这就导致在数据快速探查场景下,查询结果产出变慢。

方案调研

从上面分析来看,如果可以解决离线数仓的数据增量更新问题就可以提高链路计算的性能,而对于数据表支持索引能力,就可以在保障查询功能不降级的前提下降低查询的延迟。

  • 基于 HBase+ORC 的解决方案

解决数据的更新问题,可以采用 HBase 来做。对 RowKey 设置为主键,对各列设置为 Column,这样就可以提供数据实时写入的能力。但是受限于 HBase 的架构,对于非主键列的查询性能则非常差。为了解决其查询性能,需要定期(如小时表则小时级、天级表则天级)将 HBase 的表按照特定字段排序后导出到 HDFS 并存储为 ORC 格式,但是 ORC 格式只支持单列的 min、max 索引,查询性能依然无法满足需求,且由于 HBase 的数据写入一直在持续发生,导出的时机难以控制,在导出过程中数据还可能发生变化,如我们希望导出12月11日21点前的数据作为数据表21点分区的数据就需要考虑版本数、存储容量、筛选带来的计算性能等因素,系统复杂度陡增,同时也引入了 HBase 系统增加了运维成本。

  • 数据湖

数据湖实际上是一种数据格式,可以集成在主流的计算引擎(如 Flink/Spark)和数据存储(如对象存储)中间,不引入额外的服务,同时支持实时 Upsert,提供了多版本支持,可以读取任意版本的数据。

目前数据湖方案主要有 DeltaLake、Iceberg、Hudi。 我们调研了阿里云上这三种方案,其区别和特点如下:

此外,考虑到易用性(DeltaLake 语义清晰,阿里云提供全功能 SQL 语法支持,使用简单;后两者的使用门槛较高)、功能性(仅 DeltaLake 支持 Zorder/Dataskipping 查询加速)等方面,结合我们的场景综合考虑,我们最后选择 DeltaLake 作为数据湖解决方案。

四、基于 DeltaLake 的离线数仓

引入 DeltaLake 后,我们的离线数仓架构如下:

首先 Binlog 通过 Canal 采集后经过我们自研的数据分发系统写入 Kafka,这里需要提前说明的是,我们的分发系统需要对 Binlog 按照 Table 级严格保序,原因下面详述。其后使用 Spark 将数据分批写入 DeltaLake。最后我们升级了数据取数平台,使用 Spark SQL 从 DeltaLake 中进行取数。

在使用 DeltaLake 的过程中,我们需要解决如下关键技术点:

流数据转批

业务场景下,对于离线数仓的 ETL 任务,均是按照数据表分区就绪来触发的,如2021-12-31日的任务会依赖2021-12-30日的数据表分区就绪后方可触发运行。这个场景在 Hive 的系统上是很容易支持的,因为 Hive 天然支持按照日期字段(如dt)进行分区。但是对于 DeltaLake 来说,我们数据写入是流式写入的,因此就需要将流数据转为批数据,即某天数据完全就绪后,方可对外提供对应天级分区的读取能力。

如何界定数据完全就绪

流式数据一般会有乱序的情况,在乱序的情况下,即使采用 watermark 的机制,也只能保障一定时间范围内的数据有序,而对于离线数仓来说,数据需要100%可靠不丢。而如果我们可以解决数据源的有序性问题,那么数据就绪问题的解决就会简化很多:假如数据按照天级分区,那么当出现12-31的数据时,就可以认为12-30的数据都就绪了。

因此,我们的方案拆解为两个子问题:

  • 流数据有序后界定批数据边界
  • 保障流数据有序的机制

首先对于前者,总体方案如下:

  • 设定数据表的逻辑分区字段 dt 以及对应的时间单位信息。

  • 当 Spark 读取某一个 batch 数据后,根据上述表元数据使用数据中的 event time 生成对应的 dt 值,如数据流中 event time 的值均属于T+1,则会触发生成数据版本T的 snapshot,数据读取时根据 snapshot 找到对应的数据版本信息进行读取。

如何解决流数据的乱序问题

不论是 app-log 还是 MySQL-Binlog,对于日志本身都是有序的,以 MySQL-Binlog 举例,单个物理表的 Binlog 必然有序,但是实际业务场景下,业务系统会经常进行分库分表的使用,对于使用分表的场景,一张逻辑表 Table 会分为 Table1、Table2、……几张表,对于离线数仓的 ODS 表,则需要屏蔽掉业务侧 MySQL 分表的细节和逻辑,这样,问题就聚焦为如何解决分表场景下数据有序的问题。

  • 保障分库分表,甚至不同分表在不同集群的情况下,数据写入到 Kafka 后的有序性。即写入 DeltaLake 的 Spark 从某个 topic 读取到逻辑表的数据是 partition 粒度有序的。
  • 保障 ODS 表就绪的时效性,如区分无 Binlog 数据的情况下,ODS 层数据也可以按期就绪。

此处需要对原有系统进行升级改造,方案如下:

如上图所示:某个 MySQL 集群的 Binlog 经 Canal 采集后写入到特定的 Kafka-topic,但是由于写入时按照db和 Table(去分表_*后缀)做 hash 确定 partition,因此单个 partition 内部会存在多个物理表的 Binlog,对于写入 DeltaLake 来说非常不友好。考虑到对其他数据应用方的兼容性,我们新增了数据分发服务:

  • 将逻辑表名(去分表_*后缀)的数据写入到对应的 topic,并使用物理表名进行 hash。保障单 partition 内部数据始终有序,单 topic 内仅包括一张逻辑表的数据。
  • 在 MySQL 集群内构建了内部的心跳表,来做 Canal 采集的延迟异常监控,并基于此功能设置一定的阈值来判断当系统没有 Binlog 数据时是系统出问题了还是真的没数据了。如果是后者,也会触发 DeltaLake 进行 savepoint,进而及时触发 snapshot来保障 ODS 表的及时就绪。

通过上述方案,我们将 Binlog 数据流式的写入 DeltaLake 中,且表分区就绪时间延迟<10mins。

读写性能优化

下面讲下我们在使用 DeltaLake 过程中遇到的性能问题以及对应的解法。

通过 DPP 提高写性能

DeltaLake 支持通过 SparkStreamingSQL 的方式来写入数据。

因为要做记录的合并去重,因此这里需要通过 merge into 的方式写入。DeltaLake 更新数据时分为两步:

  • 定位到要更新的文件,默认情况下需要读取全部的文件和 Spark 内 batch 的增量数据做 Join,关联出需要更新的文件来。  
  • Merge 后重新写入这些文件,把老的文件标记为删除。

如上左图所示,由于 DeltaLake 默认会读取上个版本的全量文件,因此导致写入性能极低,一次合并操作无法在 Spark一个 batch 内完成。

针对这种场景,对 DeltaLake 做了升级:使用 DPP 做分区剪枝来优化 Megre into 的性能,如上右图所示:

  • 分析 Merge-on 条件,得到 source 表中对应到 DeltaLake 表分区字段的字段。
  • 统计得到分区字段的枚举列表。
  • 将上步结果转化成 Filter 对象并应用,进一步过滤裁剪数据文件列表。
  • 读取最终的数据文件列表和 batch 的 source 数据关联得到最终需更新的文件列表。

通过 DPP 优化后,Spark 一个 batch(5min粒度)的处理延迟由最大20mins+ 减少到 最大~3mins,完全消除了过去因为处理时间过长导致延迟不断叠加的问题。

使用 Zorder 提高读性能

在解决了数据的写入性能后,我们又遇到了数据读取性能的问题。

我们使用同样的数据(200亿+),使用 Hive 计算,平均延迟10min+,而使用 DeltaLake 后,平均延迟居然高达~11mins+。分析后发现主要是没有对筛选列使用 Zorder 排序,当开启 Zorder 后,延迟则降低到了~24s,提高了近25X性能。

基于 Zorder 对 DeltaLake 表进行查询优化,主要会涉及两个方面的提升:

  • Dataskipping
  • DeltaLake 会按照文件粒度统计各个字段的 max/min 值,用于直接过滤数据文件。
  • Zorder
  • 一种数据 layout 的方式,可以对数据重排列尽可能保证 Zorder 字段的数据局部性。

Zorder 构建耗时优化

对哪些列开启 Zorder 是按需构建的,常规情况构建时长~30mins,数据倾斜下,构建Zorder 时长高达~90mins。

针对这两种情况,对 Zorder 进行了优化:

  • 常规情况下,对于多列的 Zorder,由多次遍历数据集改为遍历一次数据集来提升构建效率。构建时长从平均~30mins降低到~20mins。
  • 数据倾斜下,对于倾斜列所在的 bucket 做了热点分散,构建时长从平均~90mins降低到~30mins。

总体效果

经过了近半年多的开发和优化,近期基于 DeltaLake 的离线数仓已经上线,重点是提升分析的查询优化,同时针对有小时全量需求的场景,也同样提供了支持,整体看的效果如下:

  • 就绪时间更快:ODS 替换到 DeltaLake 后,产出时间从之前凌晨2:00 - 3:00 提前到凌晨00:10左右,产出时间提前了2个多小时。
  • 能力扩展更广:大数据具备了支持小时全量表的能力,利用 DeltaLake 增量更新的特性,低成本的实现了小时全量的需求,避免了传统方案下读取全量数据的消耗。目前已经应用到了部分核心业务中来,构建小时级全量表,同时时效性上保障从过去的~40mins降低到~10mins。
  • 查询速度提升:我们重点提升的分析师的即席查询效率,通过将分析师常用的数仓表迁移到 Deltalake 之后,利用 Zorder 实现了查询加速,查询速度从过去的数十分钟降低到~3mins。

五、未来规划

随着 DeltaLake 在作业帮的使用,当前还有一些问题有待解决:

  • 提高修数效能。
  • 使用 Hive 时我们可以方便的针对某个历史分区独立修复,但是 DeltaLake 表修数时需要通过回退故障版本后的所有版本。
  • 完全支持 Hive 引擎。
  • 目前我们使用 DeltaLake,主要解决了过去使用 Hive 查询慢、使用 Presto 限制复杂查询的问题,在复杂查询、低延迟上提供了解决方案,但前面提到的 GSCD、Dataskipping 等特性 Hive 还不支持,导致用户无法像使用 Hive 一样使用 DeltaLake。
  • 支持 Flink 接入。
  • 我们流计算系统生态主要围绕 Flink 构建,引入 DeltaLake 后,也同时使用 Spark,会导致我们的流计算生态维护成本加重。

六、致谢

最后,非常感谢阿里云 EMR 数据湖团队,凭借他们在 DeltaLake 中的专业能力和合作过程中的高效支持,在我们这次数据湖迁移过程中,帮助我们解决了很多关键性问题。

原文链接

本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511534.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iLogtail 与Filebeat 性能对比

简介&#xff1a;前段时间, iLogtail 阿里千万实例可观测采集器开源&#xff0c;其中介绍了iLogtail采集性能可以达到单核100MB/s&#xff0c;相比开源采集Agent有5-10倍性能优势。很多小伙伴好奇iLogtail具体的性能数据和资源消耗如何&#xff0c;本文将针对目前业界使用度较高…

如何快速开发 Serverless Devs Package ?

简介&#xff1a;目前&#xff0c;开发者开发 Serverless Package 的流程相对来说是比较简单的。因为在 Serverless Devs 开发者工具中&#xff0c;已经提供了相对完整的脚手架能力&#xff0c;一文了解详情~ 作者 | 江昱&#xff08;阿里云 Serverless 产品经理&#xff09; …

首发苹果 M2!MacBook Pro 正式开售,更像是一个增强版的 A15?

作者 | Ryan Smith 译者 | 弯月出品 | CSDN虽然一年一度的WWDC主要是一个软件发布会&#xff0c;但也总是时不时地给出一些硬件惊喜&#xff0c;今年也不例外。在WWDC22上&#xff0c;苹果公布了用于Mac&#xff08;和iPad&#xff09;平台的第二代苹果系统芯片——M2。这个…

专题实战 | 如何快速构建高质量电商行业搜索?

简介&#xff1a;本文详细介绍如何快速接入智能开放搜索&#xff08;OpenSearch&#xff09;电商行业增强版&#xff0c;助力企业实现高质量搜索效果&#xff0c;提升业务转化率及用户产品体验&#xff01; 电商搜索特点 1. 关键词堆砌 例如&#xff1a;明星同款夏季连衣裙包…

Linux 网络性能的 15 个优化建议!

作者 | 张彦飞allen来源 | 开发内功修炼那么具备了对网络的深刻的理解之后&#xff0c;我们在性能方面有哪些优化手段可用呢&#xff1f;我这里给出一些开发或者运维中的性能优化建议。这些建议都是从书中摘录的。不过要注意的是&#xff0c;每一种性能优化方法都有它适用或者不…

Flink Sort-Shuffle 实现简介

简介&#xff1a;Sort-Shuffle 使 Flink 在应对大规模批数据处理任务时更加游刃有余 本文介绍 Sort-Shuffle 如何帮助 Flink 在应对大规模批数据处理任务时更加游刃有余。主要内容包括&#xff1a; 数据 Shuffle 简介引入 Sort-Shuffle 的意义Flink Sort-Shuffle 实现测试结果调…

「现代C++设计魅力」虚函数继承-thunk技术初探

简介&#xff1a;工作中使用LLDB调试器调试这一段C多继承程序的时候&#xff0c;发现通过lldb print(expression命令的别名) 命令获取的指针地址和实际理解的C的内存模型的地址不一样。那么到底是什么原因呢&#xff1f; 作者 | 扬阜 来源 | 阿里技术公众号 一 问题背景 1 实…

万物互联时代到来,锐捷发布场景化无线零漫游方案

数字化和万物互联时代到来&#xff0c;物联网与 IoT 设备发展迅猛&#xff0c;以往只在办公区域主要由手机等移动设备使用的无线网络&#xff0c;正在接入更多核心业务生产、物流仓储等各类的生产设备。据分析机构 IDC 预测&#xff0c;无线网络优先是当下智能园区网络建设投资…

阿里云田涛涛:高效智能的云,CloudOps让运维更简单

简介&#xff1a;CloudOps:以应用为中心的自动化运维新趋势 12月21日&#xff0c;在阿里云弹性计算年度峰会上&#xff0c;阿里云弹性计算体验与控制系统负责人田涛涛发表了主题为《高效智能的云&#xff0c;CloudOps让运维更简单》的演讲&#xff0c;深度解读了云上运维新趋势…

打造南沙“强芯”,南沙首届IC Nansha大会召开

6月25日&#xff0c;2022 中国南沙国际集成电路产业论坛在广州南沙召开。本次峰会由广州南沙经济技术开发区管理委员会、广州市工业和信息化局主办&#xff1b;支持单位为广州湾区半导体产业集团有限公司、广东省集成电路行业协会、广州市半导体协会&#xff1b;广东省半导体及…

OpenAI开发者大会简介

文章目录 GPT-4 Turbo 昨天晚上 OpenAI的首届开发者大会召开 Sam Altman也做了公开演讲&#xff0c;应该说 这是继今年春天发布GPT-4之后 OpenAI在AI行业又创造的一个不眠夜 过去一年 ChatGPT绝对是整个科技领域最热的词汇 OpenAI 也依靠ChatGPT取得了惊人的成绩 ChatG…

阿里云贾少天:大规模云服务器高效使用及管理实践

简介&#xff1a;本篇内容分享了大规模云服务器高效使用及管理最佳实践。 2021年10月22日&#xff0c;在云栖大会的《云上运维最佳实践》分论坛&#xff0c;阿里云高级技术专家贾少天发表了主题为“大规模云服务器高效使用及管理最佳实践”的演讲&#xff0c;本篇内容根据他的…

发现新视界——视觉计算将如何改变生产方式

简介&#xff1a;本篇内容将从3个部分为读者介绍关于视觉计算如何改变生产方式&#xff0c;进一步阐述可视化业务方面的挑战及阿里云视觉计算的解决方案与优势。 编者按&#xff1a;在2021年10月举办的云栖大会的《数字孪生&Cloud XR技术助力产研创新论坛》上&#xff0c;…

容器监控指南:三剑客轻松实现 Docker 容器监控

作者 | Milan Mahat在本指南中&#xff0c;我们将学习如何使用 docker-compose 在容器中设置 cAdvisor&#xff0c;将其与 prometheus 连接&#xff0c;并通过 grafana 监控服务器的容器。CAdvisor 是一种流行的工具&#xff0c;用于收集容器的信息。它是 prometheus 和 grafan…

N个技巧,编写更高效 Dockerfile|云效工程师指北

简介&#xff1a;云原生时代下软件的构建和部署离不开容器技术。提到容器&#xff0c;几乎大家下意识都会联想到 Docker 。而 Docker 中有两个非常重要的概念&#xff0c;一个是Image&#xff08;镜像&#xff09;&#xff0c;一个是Container&#xff08;容器&#xff09;。前…

TDA-04D8变送器数据上报阿里云

简介&#xff1a;本文将以TDA-04D8变送器作为采集对象&#xff0c;使用海创微联采集控制系统对TDA-04D8变送器进行采集&#xff0c;然后将设备上的毛重、净重、皮重数据采集上传到阿里云物联网平台&#xff0c;阿里云物联网平台将数据实时可视化。 文章分为3部分&#xff1a; …

http ,怎么优雅的拒绝你

作者 | 奇伢来源 | 奇伢云存储典型问题&#xff1a;服务端优雅的拒绝今天分享一个后端编程的实际经验。这个问题来源于对象 S3 后端协议实现的技巧思考。场景&#xff1a;服务端不想接收 http 的 body 的时候&#xff0c;该怎么优雅的拒绝呢&#xff1f;什么意思&#xff1f;对…

企业物联网平台新版公共实例升级企业实例教程

简介&#xff1a;2021年7月30日企业物联网平台重磅升级&#xff0c;发布的新版公共实例支持一键升级企业版实例&#xff0c;本文将为大家介绍一键升级教程 一、企业版实例&#xff0c;企业用户首选 企业物联网平台 提供设备上云必备的基础服务&#xff0c;用户无需自建物联网…

【全观测系列】Elasticsearch应用性能监控实践

简介&#xff1a;本文介绍了应用性能监控的应用价值以及解决方案等。 1、什么是全观测&#xff1f; 要了解全观测&#xff0c;我们先看看传统运维存在哪些问题。 数据孤岛&#xff0c;分散在不同部门&#xff0c;分析排查故障困难&#xff1b;多个厂商的多种工具&#xff0c…

es实战-使用IK分词器进行词频统计

简介&#xff1a;通过IK分词器分词并生成词云。 本文主要介绍如何通过 IK 分词器进行词频统计。使用分词器对文章的词频进行统计&#xff0c;主要目的是实现如下图所示的词云功能&#xff0c;可以找到文章内的重点词汇。后续也可以对词进行词性标注&#xff0c;实体识别以及对…