乐趣区

关于flink:融合趋势下基于-Flink-Kylin-Hudi-湖仓一体的大数据生态体系

本文由 T3 出行大数据平台负责人杨华和资深大数据平台开发工程师王祥虎介绍 Flink、Kylin 和 Hudi 湖仓一体的大数据生态体系以及在 T3 的相干利用场景,内容包含:

  1. 湖仓一体的架构
  2. Flink/Hudi/Kylin 介绍与交融
  3. T3 出行联合湖仓一体的实际

一、湖仓一体的架构

数据湖和数据仓库

既然聊湖仓一体,咱们先理解一下什么是湖,什么是仓。数据湖是一个很老的概念,在近些年又被热炒。业界对于数据湖到当初也没有一个对立的定义。AWS 是最早在云上推出数据湖解决方案的云服务提供商,在这里咱们便援用 AWS 对数据湖的定义:“数据湖是一个集中式的存储库 ,容许存储任意构造的数据并且能将它利用于大数据处理,以及进行实时剖析和机器学习等相干的利用场景。”同样咱们也借助于 AWS 对数据仓库做这样的定义:“ 数据仓库是信息的一个地方存储库。”这里的信息是可对其进行剖析,并且可做出更理智的决策。

这个定义还有具体的开展。AWS 这张图通过展现了从湖到仓的数据流向的关系,来演示数据湖与数据仓库之间的区别和分割。首先数据最后是存在于数据湖或是数据库中,而后通过数据筛选和筹备之后,就会流向数据仓库来进行一些高价值的剖析。这个比照表格很直观的从数据、Schema、性价比、数据品质、用户和剖析这 6 个维度给出数据湖和仓的比照。

湖仓一体的先例

往年咱们据说阿里巴巴提及的“湖仓一体”的概念。不晓得大家有没有想过湖仓一体在业界是否有胜利的先例?我集体认为是有的。往年(2020 年)9 月份,一家叫 Snowflake 的公司在纽交所上市。Snowflake 是一家做云数仓的公司,基于云厂商提供的基础设施提供 SaaS 平台,面向中小企业提供数据的托管和剖析服务。Snowflake 自称本人是一家云数仓公司,并且在 16 年的数据顶会上发表了一篇论文来介绍他们弹性数仓的架构以及一些技术的细节。

Snowflake 其实是基于云上的对象存储,一份存储多份计算,并且计算与存储拆散的这样一套架构。其实这就是 AWS 以及当初支流云厂商所主推的这个数据湖的架构。Snowflake 上市的首日,他的市值就飙升到了 700 亿美元的规模。所以我集体认为 Snowflake 能够算是履行湖仓一体的一个最胜利的先例。大家能够去理解一下刚谈到的这篇论文。我摘出了这 5 个点来和大家做简略的分享:

  • 首先第一点,是没有走当初传统数仓所广泛应用的 Shared-Nothing 这个架构,而是 转向 Shared-Data 这个架构。
  • 其次,论文中重点提及的 存储和计算拆散,是文中我感觉最有价值的一个观点。他提出了对立存储而后弹性计算的这样一个观点。
  • 第三,数仓及服务 是我认为他们商业化最胜利的点。它将数仓提供了一个 SaaS 化的体验,并且摒弃传统上大家认为的数仓是大而重的偏见。
  • 第四,高可用 这一块是进步用户体验和容错的很要害的一个点。
  • 最初,结构化延长到半结构化 这一块曾经体现过后他们可能摸索湖上通用数据的能力。

这尽管是 16 年的一篇论文,但外面的观点并不算古老并且依然值得咱们去学习。后续咱们会简略介绍几个被咱们排汇并且将会去实际的一些点,而且这些点也是 T3 出行在实现湖仓一体上很要害的中央。

Shared – Nothing 架构的劣势

首先,作为一个被很多传统的数仓广泛应用的一个架构,Shared-Nothing 还是有一些架构上的劣势:

  • 第一点,Table 上的数据能够进行跨节点的程度分区,并且每个节点有本人的本地存储。每个节点的计算资源,只关注解决每个节点本人存储的数据。
  • 所以它的另一个长处就是它的解决机制绝对简略,是数仓畛域很典型的一个架构。

