Apache Flink X Apache Doris 構(gòu)建極速易用的實時數(shù)倉架構(gòu)

摘要:本文整理自 SelectDB 資深大數(shù)據(jù)研發(fā)專家王磊,在 FFA 2022 實時湖倉專場的分享。本篇內(nèi)容主要分為四個部分:

  1. 實時數(shù)倉需求和挑戰(zhàn)

  2. 基于 Apache Doris 和 Apache Flink 構(gòu)建實時數(shù)倉

  3. 用戶案例與最佳實踐分享

  4. 新版本特性

點擊查看直播回放和演講 PPT

一拴鸵、實時數(shù)倉需求和挑戰(zhàn)

1.jpg

在數(shù)據(jù)流的角度上玷坠,分析一下傳統(tǒng)的數(shù)據(jù)架構(gòu)蜗搔。從圖中可以看到,數(shù)據(jù)分為實時數(shù)據(jù)流和離線數(shù)據(jù)流八堡。

在實時數(shù)據(jù)部分樟凄,通過 Binlog 的方式,將業(yè)務(wù)數(shù)據(jù)庫中的數(shù)據(jù)變更兄渺,采集到實時數(shù)倉缝龄。同時,通過 Flume-Kafka-Sink 對進(jìn)行實時采集挂谍。當(dāng)數(shù)據(jù)源上不同來源的數(shù)據(jù)都采集到實時數(shù)倉后叔壤,便可以構(gòu)建實時數(shù)倉。在實時數(shù)倉構(gòu)建的內(nèi)部口叙,我們?nèi)匀粫袷財?shù)倉分層理論炼绘,將數(shù)據(jù)分為 ODS 層俺亮、DWD 層脚曾、DWS 層、ADS 層启具。

在離線數(shù)據(jù)流部分本讥,通過 DataX 定時同步的方式,采集業(yè)務(wù)庫 RDS 中的一些數(shù)據(jù)富纸。當(dāng)不同來源的數(shù)據(jù)晓褪,進(jìn)入到離線數(shù)倉后堵漱,便可以在離線數(shù)倉內(nèi)部勤庐,依賴 Spark SQL 或 Hive SQL好港,對數(shù)據(jù)進(jìn)行定時處理愉镰。

然后,分離出不同維度(ODS钧汹、DWD丈探、ADS 等)的數(shù)據(jù),并將這些數(shù)據(jù)存在一個存儲介質(zhì)上拔莱。我們一般會存在 HDFS 或 S3 的對象存儲上碗降。通過這樣的方式隘竭,我們的離線數(shù)倉便構(gòu)建起來了。與此同時讼渊,為了保障數(shù)據(jù)的一致性动看。我們需要一個數(shù)據(jù)清洗任務(wù)。使用離線數(shù)據(jù)對實時數(shù)據(jù)進(jìn)行清洗爪幻,保障數(shù)據(jù)最終的一致性菱皆。

2.jpg

如上圖所示,我們在技術(shù)架構(gòu)的角度挨稿,對傳統(tǒng)數(shù)據(jù)架構(gòu)進(jìn)行分析仇轻。從圖中可以看到,不同應(yīng)用采取不同技術(shù)棧叶组。比如在湖倉部分是 Hive拯田、Iceberg、Hudi 等組件甩十。在湖倉之上的 Ad-hoc船庇,我們選擇 Impala 或 Kudu。對于 OLAP 的高并發(fā)侣监,我們會使用 Druid 或 Kylin 組件鸭轮。

除此之外,業(yè)務(wù)還有半結(jié)構(gòu)化的需求橄霉。我們會使用 ES 對日志進(jìn)行檢索和分析窃爷;使用 HBase 構(gòu)建高效的點查服務(wù)。在部分情況下姓蜂,業(yè)務(wù)需要對外提供統(tǒng)一的數(shù)據(jù)服務(wù)按厘。這時,部分業(yè)務(wù)會使用 Presto 或 Trino 的查詢網(wǎng)關(guān)钱慢,統(tǒng)一對用戶提供服務(wù)逮京。

這個架構(gòu)有什么問題呢?首先束莫,架構(gòu)組件多懒棉,維護(hù)復(fù)雜。其次览绿,它的計算策严、存儲和研發(fā)成本都比較高。主要因為我們同時維護(hù)兩套數(shù)據(jù)和兩套計算饿敲,即實時數(shù)據(jù)流和實時計算任務(wù)妻导。最后,我們無法保障實時流的數(shù)據(jù)和離線數(shù)據(jù)的一致性。此時倔韭,只能通過離線數(shù)據(jù)定時清洗暑脆,保證數(shù)據(jù)的一致性。

3.jpg

基于以上痛點狐肢,一個“統(tǒng)一的實時”架構(gòu)呼之欲出×げ埽“統(tǒng)一”是指數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一份名,我們希望半結(jié)構(gòu)化和結(jié)構(gòu)化數(shù)據(jù)能夠統(tǒng)一存儲在一起。同時也指的是在一個平臺中能完成多種分析和計算場合(實時查詢妓美,交互式分析僵腺,批量處理等)“實時”指的是我們希望數(shù)據(jù)的接入和數(shù)據(jù)分析都能實時的進(jìn)行。

二壶栋、基于 Apache Doris 和 Apache Flink 構(gòu)建實時數(shù)倉

4.jpg

