[LakeHouse] Delta Lake全部開源稼锅,聊聊Delta的實(shí)現(xiàn)架構(gòu)

歡迎關(guān)注公眾號(hào)“Tim在路上”
剛剛結(jié)束的Data + AI summit上岳遥,Databricks宣布將Delta Lake全部開源。

目前在LakeHouse的市場(chǎng)上國(guó)內(nèi)有Hudi聊记,國(guó)外有Iceberg, Delta Lake社區(qū)正被他們沖擊著,這次Delta Lake的全部開源不管是急病亂投醫(yī)恢暖,還是絕地反擊我們暫不討論排监。今天我們主要來了解了Delta Lake是如何實(shí)現(xiàn)的。

Delta Lake的誕生

在2017年杰捂,Delta Lake 橫空出世舆床,它主打的概念是湖倉(cāng)一體,最初只開放給付費(fèi)用戶使用。在2019年時(shí)挨队,為提高其市場(chǎng)的占用份額和影響力谷暮,將其進(jìn)行部分開源。

Delta Lake創(chuàng)建之初的定位主要是為解決云存儲(chǔ)中很難實(shí)現(xiàn) ACID 事務(wù)和高性能的問題盛垦。

  1. 更新不是原子操作湿弦,因此查詢不是隔離的,那么在多對(duì)象的更新中腾夯,reader將可以查詢到部分的更新颊埃,某個(gè)對(duì)象更新失敗后回滾需要整體回滾。
  2. 在大型表的云存儲(chǔ)中進(jìn)行元數(shù)據(jù)操作成本很高蝶俱。例如parquet文件的footer中包含min/max統(tǒng)計(jì)信息可以幫助reader進(jìn)行選擇性的讀取班利,在HDFS上讀取這樣的頁(yè)腳可能需要幾毫秒,但是在云存儲(chǔ)上需要更高的讀取延時(shí)跷乐。
  3. 對(duì)象存儲(chǔ)上的list操作性能非常差肥败。

為了解決上面的問題,設(shè)計(jì)并實(shí)現(xiàn)了基于云存儲(chǔ)的ACID表存儲(chǔ)層--Delta Lake愕提。

Delta Lake的實(shí)現(xiàn)思想也很簡(jiǎn)單:使用存儲(chǔ)在云對(duì)象存儲(chǔ)中的預(yù)寫日志,以ACID的方式來管理維護(hù)Delta表中的信息皿哨。

那么Delta Lake是如何解決上面的存儲(chǔ)層問題呢浅侨?我列舉了如下幾個(gè)重要的特性:

  1. 時(shí)間旅行,允許用戶查詢時(shí)間點(diǎn)的快照证膨,也可以根據(jù)時(shí)間點(diǎn)進(jìn)行回滾如输。
  2. Upsert、Delete和Merge操作央勒,可以有效的重寫對(duì)象不见,支持流式更新操作。
  3. 高效的流式IO, 通過流式操作將小對(duì)象寫入表中崔步,并以事務(wù)的方式進(jìn)行合并更新稳吮,同時(shí)還支持增量消費(fèi)。
  4. 自動(dòng)的數(shù)據(jù)布局優(yōu)化井濒,可以自動(dòng)的優(yōu)化表中的對(duì)象大小灶似,并將數(shù)據(jù)記錄進(jìn)行聚類。
  5. 支持schema進(jìn)化瑞你,支持表的schema更改但不用重寫他們酪惭。

Delta Lake的存儲(chǔ)架構(gòu)

Delta Lake 的數(shù)據(jù)存儲(chǔ)原理其實(shí)很簡(jiǎn)單。它通過 Partition Directories 存儲(chǔ)數(shù)據(jù)者甲,數(shù)據(jù)格式推薦為 Parquet春感,然后通過預(yù)寫的 Transaction Log (事務(wù)日志)記錄的表版本(Table Version) 和變更歷史,以維護(hù)歷史版本數(shù)據(jù)。

