Delta Lake调研:Delta Lake使用案例

本文详述了DeltaLake在Soul的应用,如何从传统离线ETL模式转型到实时数仓,提升了数据处理速度。面临数据倾斜、动态模式更新和数据重复等问题,Soul采取了相应解决方案,包括动态分区、元数据管理和调整SparkKafka偏移量提交机制。此外,还探讨了DeltaLake在CDC场景下的应用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

Delta Lake是一个基于云对象存储的表存储工具,它实现了lakehouse的构想。Delta Lake可以解决工业领域数据产生,获取,分析等涵盖企业数据分析场景下,数据生命周期内的所有问题,因而有着广阔的使用前景。

上一篇博客Delta Lake调研:Delta Lake是什么【2】Lakehouse和data warehouse、data lake的区别中,介绍了数据存储工具随需求变化的变化,其中涉及到DataBase、DataWarehouse、DataLake以及Lakehouse的区别与联系。相信大家已经明白Delta Lake作为一款数据存储工具产生的背景以及解决的问题与其他数据存储工具有何区别。这篇博客将就Delta Lake 的使用案例来具体分析使用Delta Lake进行数据分析的优势所在。

DeltaLake在Soul的应用实践

这部分内容参考「知乎帖子」Delta Lake在Soul的应用实践,此帖子转自「阿里巴巴开发者社区帖子」DeltaLake在Soul的应用实践。在这一案例钟Soul没有使用Databrick公司开源的Delta Lake而是使用的阿里云的EMR Delta。

传统离线数仓模式下,日志入库前首要阶段便是ETL,然而这产生了如下问题:

  • 天级ETL任务耗时久,影响下游依赖的产出时间
  • 凌晨占用资源庞大,任务高峰期抢占大量集群资源
  • ETL任务稳定性不佳且出错需凌晨解决、影响范围大。

为了解决天级ETL逐渐尖锐的问题,所以这次我们选择了近来逐渐进入大家视野的数据湖架构,基于阿里云EMR的Delta Lake,我们进一步打造优化实时数仓结构,提升部分业务指标实时性,满足更多更实时的业务需求。

使用DeltaLake之前

传统离线数仓模式下,日志入库前首要阶段便是ETL,Soul的埋点日志数据量庞大且需动态分区入库,在按day分区的基础上,每天的动态分区1200+,分区数据量大小不均,数万条到数十亿条不等。下图为我们之前的ETL过程,埋点日志输入Kafka,由Flume采集到HDFS,再经由天级Spark ETL任务,落表入Hive。任务凌晨开始运行,数据处理阶段约1h,Load阶段1h+,整体执行时间为2-3h

在这里插入图片描述

这里存在的问题集中在:

  • 天级ETL任务耗时久,影响下游依赖的产出时间
  • 凌晨占用资源庞大,任务高峰期抢占大量集群资源
  • ETL任务稳定性不佳且出错需凌晨解决,影响范围大

使用Delta Lake之后

数据由各端埋点上报至Kafka,通过Spark任务分钟级以Delta的形式写入HDFS,然后在Hive中自动化创建Delta表的映射表,即可通过Hive MR、Tez、Presto等查询引擎直接进行数据查询及分析。在这里插入图片描述
Delta Lake虽然解决了以往构架中过长的数据载入,实现实时数据载入,但却同时产生了其他问题。

  • 埋点数据动态分区数据量分布不均导致的数据倾斜问题
  • 应用层基于元数据的动态schema变更
  • Spark Kafka偏移量提交机制导致的数据重复
  • 查询时解析元数据耗时较多
  • 关于CDC场景

数据倾斜问题

Soul的埋点数据是落入分区宽表中的,按埋点类型分区,不同类型的埋点数据量分布不均,例如:通过Spark写入Delta的过程中,5min为一个Batch,大部分类型的埋点,5min的数据量很小(10M以下),但少量埋点数据量却在5min能达到1G或更多。数据落地时,我们假设DataFrame有M个partition,表有N个动态分区,每个partition中的数据都是均匀且混乱的,那么每个partition中都会生成N个文件分别对应N个动态分区,那么每个Batch就会生成M*N个小文件。
在这里插入图片描述
为了解决上述问题,数据落地前对DataFrame按动态分区字段repartition,这样就能保证每个partition中分别有不同分区的数据,这样每个Batch就只会生成N个文件,即每个动态分区一个文件,这样解决了小文件膨胀的问题。但与此同时,有几个数据量过大的分区的数据也会只分布在一个partition中,就导致了某几个partition数据倾斜,且这些分区每个Batch产生的文件过大等问题。
在这里插入图片描述
解决方案
Soul在将DataFrame的内容载入分区时,先通过动态分区,通过加盐方式打散到多个partition解决了小文件膨胀的问题。

动态模式更新

数据湖支持了动态schema变更,但在Spark写入之前,构造DataFrame时,是需要获取数据schema的,如果此时无法动态变更,那么便无法把新字段写入Delta表,Delta的动态schena便也成了摆设。埋点数据由于类型不同,每条埋点数据的字段并不完全相同,那么在落表时,必须取所有数据的字段并集,作为Delta表的schema,这就需要我们在构建DataFrame时便能感知是否有新增字段。

解决方案
Soul额外设计一套元数据,在Spark构建DataFrame时,首先根据此元数据判断是否有新增字段,如有,就把新增字段更新至元数据,以此元数据为schema构建DataFrame,就能保证我们在应用层动态感知schema变更,配合Delta的动态schema变更,新字段自动写入Delta表,并把变化同步到对应的Hive表中。

Spark Kafka偏移量提交机制导致的数据重复

使用Spark Streaming时,会在数据处理完成后将消费者偏移量提交至Kafka。偏移量提交时机为下一个Batch开始时,并不是当前Batch数据处理完成后就提交。这产生了一个问题:假如一个批次5min,在3min时数据处理完成,此时成功将数据写入Delta表,但偏移量却在5min后(第二个批次开始时)才成功提交,如果在3min-5min这个时间段中,重启任务,那么就会重复消费当前批次的数据,造成数据重复。

解决方案

  1. StructStreaming支持了对Delta的exactly-once,可以使用StructStreaming适配解决。
  2. 可以通过其他方式维护消费偏移量解决。

DeltaLake实现CDC

见「阿里巴巴云开发者社区帖子」数据湖构建服务搭配Delta Lake玩转CDC实时入湖

Change Data Capture(CDC)用来跟踪捕获数据源的数据变化,并将这些变化同步到目标存储(如数据湖或数据仓库),用于数据备份或后续分析,同步过程可以是分钟/小时/天等粒度,也可以是实时同步。传统的CDC方案分为侵入式(intrusive manner)和非倾入性(non-intrusive manner)两种。阿里云提供了一种新的CDC解决方案,利用自研的Streaming SQL搭配Delta Lake可以轻松实现CDC实时入湖。这套解决方案同时通过阿里云最新发布的数据湖构建(Data Lake Formation,DLF)服务提供一站式的入湖体验。
在这里插入图片描述
Streaming SQL和Delta Lake实现CDC分为四个步骤:

  1. 创建两个表格(kafka_cdctest和delta_cdctest)
  2. 在kafka_cdctest上创建一个扫描Scan
  3. 以delta_cdctest为目标表格创建流cdctest_job
  4. 使用streaming sql将数据导入Delta Lake

Delat Lake调研总篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值