基于以上需求辰如,如何通過 Apache Doris 和 Apache Flink 構(gòu)建實時數(shù)倉?滿足用戶對實時應(yīng)用和統(tǒng)一架構(gòu)的需求贵试。

首先琉兜,介紹一下什么是 Apache Doris?Apache Doris 是基于 MPP 架構(gòu)的高性能的實時分析型數(shù)據(jù)庫毙玻。它以極速易用的特點被人們所熟知豌蟋,Doris 只需亞秒就能完成海量數(shù)據(jù)(TB 級別或者百億級別數(shù)據(jù))的查詢。不僅支持高并發(fā)(點查桑滩、ad-hoc)的查場景梧疲,也支持高吞吐量(ETL 任務(wù))的查詢場景。

因此运准,Apache Doris 能較好的滿足高并發(fā)報表幌氮、即席查詢愧驱、統(tǒng)一數(shù)倉服務(wù)题涨、以及湖倉和聯(lián)邦查詢等功能踏拜。用戶在此之上凹嘲,可以構(gòu)建用戶行為分析柒爸、AB 實驗捧书、日志檢索分析垮抗、用戶畫像分析等應(yīng)用匾效。

從下圖中我們可以看到陆盘,數(shù)據(jù)源經(jīng)過各種數(shù)據(jù)集成和加工后普筹,通常會入庫到實時數(shù)倉 Doris 之中。同時隘马,部分?jǐn)?shù)據(jù)會入到湖倉架構(gòu)的 Hive 或 Iceberg 中太防。然后,基于 Doris 構(gòu)建一個統(tǒng)一的數(shù)倉,對外提供服務(wù)蜒车。

5.jpg

接下來讳嘱,看一下如何基于 Apache Doris 構(gòu)建極速易用的實時數(shù)倉的架構(gòu)?因為 Doris 既可以承載數(shù)據(jù)倉庫的服務(wù)酿愧,也可以承載 OLAP 等多種應(yīng)用場景沥潭。

因此,它的實時數(shù)倉架構(gòu)變得非常簡單嬉挡。我們只需要通過 Flink CDC 將 RDS 的數(shù)據(jù)钝鸽,實時同步到 Doris。通過 routine load 將 Kafka 等消息系統(tǒng)中的數(shù)據(jù)庞钢,實時同步到 Doris拔恰。在 Doris 內(nèi)部,基于 Doris 不同的表模型基括、Rollup颜懊、以及物化視圖的能力,構(gòu)建實時數(shù)倉风皿。

Doris 的表模型分為明細(xì)模型河爹、主鍵模型和統(tǒng)計模型。在 Doris 內(nèi)部構(gòu)建實時數(shù)倉時揪阶,ODS 層通常會使用明細(xì)模型構(gòu)建昌抠。DWD 層通過 SQL 調(diào)度任務(wù),對 ODS 數(shù)據(jù)抽取并獲取鲁僚。DWS 和 ADS 層則可以通過 Rollup 和物化視圖的技術(shù)手段構(gòu)建炊苫。

除此之外,Doris 還支持基于 Iceberg冰沙、Delta Lake 和 Hudi 的數(shù)據(jù)湖服務(wù)侨艾,提供一些聯(lián)邦分析和湖倉加速的能力。這樣我們便完成了基于 Doris 構(gòu)建一個實時數(shù)倉拓挥。在實時數(shù)倉之上唠梨,我們可以構(gòu)建 BI 服務(wù)、Adhoc 查詢侥啤、多維分析等應(yīng)用当叭。

6.jpg

架構(gòu)明確之后,我們看一下在實踐過程中會有哪些挑戰(zhàn)盖灸?首先蚁鳖,大家最關(guān)心的問題就是數(shù)據(jù)的一致性保證。

數(shù)據(jù)一致性一般分為“最多一次”赁炎、“至少一次”和“精確一次”醉箕。

  1. 最多一次是指,發(fā)送方僅發(fā)送消息,而不期待任何回復(fù)讥裤。在這種模型中放棒,數(shù)據(jù)的生產(chǎn)和消費過程,都可能出現(xiàn)數(shù)據(jù)丟失己英。
  1. 至少一次是指间螟,發(fā)送方不斷重試,直到對方收到為止损肛。在這個模型中寒亥,生產(chǎn)和消費過程都可能出現(xiàn)數(shù)據(jù)重復(fù)。
  1. 精確一次能夠保證消息荧关,只被嚴(yán)格發(fā)送一次,并且只被嚴(yán)格處理一次褂傀。這種數(shù)據(jù)模型忍啤,能夠嚴(yán)格保證數(shù)據(jù)生產(chǎn)和消費過程中的準(zhǔn)確一致性。Doris 基于兩階段提交仙辟,實現(xiàn)準(zhǔn)確的數(shù)據(jù)一致性同波。
7.jpg

Flink CDC 通過 Flink Checkpoint 機制結(jié)合 Doris 兩階段提交,實現(xiàn)端到端的數(shù)據(jù)寫入一致性叠国。具體過程分為四步未檩。

第一步,事務(wù)開啟(Flink Job 啟動和 Doris 事務(wù)開啟):當(dāng) Flink 任務(wù)啟動后粟焊,Doris 的 sink 會發(fā)起一個 precommit 請求冤狡,開啟一個寫入事務(wù)。