Delta Lake中的一些表級(jí)的操作鲫懒,例如更新元數(shù)據(jù)纺铭、更新表名、變更 Schema刀疙、增加或刪除Partition舶赔、添加或者移除文件,都會(huì)以日志的形式將所有的操作存儲(chǔ)在表中谦秧。

1ed.png

上圖展示了Delta中數(shù)據(jù)的組織形式竟纳。數(shù)據(jù)和事務(wù)日志都被存儲(chǔ)在表級(jí)的目錄下,其中數(shù)據(jù)以傳統(tǒng)的Hive分區(qū)目錄的方式存儲(chǔ)疚鲤,事務(wù)日志被存儲(chǔ)在_delta_log的目錄下锥累。

  1. Delta每次事務(wù)commit都會(huì)產(chǎn)生一個(gè)json的元數(shù)據(jù)文件,文件內(nèi)容包括本次commit做的所有action集歇,比如AddFile/RemoveFile桶略,也包括對(duì)schema的修改等等;
  2. 每產(chǎn)生一個(gè)新的json文件就會(huì)產(chǎn)生一個(gè)新的Delta的snapshot,snapshot的版本即該json文件中的數(shù)字诲宇,該數(shù)字必須是連續(xù)自增际歼,Delta的某個(gè)版本的snapshot是通過順序回放所有小于等于該snapshot版本號(hào)的所有json文件得到;
  3. Delta Lake會(huì)以一定的頻率做checkpoint,checkpoint以Parquet的格式存儲(chǔ)姑蓝,目的是為了便于使用Spark并行進(jìn)行向量化處理鹅心。
  4. delta_log子目錄下還包含一個(gè)last_checkpoint文件指向最新的checkpoint,從而在日志操作時(shí)可以快速找到最新的checkpoint纺荧。

從上面的元數(shù)據(jù)結(jié)構(gòu)可以看出旭愧,Delta和Hudi和Iceberg其實(shí)是大同小異。

那么Delta基于事務(wù)日志實(shí)現(xiàn)的細(xì)節(jié)又是怎樣的呢宙暇?

Delta事務(wù)日志的實(shí)現(xiàn)細(xì)節(jié)

Delta事務(wù)日志的實(shí)現(xiàn)主要是基于MVCC多版本控制協(xié)議實(shí)現(xiàn)输枯。Delta 的 MVCC 算法保留多個(gè)數(shù)據(jù)副本,而不是立即替換包含正在更新或刪除的記錄的文件占贫。

表的讀忍蚁ā:主要是通過使用事務(wù)日志有選擇地選擇要處理的數(shù)據(jù)文件,確保他們一次只能看到表的一致快照靶剑。

表的寫入與修改:首先蜻拨,樂觀地寫出新數(shù)據(jù)文件或修改現(xiàn)有數(shù)據(jù)文件的拷貝副本。然后桩引,進(jìn)行事務(wù)提交缎讼,通過向日志中添加新條目來創(chuàng)建表的最新原子版本。在此日志條目中坑匠,他們記錄了要在邏輯上添加和刪除哪些數(shù)據(jù)文件血崭,以及對(duì)有關(guān)表的其他元數(shù)據(jù)的更改。

在用戶指定的保留期(默認(rèn)為 7 天)后,過期的數(shù)據(jù)文件將被刪除夹纫。

  • Delta files
./_delta_log/00000000000000000001.json

Delta files是以原子性單位產(chǎn)生的文件(即沒提交一次commit事務(wù))咽瓷,文件的命名是遞增的版本id, 它與checkpoints文件一起構(gòu)成表中所有更改的日志。

Delta files的json文件中會(huì)包含一組應(yīng)用應(yīng)用于前一個(gè)表版本的actions操作舰讹,每一個(gè)actions是以一個(gè)json組存儲(chǔ)與Delta files中茅姜。

其action行為主要有以下幾種:SetTransaction、AddFile月匣、RemoveFile钻洒、Metadata、Protocol锄开、CommitInfo和Column Mapping素标。

  • Checkpoints
./_delta_log/00000000000000000010.checkpoint.parquet

