天天看點

大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

一、資料湖的角色和定位

随着移動網際網路,物聯網技術的發展,資料的應用逐漸從 BI 報表可視化往機器學習、預測分析等方向發展,即 BI 到 AI 的轉變。

資料的使用者也從傳統的業務分析人員轉為資料科學家,算法工程師。

此外對資料的實時性要求越來越高,也出現了越來越多的非結構化的資料。

目前的資料倉庫技術出現了一定的局限性,比如單一不變的 schema 和模型已經無法滿足各類不同場景和領域的資料分析的要求,并且資料科學家更願意自己去處理原始的資料,而不是直接使用被處理過的資料。

比如對于資料缺失這種情況,資料科學家會嘗試各種不同的算法去彌補缺失資料,針對不同的業務場景也會有不同的處理方式。

目前資料湖相關的技術是業界針對這些問題的一種解決方案。

下表展示了資料倉庫和資料湖在各個次元上的特性:

大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

相比于資料倉庫,資料湖會保留最原始的資料,并且是讀取時确定 Schema,這樣可以在業務發生變化時能靈活調整。最原始的資料湖技術其實就是對象存儲,比如 Amazon S3,Aliyun OSS,可以存儲任意形式的原始資料,但是如果不對這些存儲的原始檔案加以管理,就會使資料湖退化成資料沼澤(dataswamp)。

是以必須有相關的技術發展來解決這些問題。

我們都知道一個大資料處理系統分為:

  1. 分布式檔案系統:HDFS,S3
  2. 基于一定的檔案格式将檔案存儲在分布式檔案系統:Parquet,ORC, ARVO
  3. 用來組織檔案的中繼資料系統:Metastore
  4. 處理檔案的計算引擎,包括流處理和批處理:SPARK,FLINK

簡單的說,資料湖技術是計算引擎和底層存儲格式之間的一種資料組織格式,用來定義資料、中繼資料的組織方式。

并實作以下的一些功能:

  1. 支援事務 (ACID)
  2. 支援流批一體
  3. 支援 schema 演化和 schema 限制
  4. 支援多種底層資料存儲HDFS,OSS,S3,目前并沒有針對資料湖的比較成熟的解決方案,幾個大廠在開發相關技術來解決内部遇到的一些痛點後,開源了幾個項目,比較著名的有Databrics 的 Dalta Lake,Uber 開源的 Hudi,Netflix 開源的 Iceberg。

二、Delta Lake

傳統的 lambda 架構需要同時維護批處理和流處理兩套系統,資源消耗大,維護複雜。

基于 Hive 的數倉或者傳統的檔案存儲格式(比如 parquet / ORC),都存在一些難以解決的問題:

  1. 小檔案問題;
  2. 并發讀寫問題;
  3. 有限的更新支援;
  4. 海量中繼資料(例如分區)導緻 metastore 不堪重負
大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

如上圖,Delta Lake 是 Spark 計算架構和存儲系統之間帶有 Schema 資訊的存儲中間層。

它有一些重要的特性:

  1. 設計了基于 HDFS 存儲的中繼資料系統,解決 metastore 不堪重負的問題;
  2. 支援更多種類的更新模式,比如 Merge / Update / Delete 等操作,配合流式寫入或者讀取的支援,讓實時資料湖變得水到渠成;
  3. 流批操作可以共享同一張表;
  4. 版本概念,可以随時回溯,避免一次誤操作或者代碼邏輯而無法恢複的災難性後果。

Delta Lake 是基于 Parquet 的存儲層,所有的資料都是使用 Parquet 來存儲,能夠利用 parquet 原生高效的壓縮和編碼方案。

Delta Lake 在多并發寫入之間提供 ACID 事務保證。每次寫入都是一個事務,并且在事務日志中記錄了寫入的序列順序。

事務日志跟蹤檔案級别的寫入并使用樂觀并發控制,這非常适合資料湖,因為多次寫入/修改相同的檔案很少發生。在存在沖突的情況下,Delta Lake 會抛出并發修改異常以便使用者能夠處理它們并重試其作業。

Delta Lake 其實隻是一個 Lib 庫,不是一個 service,不需要單獨部署,而是直接依附于計算引擎的,但目前隻支援 spark 引擎,使用過程中和 parquet 唯一的差別是把 format parquet 換成 delta 即可,可謂是部署和使用成本極低。

三、Apache Hudi

1. Hudi 是什麼

一般來說,我們會将大量資料存儲到HDFS/S3,新資料增量寫入,而舊資料鮮有改動,特别是在經過資料清洗,放入資料倉庫的場景。

且在資料倉庫如 hive中,對于update的支援非常有限,計算昂貴。