第二步项棠,數(shù)據(jù)傳輸(Flink Job 的運行和數(shù)據(jù)的傳輸):在 Flink Job 運行過程中悲雳,Doris sink 會不斷從上游算子獲取數(shù)據(jù),并通過 httpchunked 的方式香追,持續(xù)將數(shù)據(jù)傳輸?shù)?Doris合瓢。

第三步,事務(wù)預(yù)提交:當(dāng) Flink 開始進(jìn)行 Checkpoint 時透典,F(xiàn)link 會發(fā)起一個 Checkpoint 請求晴楔。此時,F(xiàn)link 的各個算子會進(jìn)行 Barrier 對齊和快照保存峭咒。Doris Sink 會發(fā)出停止 Stream Load 寫入的請求税弃,并發(fā)起一個事務(wù)提交請求到 Doris。

此時讹语,這批數(shù)據(jù)已經(jīng)完全寫入 Doris BE 中钙皮,BE 還沒有進(jìn)行數(shù)據(jù)發(fā)布。因此,寫入 BE 的數(shù)據(jù)對用戶來說是不可見的短条。

第四步导匣,事務(wù)提交。當(dāng) Flink 的 Checkpoint 完成之后茸时,它會通知各個算子贡定。此時,Doris 會發(fā)起一次事務(wù)提交到 Doris BE可都。BE 會對此次寫入的數(shù)據(jù)缓待,進(jìn)行發(fā)布。最終完成數(shù)據(jù)流的寫入渠牲。

綜上所述旋炒,是 Flink CDC 結(jié)合 Doris 兩階段事務(wù),完成數(shù)據(jù)一致性提交的過程签杈。這里有一個問題是瘫镇,當(dāng)預(yù)提交成功,但 Flink Checkpoint 失敗時答姥,該怎么辦铣除?這時 Doris 并沒有收到事務(wù)最終的提交請求,Doris 內(nèi)部會對寫入數(shù)據(jù)進(jìn)行回滾(rollback)鹦付,從而保證數(shù)據(jù)最終的一致性尚粘。

8.jpg

下面來看一下數(shù)據(jù)增量和全量的同步。如何基于 Flink CDC 實現(xiàn)全量和增量的數(shù)據(jù)同步敲长?

這個原理很簡單郎嫁,因為 Flink CDC 實現(xiàn)了基于 Snapshot 的全量數(shù)據(jù)同步,以及基于 BinLog 實時增量的數(shù)據(jù)同步祈噪。與此同時全量數(shù)據(jù)同步和增量數(shù)據(jù)同步可以自動切換行剂。因此。在數(shù)據(jù)遷移的過程中钳降,用戶只需要配置好同步的表即可厚宰。當(dāng) Flink 任務(wù)啟動時,首先會進(jìn)行歷史表的數(shù)據(jù)同步遂填。同步完成之后铲觉,它會自動切換成實時同步。

9.jpg

完成實時數(shù)據(jù)同步之后吓坚,用戶又產(chǎn)生了 RDS Schema 的變更需求撵幽。因為隨著業(yè)務(wù)的發(fā)展,RDS 表結(jié)構(gòu)會產(chǎn)生變更礁击,用戶希望 Flink CDC 不但能夠?qū)?shù)據(jù)變化同步到 Doris盐杂,也希望將 RDS 表結(jié)構(gòu)的變更也同步到 Doris逗载。這樣的話,用戶不用擔(dān)心 RDS 的表結(jié)構(gòu)和 Doris 表結(jié)構(gòu)不一致的問題链烈。

要滿足這種 DDL 同步的需求厉斟,前提是 Doris 能夠快速支持這種 Schema 的變更。當(dāng)很多 Schema Change 請求到來后 Doris 能夠快速處理强衡。由于 Doris 處理 Schema Change 時擦秽,相對比較耗時,所以我們引入了 Light Schema Change漩勤。

Light Schema Change 的實現(xiàn)原理非常簡單感挥,我們只需要在加減列時,對 FE 中的元數(shù)據(jù)進(jìn)行修改越败,將修改后的數(shù)據(jù)持久化触幼。Schema Change 只需要更新 FE 中的元數(shù)據(jù)即可,因此 Schema Change 的效率就非常高究飞。

與此同時域蜗,這個響應(yīng)過程是同步的過程。由于 Light Schema Change 只修改了 FE 的元數(shù)據(jù)噪猾,并沒有同步給 BE。因此筑累,會產(chǎn)生 BE 和 FE Schema 不一致的問題袱蜡。

為了解決這種問題,我們對 BE 的寫出流程進(jìn)行了修改慢宗,具體包含三個方面坪蚁。

  1. 數(shù)據(jù)寫入:對于數(shù)據(jù)寫入而言,F(xiàn)E 會將 Schema 持久化到元數(shù)據(jù)中镜沽。當(dāng) FE 發(fā)起導(dǎo)入任務(wù)時敏晤,會把最新的 Schema 一起發(fā)給 Doris BE,BE 會根據(jù)最新的 Schema 對數(shù)據(jù)進(jìn)行寫入缅茉,并與 RowSet 進(jìn)行綁定嘴脾。將該 Schema 持久化到 RowSet 的元數(shù)據(jù)中,實現(xiàn)了數(shù)據(jù)的各自解析蔬墩。解決了寫入過程中 Schema 不一致的問題译打。
  1. 數(shù)據(jù)讀取:對于數(shù)據(jù)讀取而言拇颅,F(xiàn)E 生成查詢計劃時奏司,會把最新的 Schema 附在其中,并一起發(fā)送給 BE樟插。BE 會拿到最新的 Schema韵洋,對數(shù)據(jù)進(jìn)行讀取竿刁,來解決讀取過程中 Schema 發(fā)生不一致的問題。
  1. 數(shù)據(jù) Compaction:對于數(shù)據(jù)的 Compaction 而言搪缨,當(dāng)數(shù)據(jù)進(jìn)行 Compaction 時食拜,我們選取需要進(jìn)行 Compaction 的 RowSet 中最新的 Schema,作為之后 RowSet 對應(yīng)的 Schema勉吻。以此解決不同 Schema 上监婶,RowSet 的合并問題。

