Delta Lake 資料湖原理和實戰

韓楠發表於2022-04-27



                                                                                                     編輯 | 韓楠  

                                                                                                                    約  4,500 字 | 9 分鐘閱讀  


今天我要與你分享的內容是Delta Lake資料湖原理與實戰。那麼為什麼想為大家分享資料湖方面的內容呢?


一個是當下資料 湖的概念越來越火,但到底什麼是資料湖,你瞭解到什麼程度了? 好多小夥伴一直講沒法對資料湖有個很好的理解,今天我就從概念和特點上,同你一起梳理下資料湖的核心知識點。


再者,資料湖這麼火,到底是如何實現的,它是大資料架構的銀彈嗎?圍繞這個問題為大家介紹資料湖的核心實現原理和實戰。


圖1


今天這篇,講原理,講實戰,這第一步呢得先知道資料湖它是什麼,就不得不涉及到了一些概念性的東西了。


這一篇概念和邏輯上的內容偏多,面兒上看或多或少可能還覺得比較枯燥,但是希望大家不要著急,一定要跟著內容的思路,細細體會資料湖的概念和實現思路,這不但對大家理解資料湖有幫助,同時對以後理解其他大資料框架也會有益處。



0 1

我們得先知道數倉是個啥


這裡得先提一點就是:資料湖它是從資料倉儲的概念上發展而來的。因此在開啟資料湖原理和實戰之旅前,我們首先得再往前追溯一些很直接的、有強相關性的內容點,說到這就有必要回顧下數倉的基礎知識了。



我們就從資料倉儲概念說起吧,它簡稱為數倉,英文名Data Warehouse,可簡寫為DW或DWH。 資料倉儲是為企業決策提供所有型別資料支援的集合。企業建立數倉的主要目的是為分析性報告和決策支援目的而建立。


簡單介紹了資料倉儲的概念,我們們看下資料有哪些特點。這將幫助我們進一步理解數倉。


1.資料是面向主題的: 是在較高層次上對分析物件的資料的一個完整、一致的描述,能完整、統一地刻劃各個分析物件所涉及的企業的各項資料,以及資料之間的聯絡。


2.資料是整合的: 資料進入資料倉儲之前,統一源資料中所有矛盾之處,如欄位的同名異義、異名同義、單位不統一、字長不一致。


3.時間段內不可更新: 無更新操作,不用考慮資料整性保護、併發控制;重點關注高效能查詢;BI要求高。

圖2


4.資料隨時間不斷變化: 資料倉儲隨時間變化不斷增加新的資料內容;資料倉儲隨時間變化不斷刪去舊的資料內容;數倉綜合資料中很多跟時間有關。


02

何為資料湖及其核心要點


首先我們看下資料湖的概念, 資料湖指的是可以儲存任意格式資料(結構化和非結構化)的儲存中心。

為了便於大家更好地理解資料湖,我們們將通過資料湖與數倉的對比分析展開講。這部分也是理解資料湖的核心,希望大家能夠通過深入理解資料湖和數倉的區別,以辯證的思維方法對資料湖有個比較深入的瞭解,進而幫助大家實踐過程中能夠有更多看待問題的視角,尤其是方案落地上的思考。


(1)資料層面:數倉的資料大部分來自事務系統、運營資料庫和業務線應用程式,有相對明確的資料結構;而 資料湖的資料來自IoT裝置、網站、移動應用程式、社交媒體和企業應用程式等,既包含結構化資料,也包含非結構化資料。


(2)Schema層面: 數倉的Schema在資料入庫之前的設計階段就產生了,而資料湖的Schema是在寫入資料時實時分析資料結構而產生的。資料倉儲模式是schema on write,資料湖模式是schema on read。


圖3


(3)資料質量:因為數倉的資料資料具備完整的資料結構並且支援事務等操作,因此 資料質量方面比數倉較好。


(4)應用層面: 數倉主要用於批處理報告、BI 和視覺化等;資料湖主要用於機器學習、預測分析、資料發現和分析。



03

資料湖面臨的挑戰


前面通過資料湖和數倉的對比分析,大家可能會感覺資料湖真是個“好東西”,讓我趕快實戰起來吧。莫急,其實資料湖的概念,是隨著業務對需求的變化在數倉不能滿足要求的情況下提出來的。不過要實現資料湖提出的願景,其實還是面臨很多具體的技術挑戰。