另一方面,若是有僅對某段時間内新增資料進行分析的場景,則hive、presto、hbase等也未提供原生方式,而是需要根據時間戳進行過濾分析。

Apache Hudi 代表 Hadoop Upserts anD Incrementals,能夠使HDFS資料集在分鐘級的時延内支援變更,也支援下遊系統對這個資料集的增量處理。

Hudi資料集通過自定義的 nputFormat 相容目前 Hadoop 生态系統,包括 Apache Hive,Apache Parquet,Presto 和 Apache Spark,使得終端使用者可以無縫的對接。

如下圖,基于 Hudi 簡化的服務架構,分鐘級延遲。

大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

2. Hudi 存儲的架構

大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

如上圖,最下面有一個時間軸,這是 Hudi 的核心

Hudi 會維護一個時間軸,在每次執行操作時(如寫入、删除、合并等),均會帶有一個時間戳。

通過時間軸,可以實作在僅查詢某個時間點之後成功送出的資料,或是僅查詢某個時間點之前的資料。

這樣可以避免掃描更大的時間範圍,并非常高效地隻消費更改過的檔案(例如在某個時間點送出了更改操作後,僅 query 某個時間點之前的資料,則仍可以 query 修改前的資料)。

如上圖的左邊,Hudi 将資料集組織到與 Hive 表非常相似的基本路徑下的目錄結構中。

資料集分為多個分區,每個分區均由相對于基本路徑的分區路徑唯一辨別。

如上圖的中間部分,Hudi 以兩種不同的存儲格式存儲所有攝取的資料。

  • 讀優化的列存格式(ROFormat):僅使用列式檔案(parquet)存儲資料。在寫入/更新資料時,直接同步合并原檔案,生成新版本的基檔案(需要重寫整個列資料檔案,即使隻有一個位元組的新資料被送出)。此存儲類型下,寫入資料非常昂貴,而讀取的成本沒有增加,是以适合頻繁讀的工作負載,因為資料集的最新版本在列式檔案中始終可用,以進行高效的查詢。
  • 寫優化的行存格式(WOFormat):使用列式(parquet)與行式(avro)檔案組合,進行資料存儲。在更新記錄時,更新到增量檔案中(avro),然後進行異步(或同步)的compaction,建立列式檔案(parquet)的新版本。此存儲類型适合頻繁寫的工作負載,因為新記錄是以appending 的模式寫入增量檔案中。但是在讀取資料集時,需要将增量檔案與舊檔案進行合并,生成列式檔案。

四、Apache Iceberg

Iceberg 作為新興的資料湖架構之一,開創性的抽象出“表格式”table format)這一中間層,既獨立于上層的計算引擎(如Spark和Flink)和查詢引擎(如Hive和Presto),也和下層的檔案格式(如Parquet,ORC和Avro)互相解耦。

大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

此外 Iceberg 還提供了許多額外的能力:

  • ACID事務;
  • 時間旅行(time travel),以通路之前版本的資料;
  • 完備的自定義類型、分區方式和操作的抽象;
  • 列和分區方式可以進化,而且進化對使用者無感,即無需重新組織或變更資料檔案;
  • 隐式分區,使SQL不用針對分區方式特殊優化;
  • 面向雲存儲的優化等;

Iceberg的架構和實作并未綁定于某一特定引擎,它實作了通用的資料組織格式,利用此格式可以友善地與不同引擎(如Flink、Hive、Spark)對接。

是以 Iceberg 的架構更加的優雅,對于資料格式、類型系統有完備的定義和可進化的設計。

但是 Iceberg 缺少行級更新、删除能力,這兩大能力是現有資料組織最大的賣點,社群仍然在優化中。

五、總結

下表從各個次元,總結了三大資料湖架構支援的特性。

大資料下一站 資料湖 Hudi Iceberg DeltaLake 初探

如果用一個比喻來說明delta、iceberg、hudi、三者差異的話,可以把三個項目比做建房子。

  • Delta的房子底座相對結實,功能樓層也建得相對比較高,但這個房子其實可以說是databricks的,本質上是為了更好地壯大Spark生态,在delta上其他的計算引擎難以替換Spark的位置,尤其是寫入路徑層面。
  • Iceberg的建築基礎非常紮實,擴充到新的計算引擎或者檔案系統都非常的友善,但是現在功能樓層相對低一點,目前最缺的功能就是upsert和compaction兩個,Iceberg社群正在以最高優先級推動這兩個功能的實作。
  • Hudi的情況要相對不一樣,它的建築基礎設計不如iceberg結實,舉個例子,如果要接入Flink作為Sink的話,需要把整個房子從底向上翻一遍,把接口抽象出來,同時還要考慮不影響其他功能,當然Hudi的功能樓層還是比較完善的,提供的upsert和compaction功能直接命中廣大群衆的痛點。