經(jīng)過 Light Schema Change 優(yōu)化之后齿桃,Doris Schema Change 的性能惑惶,從之前一個 Schema 變化 310 毫秒,降低到了 7 毫秒短纵。整體性能有近百倍的提升带污。徹底的解決了,海量數(shù)據(jù)的 Schema Change 變化難的問題香到。

10.jpg

有了 Light Schema Change 的保證鱼冀,F(xiàn)link CDC 能夠同時支持 DML 和 DDL 的數(shù)據(jù)同步。那么在 Flink CDC 中悠就,我們是如何實現(xiàn)的呢千绪?

  1. 首先,我們要在 Flink CDC 的 MySQL Source 側(cè)開啟同步 MySQL DDL 的變更配置梗脾。然后荸型,我們需要在 Doris 側(cè)識別 DDL 的數(shù)據(jù)變更,并對其進(jìn)行解析炸茧。
  1. 當(dāng) Doris Sink 發(fā)現(xiàn) DDL 語句后瑞妇,Doris Sink 會對這種表結(jié)構(gòu)進(jìn)行驗證,驗證表結(jié)構(gòu)是否支持 Light Schema Change梭冠。當(dāng)表結(jié)構(gòu)驗證通過后辕狰,Doris Sink 會發(fā)起 Schema Change 請求到 Doris,從而完成此次 Schema Change 的變化控漠。
  1. 在具體使用過程中蔓倍,Doris 如何開啟 Light Schema Change 呢?我們只需要在表里添加盐捷,"light_schema_change" = "true"即可柬脸。當(dāng)我們解決了基于 Flink 和 Doris 數(shù)據(jù)同步過程中,源數(shù)據(jù)的一致性毙驯、全量數(shù)據(jù)和增量數(shù)據(jù)的同步倒堕、以及 DDL 數(shù)據(jù)的變更后,一個完整的數(shù)據(jù)同步方案就完成了爆价。
11.jpg

站在數(shù)據(jù)模型的角度垦巴,看一下如何基于 Flink 和 Doris媳搪,構(gòu)建不同的數(shù)據(jù)模型。

第一種數(shù)據(jù)模型骤宣,也是最簡單的數(shù)據(jù)模型秦爆。我們將一個 RDS 的表,同步到一個 Doris 的表中憔披。通過 MySQL-Source 加 Doris-Sink等限,實現(xiàn)表結(jié)構(gòu)和數(shù)據(jù)的變更。

第二種數(shù)據(jù)模型芬膝,我們可以將 MySQL 中兩個表的數(shù)據(jù)同步到 Flink 后望门,在 Flink 內(nèi)部進(jìn)行多流 Join,完成數(shù)據(jù)打?qū)捗趟梢粋€大寬表數(shù)據(jù)筹误,同步到 Doris 之上。

第三種數(shù)據(jù)模型癣缅,我們可以對上游的 Kafka 數(shù)據(jù)進(jìn)行清洗厨剪,清洗后通過 Doris-Sink 寫入 Doris 表中。

第四種數(shù)據(jù)模型友存,我們還可以將 MySQL 數(shù)據(jù)和 Kafka 數(shù)據(jù)祷膳,進(jìn)行多流的 Join,然后寫入 Doris屡立。

12.jpg

第五種數(shù)據(jù)模型直晨,我們在 Doris 側(cè)建一個基于 Unique Key 模型的寬表。然后侠驯,將上游 RDS 中的數(shù)據(jù),根據(jù) Key 使用 Doris 的多列更新模式奕巍,將多列數(shù)據(jù)分布寫入到 Doris 的大寬表中吟策。

例如,我們首先將 MySQL 第一個表中的 status的止,同步到 Doris 中檩坚。其次,我們將 MySQL 第二個表中的诅福,amount 字段同步到 Doris 的同一個大寬表模型中匾委。

除此之外,我們還可以將多源的 RDS(MySQL氓润、Oracle 等)數(shù)據(jù)同步到 Doris 后赂乐,在 Doris 內(nèi)部使用寬表抽取的方式,構(gòu)建一個大寬表咖气。

13.jpg

對于大數(shù)據(jù)來說挨措,高并發(fā)寫入并不難挖滤,難點在于高并發(fā)更新。如何在上億數(shù)據(jù)中快速找到需要更新的數(shù)據(jù)浅役,并對其進(jìn)行更新斩松?這一直是大數(shù)據(jù)領(lǐng)域比較難的問題。