Shared – Nothing 架构的劣势

这套架构其实也有一些有余的中央:

  • 最大的一点就是他耦合了计算与存储资源,
  • 同时也带来第二个问题,就是弹性有余。具体能够体现在 2 个方面。

    • 集群在扩缩容的时候,数据须要被大量重散布
    • 没有方法简略地卸载不必的计算资源
  • 第三个问题是,耦合计算和存储资源同时也就造成了它的可用性是相当无限的。因为这些称之为有状态的计算,所以在失败或者是降级的时候会显著影响性能,并会导致服务整体不可用的状态。
  • 最初是同构的资源与异构的负载的问题。因为在数仓的场景中,咱们有很多异构的负载,比如说批量的加载,查问,报表的大规模计算剖析等等。但 Shared-Nothing 架构的资源是同构的,所以这带来两者之间的碰撞。

Shared – Data 架构

基于这些问题,Snowflake 提出了一个叫做 Multi-Cluster Shared-Data 架构。这里咱们对官网的图做了一个简略的微调。

  • 这个架构的第一个劣势是它 没有数据孤岛,是一个对立的存储。这也就可能将存储从计算中进行解耦。
  • 第二个劣势是基于当初的对象存储去 包容结构化和非结构化数据
  • 第三,它的集群规模是能够 弹性作用 的。
  • 第四,上述特色同时也带来了按需计算这个 低成本 长处。

接下来咱们以分层的模式来 review 这个架构。从整体上来看,它的构造大抵分为三个档次。

  • 最底层是云厂商提供的对象存储,也就是用户的存储。
  • 中间层是多用途多份的计算集群。
  • 再往上是数据湖的治理服务,它存载的是一个大的 SaaS 化的平台,是对整个底层存储以及计算集群的治理的角色。

Shared – Data 的继续高可用

接下来一个点是这个架构的高可用。这里能够简略合成为 2 个方面。第一个是失败容错,第二个是在线降级。

  1. 首先,作为一个 SaaS 化的利用,它的容错性是须要体现在整体架构上。这里咱们同样分层来回顾一下。

    • 最底层的存储层利用了云厂商的对象存储能力,他自身是一个跨核心复制以及靠近有限扩容的一个机制,所以用户根本无需关怀。
    • 再往上是多元的计算集群。每个计算集群是在同一个数据中心内,来保障它网络传输的性能。这里就提到一个问题,有可能某一个计算集群会有节点失败的问题。如果在一次查问中有一个节点失败,这些计算节点会将这个状态返回下面的服务层。服务层在承受这个失败后,会将这个计算再次传递到可用的节点中进行二次查问。所以 Shared-Data 存储和计算拆散的这种架构上节点近乎是无状态的计算。这种架构的一个节点失败就不是一个十分大的问题。
    • 再往上服务层对于元数据的存储也是利用了对象存储的这个能力。所以这个服务层基本上能够看做是无状态的服务。
    • 最上层是一个负载均衡器,能够进行服务的冗余和负载的均摊。

  1. 第二点在线降级这一块次要利用两个设计,其实这也并不是很新鲜的做法。一个是在计算层和服务层的多方面的映射,而后灰度的切换。这里能够看到在计算层是分多版本的,并且这些版本之间会共享本地的 Cache。服务层的元数据管理也是在多方面共享。这其实也是架构内的子 Shared-Data,对于多版本之间的数据共享能做到再降级和平滑灰度的能力。

接下来我的共事(王祥虎)会跟大家介绍这 3 个框架以及它们是如何交融并最终撑持 T3 湖仓一体的实际。在介绍第二个议题前他会先介绍咱们的主框架,Hudi 和 Kylin 框架,而后再介绍他们三者之间是如何两两交融。最初再介绍 T3 是如何构建湖仓一体的。

二、Flink/Hudi/Kylin 介绍与交融

Hudi