接下來我們們介紹下資料湖實現上的技術挑戰。只有搞清楚了這些,我們才能對如何構建資料湖有個整體的思路,這些挑戰也是資料湖要解決的核心問題。


(1)對資料湖進行的讀寫操作不可靠。


由於資料湖中資料動輒上TB,因此其讀寫相對耗時,不可能像關係型資料庫那樣以鎖表加事務的方式保障資料的一致性。這樣的話會引起資料寫入的過程中有人讀取資料,從而看到中間狀態資料的情況,類似資料庫中的幻讀。在實際資料湖的設計中,可以通過新增版本號等方式解決。


(2)資料湖的資料質量較差。


由於資料湖對資料的結構沒有要求,因此大量的各種非結構化的資料會存入資料湖,這樣會對後期資料湖中的資料治理,帶來很大的挑戰。


(3)隨著資料量的增加,效能變差。


隨著對資料湖中資料操作的增加,後設資料也會不斷增加,並且資料湖架構一般不會刪除後設資料資訊,因此後設資料湖不斷膨脹,處理資料的作業在後設資料的查詢上會消耗大量的時間。

圖4


(4)更新資料湖中的記錄,非常困難。 資料湖中的資料更新需要工程師通過複雜邏輯實現,維護困難。


(5) 資料如何回滾 方面:資料處理過程中錯誤是不可避免的,因此資料湖要有良好的回滾方案保障資料的完整性。


結合前面的分享,不難發現,要實現資料湖提出的願景,還是有很多具體的技術難題需要解決。



04

Copy-On-Write VS Merge-On-Read模式


基於資料湖的理念,有多種資料湖的實現方案。例如KUDU、Hudi和Delta Lake。這些資料湖方案中很重要一個技術選型,就是更新資料是採用Copy-On-Write 模式,還是採用 Merge-On-Read模式。


要想理解各個資料湖實現的特點,還是得清楚兩者的區別到底在哪兒,如此一來,才能夠幫助我們更好地做分析判斷。


那麼這兩種模式有何區別呢?


1) Copy-On-Write 模式, 指的是當執行資料更新時,從原來的資料複製出來一個副本,在副本上進行資料更新,當副本更新完成後把原始資料替換為當前副本。 它屬於寫放大的操作,適合於資料讀取請求多,資料更新請求少的應用場景。


2) Merge-On-Read 模式, 指的是使用者在寫入和更新資料的時候不處理資料的準確性、Schema的相容性和一直性等問題,當使用者查詢該部分資料時再對資料進行合併,分析。 處理資料的準確性、Schema的相容性和一直性。然後將處理後的結果返回給使用者。也就是說Merge-On-Read 是在讀資料的時候對資料進行修復的。


做個小結:

圖5


通過將資料湖和數倉進行對比分析,我們介紹完了資料湖的核心概念,下面讓我們進入這次分享的重頭戲,Delta Lake資料湖原理和實戰。


05

Delta Lake 資料湖原理


在介紹Delta Lake資料湖原理前,讓我們先快速看下Delta Lake的概念:Delta Lake是Databricks公司開發的資料湖解決方案,它 提供了基於大資料的ACID、版本控制、資料回滾等功能,使得使用者基於Delta Lake和雲端儲存能快速構建起資料湖應用。它採用Copy-On-Write模式。


1.Delta Lake 的主要特點


Delta Lake 解決了資料湖面對的問題,簡化了資料湖構建。下面我們們看下 Delta Lake 的主要特點,具體包括ACID 事務、模式(Schema)管理、資料版本控制和時間旅行、統一的批處理和流接收、記錄更新和刪除。其中ACID 事務、模式(Schema)管理和統一的批處理和流接收是Delta Lake 設計的核心要點,需要同學們重點關注。


(1)ACID 事務:


Delta Lake支援事務操作,在Delta Lake中每個寫操作都是一個事務,事務的狀態通過事務日誌來記錄,事務的日誌會跟蹤每個檔案的寫操作狀態。Delta Lake的併發寫操作使用樂觀鎖的方式控制,當有多個操作同時對一份資料進行寫操作時只會有一個寫操作成功,其他寫操作會丟擲異常,以便客戶端根據異常情況選擇重試還是放棄修改操作。


(2)模式(Schema)管理:


資料在寫入過程中,Delta Lake會檢查DataFrame中資料的Schema資訊,如果發現新的列資料在表中存在但是在DataFrame中不存在,就會將該列資料儲存為null;如果發現DataFrame新的列在表中不存在,則會丟擲異常。同時Delta Lake還可以顯式地新增新列的DDL和自動更新Schema。

圖6


(3)資料版本控制和時間旅行:


Delta Lake將使用者的寫操作以版本的形成儲存,也就是說每次對資料執行一次更新操作Delta Lake都會生成一個新的版本,使用者在讀取資料時,可以在API中傳入版本號讀取任何歷史版本的資料。


同時,還可以將表中資料的狀態還原到歷史的某個版本。


(4)統一的批處理和流接收(Streaming Sink):


Delta Lake可以從Spark的結構化流獲取資料並結合自身的ACID、事務、可伸縮的後設資料處理的能力,來實現多種近實時的資料分析。


(5)記錄更新和刪除:


在未來的版本中,Delta Lake計劃支援DML的合併、更新和刪除功能。


2.Delta Lake資料儲存


資料的儲存是資料湖要實現的核心技術點,你需要重點關注。接下來我們們介紹下Delta Lake的資料儲存原理。


Delta Lake 的資料儲存原理其實很簡單。它通過 Partition Directories 儲存資料,資料格式推薦為 Parquet,然後通過 Transaction Log (事務日誌)記錄的表版本(Table Version) 和變更歷史,以維護歷史版本資料。


Delta Lake中的表其實是一些列操作的結果,例如:更新後設資料、更新表名、變更 Schema、增加或刪除Partition、新增或者移除檔案。

圖7


Delta Lake會以日誌的形式將所有的操作儲存在表中。也就是說當前表中的資料是一些列歷史操作的結果,為Delta Lake表的結構資訊。 其中包含了表名稱、事務日誌(每個事務日誌檔案代表了一個資料版本)、分割槽目錄和資料檔案。


3.Delta Lake原子性保障


如何保障在多使用者併發讀寫下的情況下資料的原子性,是一個資料湖設計必須要考慮的問題,在該問題的處理上, Delta Lake解決問題的方式很巧妙,它只要保障 Commit File 的順序和原子性就可以了。


這裡舉個例子,我們先在表中新增一個檔案001.snappy.parquet,形成一個版本,以00.json的日誌檔案形式儲存。接著刪除剛才新增的01.snappy.parquet檔案,重新加入一個新的02.snappy.parquet檔案形成另外一個版本01.json。

圖片

圖8


這樣在資料的寫入過程中,如果有人讀取資料,則每次只能讀取到已經 Commit 的結果資料。


4.Delta Lake併發寫


Delta Lake使用Copy-On-Write實現寫操作。由於Spark應用屬於高併發讀,低併發寫的應用,因此它比較適合使用樂觀鎖來控制併發寫。接下來分別從資料讀取和寫入兩個方面,看下Delta Lake的資料一致性問題。


資料讀取的是表的某個版本的快照(Snapshot),因此即使在讀取過程中資料有更新,讀操作看到的也是之前版本的資料, 也就是說在資料更新過程中讀操作看到的資料不會有變動。


在寫資料的情況下,Delta 使用樂觀鎖來保證事務,寫操作分為 3 個階段。


(1)讀取:讀取最新版本的資料,作為一個資料集的一個Snapshot, 然後定位需要改變的檔案,後續寫操作在Snapshot的版本上寫入新資料。


(2)寫入:執行寫操作,並將資料版本加1,準備提交寫操作結果。

圖9


(3)驗證和提交:在提交寫操作結果之前,檢測是否有其他已經提交的操作更新了檔案,並檢查和本事務需要更新的檔案是否有衝突。


沒衝突,就提交本次寫操作結果,產生一個新的版本資料。如果有衝突,就會丟擲一個併發修改異常,放棄修改。這樣保障瞭如果有多個併發寫,即使來自不同的叢集,也會保證一致性。


5.Delta Lake大規模後設資料處理


當不斷地對 Delta Lake 表進行操作時,會不斷地產生提交日誌檔案(Commit Log File)、小檔案,並且隨著時間的推移日誌檔案會不斷的增加,最終會形式很多的小檔案。如果將後設資料像Hive那樣儲存在Hive Metastore 上,則每次讀取資料都需要一行行讀取Partition資訊,並找出Partition下所有的問題資訊,效率低下。