為了解決這個問題觉既,Doris 通過 MVCC 多版本并發(fā)機制來實現(xiàn)惧盹。特別是在 Unique Key 模型中,當(dāng)我們寫入一個數(shù)據(jù)時瞪讼,如果數(shù)據(jù)庫中不存在數(shù)據(jù)钧椰,會寫入一個版本。當(dāng)我們再次對該數(shù)據(jù)進(jìn)行更新時尝艘,會再次寫入一個版本演侯。此時,數(shù)據(jù)變更在 Doris 以多個版本的形式存在背亥。當(dāng)用戶在查詢時秒际,Doris 會將最新版本對應(yīng)的數(shù)據(jù)返回給用戶。并在 compaction 時狡汉,對歷史變更的數(shù)據(jù)進(jìn)行清理娄徊。這種設(shè)計解決了海量數(shù)據(jù)的更新問題。同時盾戴,Doris 支持 Merge On Read 和 Merge On Write 兩種方式寄锐。

14.jpg

首先,講一講 Merge On Read尖啡,它的特點是寫入速度非抽掀停快。無論是 insert 語句衅斩,還是 update 語句盆顾,對于 Doris 來說,都是以多版本的方式寫入 Doris畏梆。因此您宪,它的寫入性能很高。其次奠涌,它的查詢性能不是很高宪巨。因為在查詢過程中,需要對 Key 進(jìn)行聚合去重溜畅,然后再執(zhí)行查詢捏卓。因此,它的性能不是很高慈格。

舉例:

  1. 我們在數(shù)據(jù)里面寫入三條訂單數(shù)據(jù)天吓,數(shù)據(jù)是以 append 的形式寫入 Doris 表中贿肩。
  1. 然后,我們對訂單 1 的 cost 進(jìn)行更新龄寞,寫入一個新的版本的數(shù)據(jù)汰规。當(dāng)我們將訂單 1 的 cost 修改為 30 時,數(shù)據(jù)通過 append 的形式物邑,以新版本寫入 Doris溜哮。
  1. 當(dāng)我們對訂單 2 的數(shù)據(jù)進(jìn)行刪除時,仍然通過 append 方式色解,將數(shù)據(jù)多版本的寫入 Doris 并將_DORIS_DELETE_SIGN字段變?yōu)?1茂嗓,此時,表示這條數(shù)據(jù)被刪除了科阎。

當(dāng) Doris 讀取數(shù)據(jù)時述吸,發(fā)現(xiàn)最新版本的數(shù)據(jù)被標(biāo)記刪除,就會將該數(shù)據(jù)從查詢結(jié)果中進(jìn)行過濾锣笨。除此之外蝌矛,Doris 還有一個DORIS_SEQUENCE_COL列,保證在高并發(fā)更新的情況下错英,更新數(shù)據(jù)的一致性和順序性入撒。

下面看一下查詢效果。當(dāng)用戶進(jìn)行查詢時椭岩,會進(jìn)行兩次聚合操作茅逮。第一次,使用多路歸并排序判哥,將重復(fù)的數(shù)據(jù)排列在一起献雅,并使用高版本數(shù)據(jù)覆蓋低版本數(shù)據(jù)的方式,對數(shù)據(jù)進(jìn)行合并塌计。

第二次挺身,按照查詢的聚合條件,對數(shù)據(jù)進(jìn)行聚合夺荒。這樣帶來兩個比較嚴(yán)重的查詢性問題瞒渠。第一良蒸,在多路歸并的時候技扼,它的代價較高,對 Key 進(jìn)行比較嫩痰,非常消耗 CPU剿吻。第二,在數(shù)據(jù)讀取的過程中串纺,我們無法進(jìn)行有效的數(shù)據(jù)裁剪丽旅,會引入大量的 IO 操作椰棘。

15.jpg

下面來看一下 Merge On Write 如何實現(xiàn)高并發(fā)寫入以及查詢的性能問題。Merge On Write 兼容查詢性能和寫入性能榄笙。

Merge On Write 在寫入的過程中邪狞,引入了 Delete Bitmap 數(shù)據(jù)結(jié)構(gòu),Doris 使用 Delete Bitmap 標(biāo)記 RowSet 中某一行是否被刪除茅撞。這里使用了兼顧性能和存儲空間的 Row Bitmap帆卓,將 Bitmap 中的 Mem Table 一起存儲在 BE 中,每個 segment 會對應(yīng)一個 Bitmap米丘。

為了保持 Unique Key 原有的語義剑令,Delete Bitmap 也支持多版本。每次導(dǎo)入會產(chǎn)生該版本增量的 Bitmap拄查。在查詢時需要合并此前所有版本的 Delete Bitmap吁津。

接下來,看一下基于 Delete Bitmap 的 Merge On Write 的寫入流程堕扶。首先碍脏,DeltaWriter 會先將數(shù)據(jù) flush 到磁盤。第二步挣柬,我們會批量檢查所有 Key潮酒。在點查過程中,會經(jīng)過一個區(qū)間樹邪蛔,查找到對應(yīng)的 RowSet急黎。然后,在 RowSet 內(nèi)部通過 BloomFilter 和 index 高效查詢侧到。當(dāng)查詢到 Key 對應(yīng)的 RowSet 后勃教,便會覆蓋 RowSet Key 對應(yīng)的 Bitmap。然后在 publish 階段更新 Bitmap匠抗,從而保證批量點查 Key 和更新 Bitmap 期間不會有新的可見 RowSet故源,保證 Bitmap 在更新過程中數(shù)據(jù)的正確性。除此之外汞贸,如果某個 segment 沒有被修改绳军,則不會有對應(yīng)版本的 Bitmap 記錄。