checkpoints文件也存儲(chǔ)在 _delta_log 目錄中,可以為任何版本的表創(chuàng)建萍悴。檢查點(diǎn)包含在此版本之前的所有操作的完整回放头遭,并刪除了無效操作。無效操作是那些已被后續(xù)操作取消的操作(例如刪除已添加的文件)癣诱。

默認(rèn)情況下计维,參考實(shí)現(xiàn)每 10 次提交創(chuàng)建一個(gè)checkpoint。checkpoints文件名基于檢查點(diǎn)包含的表的版本狡刘。

  • 最后一個(gè)Checkpoint

Delta 事務(wù)日志通常包含許多(例如 10,000+)文件享潜。列出如此大的目錄可能會(huì)非常昂貴。最后一個(gè)checkpoint文件可以通過提供指向日志末尾附近的指針來幫助降低構(gòu)建表的最新快照的成本嗅蔬。

讀者可以通過查看_delta_log/_last_checkpoint文件來定位最近的檢查點(diǎn),而不是列出整個(gè)目錄疾就。

U2ntitled.png

那么接下來我們來看看json文件中的內(nèi)容是什么澜术?下面我們撿幾個(gè)重要的展開看看。

Actions

  1. Metadata

元數(shù)據(jù)操作更改表的當(dāng)前元數(shù)據(jù)猬腰。表的第一個(gè)版本必須包含元數(shù)據(jù)操作鸟废。隨后的元數(shù)據(jù)操作完全覆蓋表的當(dāng)前元數(shù)據(jù)。

{
  "metaData":{
    "id":"af23c9d7-fff1-4a5a-a2c8-55c59bd782aa",
    "format":{"provider":"parquet","options":{}},
    "schemaString":"...",
    "partitionColumns":[],
    "configuration":{
      "appendOnly": "true"
    }
  }
}

Metadata中記錄當(dāng)前表id, 表級(jí)別的file format, 分區(qū)列信息等姑荷。在schemaString存儲(chǔ)這columnMapping信息盒延。使用列映射來避免任何列命名限制,并支持重命名和刪除列鼠冕,而無需重寫所有數(shù)據(jù)添寺。列映射有三種模式,按名稱和按id和none懈费。

{
    "name" : "e",
    "type" : {
      "type" : "array",
      "elementType" : {
        "type" : "struct",
        "fields" : [ {
          "name" : "d",
          "type" : "integer",
          "nullable" : false,
          "metadata" : {
            "delta.columnMapping.id": 5,
            "delta.columnMapping.physicalName": "col-a7f4159c-53be-4cb0-b81a-f7e5240cfc49"
          }
        } ]
      },
      "containsNull" : true
    },
    "nullable" : true,
    "metadata" : {
      "delta.columnMapping.id": 4,
      "delta.columnMapping.physicalName": "col-5f422f40-de70-45b2-88ab-1d5c90e94db1"
    }
  }

  1. ADD / Delete File

添加和刪除操作分別用于通過添加或刪除單個(gè)數(shù)據(jù)文件來修改表中的數(shù)據(jù)计露。

{
  "add": {
    "path":"date=2017-12-10/part-000...c000.gz.parquet",
    "partitionValues":{"date":"2017-12-10"},
    "size":841454,
    "modificationTime":1512909768000,
    "dataChange":true
    "stats":"{\\"numRecords\\":1,\\"minValues\\":{\\"val..."
  }
}

add中記錄添加文件的相對(duì)路徑,以及當(dāng)前file所屬的分區(qū)信息,通過還包含了file的統(tǒng)計(jì)信息票罐,包括min/max叉趣。

{
  "remove":{
    "path":"part-00001-9…..snappy.parquet",
    "deletionTimestamp":1515488792485,
    "dataChange":true
  }
}

刪除操作只包括一個(gè)時(shí)間戳,指示刪除發(fā)生的時(shí)間该押。文件的物理刪除可能會(huì)延遲進(jìn)行在用戶指定的過期時(shí)間之后疗杉。刪除操作應(yīng)該作為邏輯刪除保持在表的狀態(tài)中,直到過期蚕礼。當(dāng)增量文件的創(chuàng)建時(shí)間戳超過添加到刪除操作時(shí)間戳的過期閾值時(shí)烟具,邏輯刪除將過期。

  1. Transaction Identifiers
{
  "txn": {
    "appId":"3ba13872-2d47-4e17-86a0-21afd2a22395",
    "version":364475
  }
}