首先来理解一下 Hudi 是什么。Hudi 最后是由 Uber 的工程师为了满足他们的数据分析需要设计开发的一个数据湖框架。它于 2019 年 1 月份退出到 Apache 孵化器,并于 2020 年 5 月顺利毕业,成为 Apache 的顶级我的项目。Hudi 的名字来源于 Hadoop Upserts Deletes and Incrementals 的缩写。也就是说,Hudi 是一个反对插入、更新、删除、以及增量解决的数据湖框架。除此之外,它还反对事务性 ACID 增量解决、存储管理和工夫治理。Hudi 可能治理云上超大规模上百 PB 的剖析型数据集,对于所有的云服务都开箱即用,十分的不便,而且曾经在 Uber 外部稳固运行了靠近 4 年。

下图是 Hudi 的插件化架构。咱们能够看到,Hudi 在存储、数据处理引擎、表类型、索引类型、查问视图和查问引擎方面都有比拟宽松的反对。也就是说,他不与某一个组件绑定。

  • 在存储方面,Hudi 能够反对 HDFS,OSS 和 S3。
  • 在数据处理引擎方面,Hudi 反对 Flink 和 Spark。Java 和 Python 客户端曾经在社区反对中。Hudi 反对两种表,COW 和 MOR,这两种表别离对应低提早的查问和疾速摄入两种场景。
  • 在索引方面,Hudi 反对 Bloom 和 HBase 等 4 种索引类型。底层用了 Parquet 和 Avro 存储数据,社区还正在做 ORC 格局的反对以及 SQL 反对,置信不久的未来会跟大家见面。

Hudi 反对 3 种查问,读优化查问,增量查问和快照查问。而在查问引擎方面,有 Spark、Presto、Hive 和 Impala,实际上一些其余的组件曾经反对了。

上面具体的介绍一下存储模式和视图。

  • 第一个是 Copy On Write 模式,对应到 Hudi 的 COW 表。它是一种偏重低延时的数据查问场景的表,底层应用 Parquet 数据文件存储数据,可能反对快照查问和增量查问两种查问形式。在查问引擎方面,大家能够看到下面有 5 个引擎,他们对快照查问、增量查问和读优化 3 种视图都有不同水平的反对。
  • Merge On Read 表对 Copy On Write 有不同层面的互补,能够看到它侧重于疾速的数据摄入场景。应用 Parquet 文件来存储具体的数据,应用行式 Avro 增量文件来存储操作日志,相似于 HBase WAL。它反对 Hudi 所有 3 种视图,能够看到 Hive,Spark SQL,Spark Datasource, Presto 和 Impala 对于读优化查问都是反对的。而 Hive, Spark SQL 只反对到了快照查问。这种组件反对的信息大家当前能够到官网上查问。

在出行业务中,订单会有领取长尾的属性。也就是说一个订单开始之后,它的领取环节可能会拖的比拟久。换言之,它可能会在这个用户下一次出行前才进行领取(也或者会更久,甚至永远不领取)。这种长尾属性将会导致一个超长的业务闭环窗口,会导致咱们无奈精确预测数据的更新机会。如果存在多级更新的话,链路会比拟长,更新老本也十分的高。

下图是咱们的长尾更新引发的冷数据频繁更新示意图。左侧是业务库,右侧是有依赖关系的 3 张示意表。当业务库有数据更新时,右侧须要更新的数据可能曾经归档到性能绝对较差的设施上,减少数据更新老本。而且如果这次数据更新会引发长链路级联更新的话,这种慢速的 I/O 还会被进一步放大。

数据的可靠性也是数据 ETL 中不可避免的问题。可能因为机器故障或者计算逻辑导致加工解决的数据失真或者齐全不对,就会给经营的决策造成很大的影响。数字提早性方面,在基于 Hive 构件的传统架构中,因为 Hive 短少索引机制,所以数据更新大都会导致数据分区重写,且没有方法原地删除。其次小文件问题会减少 NameNode 存储和查问的累赘,拖慢过程,在肯定水平上减少数据提早性。

Kylin 框架