16.jpg

下面看一下 Merge On Write 的查詢流程矢腻。首先门驾,當(dāng)我們查詢某一版本數(shù)據(jù)時,Doris 會從 LRU Cache Delete Bitmap 中多柑,查找該版本對應(yīng)的緩存奶是。如果緩存不存在,我們再去 RowSet 中讀取對應(yīng)的 Bitmap。最后聂沙,我們使用 Delete Bitmap秆麸,對 RowSet 中的數(shù)據(jù)進(jìn)行過濾,將結(jié)果返回及汉。

同時在這個階段我們還可以通過 Bloomfilter 和 Bitmap 的二級索引來提高查詢的效率沮趣,查詢過程中 Doris 會進(jìn)行有效的謂詞下推。因此坷随,在 Merge On Write 中兔毒,大幅提升了數(shù)據(jù)寫入的查詢的效率。

17.jpg

Doris 針對不同場景甸箱,提供了不同的數(shù)據(jù)模型育叁,分別有明細(xì)數(shù)據(jù)模型、主鍵數(shù)據(jù)模型芍殖、聚合數(shù)據(jù)模型豪嗽。其中,明細(xì)數(shù)據(jù)模型主要用來存儲日志豌骏,數(shù)據(jù)來一條就存一條龟梦。主鍵數(shù)據(jù)模型指相同的 Key 會進(jìn)行覆蓋,比如根據(jù)訂單 ID窃躲,對訂單狀態(tài)進(jìn)行更新计贰。

在統(tǒng)計模型方面,我們會將相同 Key 的 Value 列進(jìn)行統(tǒng)計合并計算蒂窒。比較典型的應(yīng)用場景是報表統(tǒng)計和指標(biāo)計算躁倒。比如根據(jù)門店 ID 和門店時間,對銷售額進(jìn)行統(tǒng)計計算洒琢。

對于統(tǒng)計模型來說秧秉,數(shù)據(jù)會邊入庫邊統(tǒng)計。對于用戶查詢來說衰抑,直接查詢統(tǒng)計后的數(shù)據(jù)象迎,讓查詢過程更高效。

18.jpg

物化視圖的概念呛踊。物化視圖指砾淌,根據(jù)預(yù)定義的 SQL 分析語句執(zhí)行預(yù)計算,并將計算結(jié)果物化谭网,從而加速查詢的一種手段摊鸡。

對于 Doris 來說献烦,物化視圖主要用于聚合場景掠抬。除此之外拔稳,還可以用于聚合數(shù)據(jù)和明細(xì)數(shù)據(jù)的同時查詢;以及匹配不同的前綴索引場景薄辅。

在物化視圖使用方面要拂,首先建立一個表,然后再建立一個物化視圖站楚⊥讯瑁基于一張 Base 表,可以構(gòu)建不同的物化視圖基于不同的維度進(jìn)行統(tǒng)計窿春。當(dāng)用戶查詢時拉一,如果能夠命中化識圖,都會走物化視圖旧乞;如果沒有命中物化視圖蔚润,會走 Base 表,從而完成高效查詢尺栖。

對于數(shù)據(jù)更新來說嫡纠,首先會更新 Base 表,然后更新物化視圖延赌。從而讓 Doris 保證物化視圖和 Base 表數(shù)據(jù)的完全一致性除盏。

19.jpg

接下來,看一下物化視圖的智能路由選擇挫以。Doris 通過物化視圖加速查詢者蠕,并且在查詢過程中,自動進(jìn)行路由選擇掐松。在查詢數(shù)據(jù)的過程中踱侣,如果數(shù)據(jù)在物化視圖中存在,會直接走物化視圖大磺;如果在物化視圖中不存在泻仙,才會走 Base 表。

與此同時量没,Doris 的智能存儲和現(xiàn)代化計算能力玉转,也能快速完成數(shù)據(jù)查詢。物化視圖在智能路由的過程中殴蹄,遵循最小匹配原則究抓。只有查詢的數(shù)據(jù)集比物化視圖集合小時,才可能走物化視圖袭灯。

它的智能選擇過程包括最優(yōu)選擇和查詢改寫兩個部分刺下。首先,我們來看一下最優(yōu)選擇稽荧。最優(yōu)選擇包括兩個部分橘茉,即過濾候選集和選擇最優(yōu)。

在過濾候選集過程中,當(dāng)一個 SQL 語句過來畅卓,通過 Where 條件進(jìn)行判斷擅腰。Where 條件里查詢的是 advertiser=1。由此可見翁潘,物化視圖和 Base 表都有這個字段趁冈,這時的候選集是物化視圖和 Base 表。