Delta Lake將後設資料儲存在事務日誌中,基於Spark對檔案快速分析的能力,使得Delta Lake 能夠在固定的時間內列出大型目錄中的檔案,從而提高了資料讀取的效率。


06

Delta Lake資料湖實戰


前面介紹完了Delta Lake資料湖的概念和原理,接下來讓我們從實戰的角度看下Delta Lake資料湖的使用。


(1)開啟Delta支援: 首先需要定義一個SparkSession例項物件Spark,並在SparkSession定義時新增Delta的支援。


     val spark = SparkSession.builder().master("local").appName("DeltaDemo").config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension").config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog").config("spark.databricks.deltaschema.autoMerge.enabled", "true").getOrCreate()

    code1


    (2)資料插入: 當定義好spark後,便可以將spark中的資料以delta的格式寫入到spark中。下面程式碼中的format("delta")表示寫入的資料格式為delta,mode("overwrite")表示寫入模式為覆寫。


      val data_update = spark.range(5, 10)data_update.write.format("delta").mode("overwrite").save(basePath+"delta/delta-table")data_update.show()

      code2


      (3)資料更新:當需要對資料進行更新操作時,可以呼叫update方法對符合條件的資料進行更新,比如要將id為偶數的資料id值加100,具體實現為:


        deltaTable.update(condition = expr("id % 2 == 0"),  set = Map("id" -> expr("id + 100")))deltaTable.toDF.show()

        code3


        (4)資料刪除:當一些資料不再需要時,可以呼叫delete方法對資料進行刪除。例如刪除id為偶數的資料程式碼是這樣的:


          deltaTable.delete(condition = expr("id % 2 == 0"))deltaTable.toDF.show()

          code4


          (5)merge操作:delta支援資料的merge操作,具體做法是將原始資料表命名為oldData,並和newData進行merge,來看下具體實現。


             deltaTable.as("oldData").merge(newData.as("newData"), "oldData.id = newData.id")//當資料存在是更新  .whenMatched.update(Map("id" -> col("newData.id")))//當資料不存在是插入  .whenNotMatched.insert(Map("id" -> col("newData.id"))).execute()deltaTable.toDF.show()

            code5


            (6)在Delta中,可以定義在Schema發生變化時,是採用overwrite(覆寫)模式還是mergeSchema(合併Schema)模式更新Schema。


              val df = spark.read.format("delta").option("versionAsOf",3).load(basePath+"delta/delta-table")//overwriteSchema模式df.write.format("delta").option("overwriteSchema", "true").mode("overwrite").save(basePath+"delta/delta-table")//mergeSchema模式df.write.format("delta").option("mergeSchema", "true").mode("overwrite").save(basePath+"delta/delta-table")

              code6


              07

              今日分享-結語


              本文首先介紹了資料湖的概念,資料湖面臨的挑戰、Copy-On-Write & Merge-On-Read兩種模式,為大家理解資料湖掃清知識障礙。接著重點講了Delta Lake資料湖原理和實戰。


              原理部分介紹了Delta Lake 的主要特點、Delta Lake資料儲存、Delta Lake原子性保障、Delta Lake併發寫、Delta Lake大規模後設資料處理等知識。 其中Delta Lake資料儲存、原子性保障、併發寫、大規模後設資料處理,是需要你重點掌握的知識點。這也是我們理解資料湖是如何實現的核心要點。


              圖10


              08

              知識點延伸:LakeHouse(湖倉一體)


              資料湖適合各種來源資料的儲存,但又缺少一些關鍵功能,比如強事務、隔離性、不保證執行資料質量等。


              為了解決資料湖的侷限性,有部分專家提出湖倉一體(LakeHouse)方案,湖倉一體是一種新型開放式架構,將資料湖和資料倉儲的優勢充分結合,它構建在資料湖低成本的資料儲存架構之上,又繼承了資料倉儲的資料處理和管理功能。      

              圖11


              LakeHouse在事務支援、資料的模型化和資料治理、BI支援方面,有比較大的優勢。但是限於篇幅這裡不再展開介紹,如果大家感興趣後續我再跟大家聊一下。





              來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70016482/viewspace-2889058/,如需轉載,請註明出處,否則將追究法律責任。

              相關文章