事務(wù)標(biāo)識(shí)符以appId版本對(duì)的形式存儲(chǔ)闻牡,其中appId是修改表的進(jìn)程的唯一標(biāo)識(shí)符净赴,版本表示該應(yīng)用程序取得了多大進(jìn)展。該信息的原子記錄以及對(duì)表的修改使這些外部系統(tǒng)能夠?qū)⑵鋵懭氲紻elta表冪等中罩润。

下面我們來總結(jié)對(duì)比下:

  1. Delta的實(shí)現(xiàn)和Spark深度綁定玖翅,雖然delta2.0官宣支持多種引擎,但I(xiàn)ceberg和Hudi早已可以支持多種引擎割以,另外iceberg不和任何引擎綁定金度。
  2. 目前Delta只支持COW形式,Iceberg和Hudi都支持部分MOR严沥。
  3. 在實(shí)現(xiàn)方式上與Hudi, Iceberg大同小異猜极,但是其事務(wù)日志文件中只記錄了上一版本與當(dāng)前版本的差分Action。如果要獲取某個(gè)commit的完整文件列表就需要把之前的差分Action進(jìn)行重放消玄。不過Delta引入checkpoint機(jī)制跟伏,當(dāng)commit積累到一定數(shù)量,會(huì)生成一個(gè)checkpoint, 此時(shí)會(huì)刪除簡(jiǎn)化無效的Action, 后續(xù)的讀取可以基于這個(gè)checkpoint開始重放翩瓜。
  4. Delta可以生成較少的元數(shù)據(jù)文件受扳,基于checkpoint機(jī)制和過期文件的刪除,減少了大量小文件的產(chǎn)生兔跌,但是并不能很好獲取某個(gè)commit的數(shù)據(jù)勘高。Iceberg可能會(huì)產(chǎn)生大量的元數(shù)據(jù)文件,影響了查詢性能坟桅,但也相應(yīng)的增加文件組跳過的能力华望。

后續(xù)會(huì)再繼續(xù)解密下開源的付費(fèi)功能Z-order的實(shí)現(xiàn)源碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仅乓,一起剝皮案震驚了整個(gè)濱河市赖舟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌方灾,老刑警劉巖建蹄,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碌更,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡洞慎,警方通過查閱死者的電腦和手機(jī)痛单,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劲腿,“玉大人旭绒,你說我怎么就攤上這事〗谷耍” “怎么了挥吵?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)花椭。 經(jīng)常有香客問我忽匈,道長(zhǎng),這世上最難降的妖魔是什么矿辽? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任丹允,我火速辦了婚禮,結(jié)果婚禮上袋倔,老公的妹妹穿的比我還像新娘雕蔽。我一直安慰自己,他們只是感情好宾娜,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布批狐。 她就那樣靜靜地躺著,像睡著了一般前塔。 火紅的嫁衣襯著肌膚如雪嚣艇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天华弓,我揣著相機(jī)與錄音髓废,去河邊找鬼。 笑死该抒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顶燕。 我是一名探鬼主播凑保,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼涌攻!你這毒婦竟也來了欧引?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤恳谎,失蹤者是張志新(化名)和其女友劉穎芝此,沒想到半個(gè)月后憋肖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡婚苹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年岸更,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膊升。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怎炊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出廓译,到底是詐尸還是另有隱情评肆,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布非区,位于F島的核電站瓜挽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏征绸。R本人自食惡果不足惜久橙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歹垫。 院中可真熱鬧剥汤,春花似錦、人聲如沸排惨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)暮芭。三九已至鹿驼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辕宏,已是汗流浹背畜晰。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瑞筐,地道東北人凄鼻。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像聚假,于是被迫代替她去往敵國(guó)和親块蚌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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