我們會判斷 Group By 計算拜马。Group By 字段是 advertiser 和 channel渗勘。這兩個字段同時在物化視圖和表中 Base。這時過濾的候選集仍然是物化視圖和 Base 表俩莽。接下來旺坠,我們會過濾計算函數(shù)。比如在這里會執(zhí)行 count(distinct user_id)扮超,然后對數(shù)據(jù)進(jìn)行計算价淌。由于 Count Distinct 的字段 user_id 在物化視圖和 Base 表中都存在。因此過濾結(jié)果仍是物化視圖加 Base 表瞒津。最后蝉衣,進(jìn)行最優(yōu)選擇。通過一系列計算巷蚪,我們發(fā)現(xiàn)查詢條件無論是 Where病毡、Group By 還是 Agg function 關(guān)聯(lián)的字段,在 Base 表和物化視圖都存在屁柏。這時啦膜,我們需要進(jìn)行最優(yōu)選擇。然后淌喻,Doris 經(jīng)過計算發(fā)現(xiàn) Base 表的數(shù)據(jù)遠(yuǎn)大于物化視圖僧家,即物化視圖的數(shù)據(jù)更小。

由此可見裸删,如果查詢走物化視圖八拱,它的效率更高。最優(yōu)的查詢計劃是物化視圖涯塔。當(dāng)我們找到最優(yōu)的查詢計劃肌稻,會進(jìn)行子查詢改寫,將我們的 Count Distinct 改寫成 Bitmap匕荸。從而完成了物化視圖的智能路由爹谭。完成智能路由之后,我們會將 Doris 生成的查詢 SQL 發(fā)送到 BE 進(jìn)行分布式查詢計算榛搔。

21.jpg

Doris 數(shù)據(jù)分為兩級存儲诺凡。第一個是分區(qū)东揣,第二個是分桶。我們可以按照天對數(shù)據(jù)在 Partition 級別進(jìn)行分區(qū)腹泌。

接下來嘶卧,我們按照 set 級別進(jìn)行分桶。將一個分區(qū)的數(shù)據(jù)真屯,分到不同的桶里。當(dāng)我們在查詢 set ID 時穷娱,就可以通過分區(qū)裁剪绑蔫,快速定位數(shù)據(jù),實現(xiàn)高并發(fā)的查詢泵额。

除此之外配深,Doris 還有很多優(yōu)化查詢的手段。比如一些索引能夠加速查詢嫁盲,前 36 位會走前綴索引篓叶。Zone Map 索引、Bloom Filter 索引都能能快速完成數(shù)據(jù)的過濾計算羞秤。最后缸托,Doris 內(nèi)部在查詢過程中,還做了各種各樣的優(yōu)化瘾蛋。

比如智能算子下推俐镐,選擇更合適的數(shù)據(jù)模型。與此同時哺哼,Doris 在 Join 方面也有很大的優(yōu)勢佩抹,比如 Broadcast Join、Bucket Shuffle Join取董、Colocate棍苹、Shuffle Join,能夠盡量減少 Join 過程中的數(shù)據(jù) Shuffle茵汰。

三枢里、用戶案例與最佳實踐分享

22.jpg

Doris 的應(yīng)用場景主要應(yīng)用在即時分析/交互分析、多維報表分析蹂午,實時數(shù)倉坡垫、湖倉加速&聯(lián)邦分析的四大場景。在這四大場景上画侣,我們可以構(gòu)建一些指標(biāo)監(jiān)控冰悠、高頻發(fā)報表、自助 BI配乱、行為分析溉卓、AB Test 等各豐富的數(shù)據(jù)應(yīng)用皮迟。

23.jpg

這是一個典型的基于 Doris 構(gòu)建實時數(shù)倉的案例。下層的數(shù)據(jù)源是 RDS 業(yè)務(wù)庫桑寨,文件系統(tǒng)數(shù)據(jù)伏尼、埋點數(shù)據(jù)。當(dāng)數(shù)據(jù)實時接入 Doris 后尉尾,它基于 Doris 構(gòu)建了一個實時數(shù)倉爆阶。

在數(shù)據(jù)接入過程中通過 DataX 進(jìn)行離線數(shù)據(jù)同步;通過 Flink CDC 進(jìn)行實時數(shù)據(jù)同步沙咏。然后辨图,在 Doris 內(nèi)部構(gòu)建不同的數(shù)據(jù)分層,比如 ODS 層肢藐、DWS 層故河、DWD 層的數(shù)據(jù)。最后吆豹,在上層構(gòu)建不同的數(shù)據(jù)應(yīng)用鱼的,比如自助報表、自助數(shù)據(jù)抽取痘煤、數(shù)據(jù)大屏凑阶。

除此之外,它結(jié)合了自己的應(yīng)用平臺衷快,構(gòu)建了數(shù)據(jù)開發(fā)與治理平臺晌砾,完成了源數(shù)據(jù)管理、數(shù)據(jù)分析等操作烦磁。用戶在使用 Doris 后养匈,又帶來什么好處呢?

首先都伪,它的業(yè)務(wù)計算從之前的兩小時呕乎,減少到三分鐘。全鏈路的更新報表從周級別陨晶,更新到十分鐘級別猬仁。同時,Doris 基于高度兼容 MySQL先誉,它的學(xué)習(xí)成本非常低湿刽。因此,報表簽約工作是非常順利的褐耳。

由于 Doris 的開發(fā)非常簡單诈闺。開發(fā)周期從從周下降至天級。業(yè)務(wù)人員能快速滿足業(yè)務(wù)需求的變化铃芦。

24.jpg

