更多技术交换、求职机会,欢送关注字节跳动数据平台微信公众号,回复【1】进入官网交换群

Doris简介

Doris是一种MPP架构的剖析型数据库,次要面向多维分析,数据报表,用户画像剖析等场景。自带剖析引擎和存储引擎,反对向量化执行引擎,不依赖其余组件,兼容MySQL协定。
Apache Doris具备以下几个特点:

  • 良好的架构设计,反对高并发低延时的查问服务,反对高吞吐量的交互式剖析。多FE均可对外提供服务,并发减少时,线性裁减FE和BE即可反对高并发的查问申请。
  • 反对批量数据load和流式数据load,反对数据更新。反对Update/Delete语法,unique/aggregate数据模型,反对动静更新数据,实时更新聚合指标。
  • 提供了高可用,容错解决,高扩大的企业级个性。FE Leader谬误异样,FE Follower秒级切换为新Leader持续对外提供服务。
  • 反对聚合表和物化视图。多种数据模型,反对aggregate,replace等多种数据模型,反对创立rollup表,反对创立物化视图。rollup表和物化视图反对动静更新,无需用户手动解决。
  • MySQL协定兼容,反对间接应用MySQL客户端连贯,十分易用的数据利用对接。
    Doris由Frontend(以下简称FE)和Backend(以下简称BE)组成,其中FE负责承受用户申请,编译,优化,散发执行打算,元数据管理,BE节点的治理等性能,BE负责执行由FE下发的执行打算,存储和治理用户数据。

数据湖格局Hudi简介

Hudi是下一代流式数据湖平台,为数据湖提供了表格局治理的能力,提供事务,ACID,MVCC,数据更新删除,增量数据读取等性能。反对Spark,Flink,Presto,Trino等多种计算引擎。

Hudi依据数据更新时行为不同分为两种表类型:

针对Hudi的两种表格局,存在3种不同的查问类型:

Doris剖析Hudi数据的技术背景
在数仓业务中,随着业务对数据实时性的要求越来越高,T+1数仓业务逐步往小时级,分钟级,甚至秒级演进。实时数仓的利用也越来越广,也经验了多个倒退阶段。目前存在着多种解决方案。

Lambda架构

Lambda将数据处理流分为在线剖析和离线剖析分为两条不同的解决门路,两条门路相互独立,互不影响。
离线剖析解决T+1数据,应用Hive/Spark解决大数据量,不可变数据,数据个别存储在HDFS等零碎上。如果遇到数据更新,须要overwrite整张表或整个分区,老本比拟高。
在线剖析解决实时数据,应用Flink/Spark Streaming解决流式数据,剖析解决秒级或分钟级流式数据,数据保留在Kafka或定期(分钟级)保留到HDFS中。
该套计划存在以下毛病:

  • 同一套指标可能须要开发两份代码来进行在线剖析和离线剖析,保护简单
  • 数据利用查问指标时可能须要同时查问离线数据和在线数据,开发简单
  • 同时部署批处理和流式计算两套引擎,运维简单
  • 数据更新须要overwrite整张表或分区,老本高

Kappa架构

随着在线剖析业务越来越多,Lambda架构的弊病就越来越显著,减少一个指标须要在线离线别离开发,保护艰难,离线指标可能和在线指标对不齐,部署简单,组件繁多。于是Kappa架构应运而生。
Kappa架构应用一套架构解决在线数据和离线数据,应用同一套引擎同时解决在线和离线数据,数据存储在音讯队列上。
Kappa架构也有肯定的局限:

  • 流式计算引擎批处理能力较弱,解决大数据量性能较弱
  • 数据存储应用音讯队列,音讯队列对数据存储有有效性限度,历史数据无奈回溯
  • 数据时序可能乱序,可能对局部对时序要求比拟严格的利用造成数据谬误
  • 数据利用须要从音讯队列中取数,须要开发适配接口,开发简单

基于数据湖的实时数仓

针对Lambda架构和Kappa架构的缺点,业界基于数据湖开发了Iceberg, Hudi, DeltaLake这些数据湖技术,使得数仓反对ACID, Update/Delete, 数据Time Travel, Schema Evolution等个性,使得数仓的时效性从小时级晋升到分钟级,数据更新也反对局部更新,大大提高了数据更新的性能。兼具流式计算的实时性和批计算的吞吐量,反对的是近实时的场景。

以上计划中其中基于数据湖的利用最广,但数据湖模式无奈撑持更高的秒级实时性,也无奈间接对外提供数据服务,须要搭建其余的数据服务组件,零碎较为简单。基于此背景下,局部业务开始应用Doris来承接,业务数据分析师须要对Doris与Hudi中的数据进行联邦剖析,此外在Doris对外提供数据服务时既要能查问Doris中数据,也要能减速查问离线业务中的数据湖数据,因而咱们开发了Doris拜访数据湖Hudi中数据的个性。