咱们再来介绍一下这个 Kylin 框架。相比拟 Hudi,大家应该会对 Kylin 绝对相熟一些,它是一个开源的分布式剖析型数据仓库,可能提供 Hadoop/Spark SQL 之上的数据查问窗口。最后是由 eBay 凋谢并奉献到开源社区,可能在亚秒内查问微小的表。它的秘诀其实就是做预计算,针对一个星型拓扑构造数据立方体,估算多个维度组合的度量把后果写出到输出表,对外裸露查问接口实现实时查问,也就是用空间来换取存取时间。

Kylin 在往年的 9 月份公布了 4.0 alpha 版本,这是在 Kylin3 之后一个重大架构降级。应用 Parquet 代替 Hbase 存储,从而晋升了文件的扫描性能,也加重甚至打消了 Hbase 的保护累赘。Kylin4 从新实现 Spark 构建引擎和查问引擎,使得计算和存储拆散,也更加实用云原生的技术趋势。

Flink/Hudi/Kylin 框架之间的交融

随同 Kylin3.1 公布,Kylin 与 Flink 就交融曾经实现。这个个性是在 2019 年实现的,Kylin 与 Flink 的集成开始于去年 1 月,通过 Flink Batch 实现。对于 Hudi 交融,能够说 Kylin 和 Hudi 天生就是兼容的,因为 Hudi 能够将本人裸露成一张 Hive 表,用户能够像读取 Hive 一样应用 Hudi 的数据,这样对 Kylin 会十分敌对。因为 Kylin 能够把 Hudi 当成一张 Hive 表无缝应用数据。Hudi 和 Flink 交融这个个性是我往年对社区的次要奉献。这个两张截图对应 Hudi 和 Flink 交融路上的 2 个里程碑式的 PR。

  • 第一个 Hudi client 反对多引擎,将 Hudi 与 Spark 解耦,让 Hudi 反对多引擎成为可能。
  • 第二个是 Flink 客户端根本实现奉献到社区,让 Hudi 能够真正意义上写入 Flink 数据表。这 2 个改变十分大,加在一起曾经超过了 1 万行的代码,也能够说是往年 Hudi 社区比拟亮眼的一个个性。

Hudi 和 Flink 的交融过程

上面来具体介绍下 Hudi 和 Flink 交融过程。Hudi 本来只反对 Spark 引擎,所以第一步是将 Hudi 与 Spark 解耦之后再去集成咱们想要的引擎。

解耦的难点在于 Hudi 最后没有思考多引擎的反对,所以从数据源读取数据到最终将数据写出到 Hudi 表,RDD 无处不在。连一般的工具类都会应用 RDD 作为根本的操作单元。与 Spark 解耦,咱们评估到他的改变十分的大。其次是 Flink 与 Spark 外围形象上的差别。Spark 认为数据是无限的数据集,而 Flink 认为数据是无界的,是一种数据流。这种形象上的差别导致咱们很难对立出一个通用的形象。

这次改变对于 Hudi 来说是伤筋动骨的,因而咱们决定要优先保障原版 Hudi 的性能和性能,当然也就义了局部 Flink Stream API。让 Flink 来操作 list,而用 Spark 操作 RDD。这样就能够抽取一个泛型进去造成一个对立的形象层。

形象准则:

  1. 对立应用泛型 I、K、O 代替。
  2. 去 Spark 化,形象层 API 都是引擎无关的,难以在形象层实现的,咱们会把它改为形象办法下推到 Spark 子类实现。
  3. 不影响原版,形象层尽量的缩小改变,以保障固定的功能性。
  4. 引入 HoodieEngineContext 代替 JavaSparkContext, 提供运行时的上下文。

上面说 Flink Client DAG,这里次要分了 5 局部,

  • 第一局部是 Kafka Streaming Source,次要用来接管 Kafka 数据并转换成 List<HoodieRecord>。
  • 第二个是 InstantGeneratorOperator, 一个 Flink 算子, 用来生成全局惟一的 instant。
  • 第三是 KeyBy 分区操作,依据 partitionPath 分区防止多个子工作将数据写入同一个分区造成抵触。
  • 第四个是 WriteProcessOperator,这也是咱们自定义的一个算子。这个算子是写操作理论产生的中央。
  • 第五个是 CommitSink,他会承受上游 WriteProcessOperator 发来的数据,依据上游数据判断是否提交事务。