某運營商的服務(wù)的架構(gòu)是通過 Flink CDC 將 RDS 的數(shù)據(jù)同步到 Doris 中雅镊。然后襟雷,通過 routine load 將上層日志中的數(shù)據(jù)接入到 Kafka 之后,將 Kafka 數(shù)據(jù)同步到 Doris 之中仁烹。然后耸弄,在 Doris 內(nèi)部構(gòu)建實時數(shù)倉。在數(shù)據(jù)調(diào)度時卓缰,它通過開源 Doris计呈,完成數(shù)據(jù)調(diào)度。使用 Prometheus+Grafana 進(jìn)行數(shù)據(jù)監(jiān)控征唬。

它采用 Flink+Doris 架構(gòu)體系后捌显,帶來的好處是組件減少,解決了多架構(gòu)下的數(shù)據(jù)的冗余存儲鳍鸵,服務(wù)器資源節(jié)省了 30%苇瓣,數(shù)據(jù)存儲磁盤占用節(jié)省了 60%尉间,運營成本大幅降低偿乖。該案例每天在用戶的業(yè)務(wù)場景上,支持?jǐn)?shù)萬次的用戶的在線查詢和分析哲嘲。

25.jpg

如上圖所示贪薪,之前的架構(gòu)是 Hadoop 數(shù)倉架構(gòu)。因此它的組件比較豐富眠副,有 RDS画切、HBase、Hive囱怕。除此之外霍弹,還有 Kafka 等技術(shù)棧。由此可見娃弓,它的技術(shù)棧非常復(fù)雜典格。

在使用 Doris 之后,它將 RDS 里的數(shù)據(jù)通過 Flink CDC台丛,實時同步到 Doris 里耍缴,服務(wù)器資源成本得到了很大的降低。同時挽霉,也將數(shù)據(jù)的查詢時間從 Spark 的 2~5 小時防嗡,縮短到十分鐘,查詢效率也大大提升侠坎。

在數(shù)據(jù)的同步過程中蚁趁,它使用了 Flink CDC+MySQL,全量加增量的數(shù)據(jù)同步方式实胸。與此同時荣德,它還利用 Doris 的 Light Schema Change 特性闷煤,實時同步 Binlog 里的 DDL 表結(jié)構(gòu)變更到 Doris,實現(xiàn)數(shù)據(jù)接入數(shù)倉零開發(fā)成本涮瞻。

四鲤拿、新版本特性

26.jpg

1.2 版本第一個新特性是增加了 Multi Catalog,用戶可以無縫對接多種數(shù)據(jù)源署咽。Doris 會自動進(jìn)行 Schema 同步近顷,它的性能是 Trino 的三倍。

除此之外宁否,我們在主鍵模型可實時更新窒升,實時更新場景下查詢性能 10 倍以上提升。Light Schema Change 能將 DDL 數(shù)據(jù)更新慕匠,并將數(shù)據(jù)表結(jié)構(gòu)的變更饱须,拉近毫秒級別。在外表上台谊,我們開始支持 JDBC 外表蓉媳,以及 Array 類型數(shù)據(jù)類型,New Decimal 等各種情況锅铅。

重點介紹一下酪呻,之前我們支持 native UDF,大家的使用成本較高⊙涡耄現(xiàn)在玩荠,我們會支持 Java UDF,用戶可以快速寫一個 Java 類贼邓,就可以完成 Java UDF 的使用阶冈。

27.jpg

新版本相比在 1.1 之前的版本,有 3~5 倍的性能提升塑径。同時女坑,我們的性能也領(lǐng)先某業(yè)界標(biāo)桿競品兩倍以上。上圖是我們在 SSB-FLAT 的性能測試結(jié)果晓勇。

點擊查看直播回放和演講 PPT

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末堂飞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绑咱,更是在濱河造成了極大的恐慌绰筛,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件描融,死亡現(xiàn)場離奇詭異铝噩,居然都是意外死亡,警方通過查閱死者的電腦和手機窿克,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門骏庸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毛甲,“玉大人,你說我怎么就攤上這事具被〔D迹” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵一姿,是天一觀的道長七咧。 經(jīng)常有香客問我,道長叮叹,這世上最難降的妖魔是什么艾栋? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮蛉顽,結(jié)果婚禮上蝗砾,老公的妹妹穿的比我還像新娘。我一直安慰自己携冤,他們只是感情好悼粮,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著噪叙,像睡著了一般矮锈。 火紅的嫁衣襯著肌膚如雪霉翔。 梳的紋絲不亂的頭發(fā)上睁蕾,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音债朵,去河邊找鬼子眶。 笑死,一個胖子當(dāng)著我的面吹牛序芦,可吹牛的內(nèi)容都是我干的臭杰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼谚中,長吁一口氣:“原來是場噩夢啊……” “哼渴杆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宪塔,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤磁奖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后某筐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比搭,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年南誊,在試婚紗的時候發(fā)現(xiàn)自己被綠了身诺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜜托。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖霉赡,靈堂內(nèi)的尸體忽然破棺而出橄务,到底是詐尸還是另有隱情,我是刑警寧澤穴亏,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布仪糖,位于F島的核電站,受9級特大地震影響迫肖,放射性物質(zhì)發(fā)生泄漏锅劝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一蟆湖、第九天 我趴在偏房一處隱蔽的房頂上張望故爵。 院中可真熱鬧,春花似錦隅津、人聲如沸诬垂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽结窘。三九已至,卻和暖如春充蓝,著一層夾襖步出監(jiān)牢的瞬間隧枫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工谓苟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留官脓,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓涝焙,卻偏偏與公主長得像卑笨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子仑撞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容