Doris剖析Hudi数据的设计原理

基于以上背景,咱们设计了Apache Doris中查问数据湖格局Hudi数据,因Hudi生态为java语言,而Apache Doris的执行节点BE为C++环境,而C++ 无奈间接调用Hudi java SDK,针对这一点,咱们有四种解决方案:

  1. 实现Hudi C++ client,在BE中间接调用Hudi C++ client去读写Hudi表。
    该计划须要残缺实现一套Hudi C++ client,开发周期较长,前期Hudi行为变更须要同步批改Hudi C++ client,保护较为艰难。
  2. BE通过thrift协定发送读写申请至Broker,由Broker调用Hudi java client读取Hudi表。
    该计划须要在Broker中减少读写Hudi数据的性能,目前Broker定位仅为fs的操作接口,引入Hudi突破了Broker的定位。第二,数据须要在BE和Broker之间传输,性能较低。
  3. 在BE中应用JNI创立JVM,加载Hudi java client去读写Hudi表。
    该计划须要在BE过程中保护JVM,有JVM调用Hudi java client对Hudi进行读写。读写逻辑应用Hudi社区java实现,能够保护与社区同步;同时数据在同一个过程中进行解决,性能较高。但须要在BE保护一个JVM,治理较为简单。
  4. 应用BE arrow parquet c++ api读取hudi parquet base file,hudi表中的delta file暂不解决。
    该计划能够由BE间接读取hudi表的parquet文件,性能最高。但以后不反对base file和delta file的合并读取,因而仅反对COW表Snapshot Queries和MOR表的Read Optimized Queries,不反对Incremental Queries。

综上,咱们抉择计划四,第一期实现了COW表Snapshot Queries和MOR表的Read Optimized Queries,前面联结Hudi社区开发base file和delta file合并读取的C++接口。

Doris剖析Hudi数据的技术实现

Doris中查问剖析Hudi表面应用步骤非常简单。

1. 创立Hudi表面

建表时指定engine为Hudi,同时指定Hudi表面的相干信息,如hive metastore uri,在hive metastore中的database和table名字等。
建表仅仅在Doris的元数据中减少一张表,无任何数据挪动。
建表时反对指定全副或局部hudi schema,也反对不指定schema创立hudi表面。指定schema时必须与hiveMetaStore中hudi表的列名,类型统一。
Example:

   CREATE TABLE example_db.t_hudi     ENGINE=HUDI    PROPERTIES (    "hudi.database" = "hudi_db",    "hudi.table" = "hudi_table",    "hudi.hive.metastore.uris"  =  "thrift://127.0.0.1:9083"    );            CREATE TABLE example_db.t_hudi (    column1 int,    column2 string)    ENGINE=HUDI    PROPERTIES (    "hudi.database" = "hudi_db",    "hudi.table" = "hudi_table",    "hudi.hive.metastore.uris"  =  "thrift://127.0.0.1:9083"    );

2. 查问Hudi表面

查问Hudi数据表时,FE在analazy阶段会查问元数据获取到Hudi表面的的hive metastore地址,从Hive metastore中获取hudi表的schema信息与文件门路。

  1. 获取hudi表的数据地址
  2. FE布局fragment减少HudiScanNode。HudiScanNode中获取Hudi table对应的data file文件列表。
  3. 依据Hudi table获取的data file列表生成scanRange
  4. 下发HudiScan 工作至BE节点
  5. BE节点依据HudiScanNode指定的Hudi表面文件门路调用native parquet reader进行数据读取。

前期布局

目前Apche Doris查问Hudi表已合入社区,以后已反对COW表的Snapshot Query,反对MOR表的Read Optimized Query。对MOR表的Snapshot Query临时还未反对,流式场景中的Incremental Query也没有反对。
后续还有几项工作须要解决,咱们和社区也在积极合作进行中:

  1. MOR表的Snapshot Query。MOR表实时读须要合并读取Data file与对应的Delta file,BE须要反对Delta file AVRO格局的读取,须要减少avro的native读取形式。
  2. COW/MOR表的Incremental Query。反对实时业务中的增量读取。
  3. BE读取Hudi base file和delta file的native接口。目前BE读取Hudi数据时,仅能读取data file,应用的是parquet的C++ SDK。前期咱们和联结Hudi社区提供Huid base file和delta file的C++/Rust等语言的读取接口,在Doris BE中间接应用native接口来查问Hudi数据。

本文为字节跳动数据平台研发工程师在DataFunSummit大会演讲实录,关注字节跳动数据平台微信公众号,回复【0929】,支付本次分享PPT。

立刻跳转火山引擎E-MapReduce官网理解更多信息