上面是 Flink 更新的代码示例。左侧是原版外面 HoodieWriteClient 简化的版本,
能够看到 insert 函数的入参是 RDD,返回值也是 RDD。右侧形象之后的 abstract 能够看到它的入参变成了泛型 I,返回值变成了 O,有趣味的话大家能够去理解一下。

上面是咱们对 Flink 如何交融的另外一个想法,就是心愿做出一个 streaming source,应用 Flink 构建一个残缺的从 Hudi 表读数据,再写出到 Hudi 表的 ETL 管道。

而后是咱们初步的构想。左侧灰色的图外面有 5 列的 Hudi 元数据。最左侧是 hoodie_commit_time 事务列表。每一个 hoodie_commit_time 对应一个事务,每一个事务对应一批的数据。每一批数据中的每一条记录都会有一个提交的序列号,就是第 2 列 hoodie_commit_seqno 序列号。hoodie_commit_time 和 hoodie_commit_seqno 这种映射关系跟 Kafka 中的分区和 offset 的这种映射关系十分相似。前期咱们可能会基于这种特点实现一个 Hoodie Streaming Source。

基于这 3 个框架之间的交融关系,咱们发现别离用于计算、剖析、存储的这 3 个引擎之间是互相兼容的。并且他们可能反对湖仓一体,向云原生体系聚拢。

三、T3 出行构造湖仓一体的实际

最初咱们来看一看 T3 出行是如何构建湖仓一体的。这是咱们 T3 出行车联网的架构,能够看到是从底向上,从根底反对到下层不停的赋能,并与车企的信息系统、国家信息平台做交互。作为一家车联网驱动的出行公司,咱们收集到了人、车、路等相干的数据,每一种数据都有它本人的利用场景,数据之间并不孤立,互相赋能,独特反对 T3 智慧出行。

这是咱们的存储和计算拆散的数据库架构,整个架构分为了两层,一层是计算层,一层是存储层。

  • 计算层咱们用到了 Flink、Spark、Kylin 和 Presto 并且搭配 ES 做任务调度。数据分析和展现方面用到了达芬奇和 Zeppelin。
  • 在存储层,咱们应用了阿里云 OSS 并搭配 HDFS 做数据存储。数据格式方面应用 Hudi 作为次要的存储格局,并配合 Parquet、ORC 和 Json 文件。在计算和存储之前,咱们加了一个 Alluxio 来减速晋升数据处理性能。资源管理方面我用到了 Yarn,在前期时机成熟的时候也会转向 K8s。

在以后存储计算拆散的趋势下,咱们也是以湖存储为外围,在它四周构建了湖减速湖计算、OLAP 剖析、交互式查问、可视化等等一整套的大数据生态体系。

T3 对 Hudi 的利用场景

上面是咱们 T3 外部对 Hudi 的几个利用场景。

  • 一个是 近实时的流数据管道。咱们能够从左侧通过 Log、MySQL 或者间接读取业务数据的 Kafka,把数据导入到数据管道中,再应用 Flink 或者原版的 DeltaStreamer 将流式数据输出到列表中。

近实时的流式数据处理的 Flink UI 界面上能够看到之前介绍的 DAG 的几个算子都在外面,比方 source、instant_generator 等。

  • 另一个是 近实时的数据分析场景。咱们应用 Hive、Spark 或 Presto 查问数据,并最终用达芬奇或者 Zeppelin 做最终的数据报表。

这是咱们用 Hudi 构建的增量数据管道。最左侧 CDC 数据捕捉之后要更新到前面的一系列的表。有了 Hudi 之后,因为 Hudi 反对索引和增量数据处理,咱们只须要去更新须要更新的数据就能够了,不须要再像以前那样去更新整个分区或者更新整个表。

  • 最初的一个场景是将后面介绍的用 Flink 将线上或者业务数据 订阅 ETL 到 Hudi 表中供机器学习应用。然而机器学习是须要有数据根底的,所以咱们利用 Hudi 将线上的数据增量公布到线下环境,进行模型训练或者调参。之后再将模型公布到线上为咱们的业务提供服务。

退出移动版