Lakehouse數(shù)據(jù)湖并發(fā)控制陷阱分析
1. 概述
如今數(shù)據(jù)湖上的事務(wù)被認(rèn)為是 Lakehouse 的一個(gè)關(guān)鍵特征。 但到目前為止,實(shí)際完成了什么? 目前有哪些方法? 它們?cè)诂F(xiàn)實(shí)世界中的表現(xiàn)如何? 這些問(wèn)題是本博客的重點(diǎn)。
有幸從事過(guò)各種數(shù)據(jù)庫(kù)項(xiàng)目——RDBMS (Oracle)、NoSQL 鍵值存儲(chǔ) (Voldemort)、流數(shù)據(jù)庫(kù) (ksqlDB)、閉源實(shí)時(shí)數(shù)據(jù)存儲(chǔ),當(dāng)然還有 Apache Hudi, 我可以肯定地說(shuō),工作負(fù)載的不同深刻地影響了不同數(shù)據(jù)庫(kù)中采用的并發(fā)控制機(jī)制。本博客還將介紹我們?nèi)绾沃匦滤伎?Apache Hudi 數(shù)據(jù)湖的并發(fā)控制機(jī)制。
首先,我們直截了當(dāng)點(diǎn),RDBMS 數(shù)據(jù)庫(kù)提供了最豐富的事務(wù)功能集和最廣泛的并發(fā)控制機(jī)制,不同的隔離級(jí)別、細(xì)粒度鎖、死鎖檢測(cè)/避免等其他更多機(jī)制,因?yàn)樗鼈儽仨氈С中屑?jí)變更和跨多個(gè)表的讀取,同時(shí)強(qiáng)制執(zhí)行鍵約束并維護(hù)索引。而NoSQL 存儲(chǔ)提供了非常弱的保證,例如僅僅提供最終一致性和簡(jiǎn)單的行級(jí)原子性,以換取更簡(jiǎn)單的工作負(fù)載的更好的擴(kuò)展性。傳統(tǒng)數(shù)據(jù)倉(cāng)庫(kù)基于列存或多或少提供了您在 RDBMS 中可以找到的全套功能,強(qiáng)制執(zhí)行鎖定和鍵約束,而云數(shù)據(jù)倉(cāng)庫(kù)似乎更多地關(guān)注存算分離架構(gòu),同時(shí)提供更少的隔離級(jí)別。作為一個(gè)令人驚訝的例子,沒(méi)有強(qiáng)制執(zhí)行鍵約束。
2. 數(shù)據(jù)湖并發(fā)控制中的陷阱
從歷史看來(lái),數(shù)據(jù)湖一直被視為在云存儲(chǔ)上讀取/寫(xiě)入文件的批處理作業(yè),有趣的是看到大多數(shù)新工作如何擴(kuò)展此視圖并使用某種形式的“樂(lè)觀并發(fā)控制”(OCC)來(lái)實(shí)現(xiàn)文件版本控制。 OCC 作業(yè)采用表級(jí)鎖來(lái)檢查它們是否影響了重疊文件,如果存在沖突則中止操作,鎖有時(shí)甚至只是在單個(gè) Apache Spark Driver節(jié)點(diǎn)上持有的 JVM 級(jí)鎖,這對(duì)于主要將文件附加到表的舊式批處理作業(yè)的輕量級(jí)協(xié)調(diào)來(lái)說(shuō)可能沒(méi)問(wèn)題,但不能廣泛應(yīng)用于現(xiàn)代數(shù)據(jù)湖工作負(fù)載。此類(lèi)方法是在考慮不可變/僅附加數(shù)據(jù)模型的情況下構(gòu)建的,這些模型不適用于增量數(shù)據(jù)處理或鍵控更新/刪除。 OCC 非常樂(lè)觀地認(rèn)為真正的沖突永遠(yuǎn)不會(huì)發(fā)生。將 OCC 與 RDBMS 或傳統(tǒng)數(shù)據(jù)倉(cāng)庫(kù)的完全成熟的事務(wù)功能進(jìn)行比較的開(kāi)發(fā)人員布道是完全錯(cuò)誤的,直接引用維基百科——“如果頻繁地爭(zhēng)用數(shù)據(jù)資源,重復(fù)重啟事務(wù)的成本會(huì)顯著損害性能,在這種情況下,其他并發(fā)控制方法可能更適合。” 當(dāng)沖突確實(shí)發(fā)生時(shí),它們會(huì)導(dǎo)致大量資源浪費(fèi),因?yàn)槟阌忻看螄L試運(yùn)行幾個(gè)小時(shí)后都失敗的批處理作業(yè)!
想象一下兩個(gè)寫(xiě)入進(jìn)程的真實(shí)場(chǎng)景:一個(gè)每 30 分鐘生成一次新數(shù)據(jù)的攝取寫(xiě)入作業(yè)和一個(gè)執(zhí)行 GDPR 的刪除作業(yè),需要 2 小時(shí)才能完成刪除。這些很可能與隨機(jī)刪除重疊文件,并且刪除作業(yè)幾乎可以保證每次都餓死并且無(wú)法提交。 在數(shù)據(jù)庫(kù)方面,將長(zhǎng)期運(yùn)行的事務(wù)與樂(lè)觀混合會(huì)導(dǎo)致失望,因?yàn)槭聞?wù)越長(zhǎng),它們重疊的可能性就越高。
那么有什么替代方案呢?鎖?維基百科還說(shuō) - “但是,基于鎖(“悲觀”)的方法也可能提供較差的性能,因?yàn)榧词贡苊饬怂梨i,鎖也會(huì)極大地限制有效的并發(fā)性。”。這就是 Hudi 采用不同方法的地方,我們認(rèn)為這種方法更適合現(xiàn)代數(shù)據(jù)湖事務(wù),這些事務(wù)通常是長(zhǎng)期運(yùn)行的,甚至是連續(xù)的。與數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)讀/寫(xiě)相比,數(shù)據(jù)湖工作負(fù)載與高吞吐量流處理作業(yè)共享更多特征,這就是我們借鑒的地方。在流處理中,事件被序列化為單個(gè)有序日志,避免任何鎖/并發(fā)瓶頸,用戶可以每秒連續(xù)處理數(shù)百萬(wàn)個(gè)事件。Hudi 在 Hudi 時(shí)間線上實(shí)現(xiàn)了一個(gè)文件級(jí)、基于日志的并發(fā)控制協(xié)議,而該協(xié)議又依賴于對(duì)云存儲(chǔ)的最低限度的原子寫(xiě)入。通過(guò)將事件日志構(gòu)建為進(jìn)程間協(xié)調(diào)的核心部分,Hudi 能夠提供一些靈活的部署模型,與僅跟蹤表快照的純 OCC 方法相比,這些模型提供更高的并發(fā)性。
3. 模型 1:?jiǎn)螌?xiě)入,內(nèi)聯(lián)表服務(wù)
并發(fā)控制的最簡(jiǎn)單形式就是完全沒(méi)有并發(fā)。 數(shù)據(jù)湖表通常在其上運(yùn)行公共服務(wù)以確保效率,從舊版本和日志中回收存儲(chǔ)空間、合并文件(Hudi 中的Clustering)、合并增量(Hudi 中的Compaction)等等。 Hudi 可以簡(jiǎn)單地消除對(duì)并發(fā)控制的需求,并通過(guò)支持這些開(kāi)箱即用的表服務(wù)并在每次寫(xiě)入表后內(nèi)聯(lián)運(yùn)行來(lái)最大化吞吐量。
執(zhí)行計(jì)劃是冪等的,持久化至?xí)r間線并從故障中自動(dòng)恢復(fù)。對(duì)于大多數(shù)簡(jiǎn)單的用例,這意味著只需寫(xiě)入就足以獲得一個(gè)不需要并發(fā)控制的管理良好的表。
4. 模型2:?jiǎn)螌?xiě)入,異步表服務(wù)
我們上面的刪除/攝取示例并不是那么簡(jiǎn)單。雖然攝取/寫(xiě)入可能只是更新表上的最后 N 個(gè)分區(qū),但刪除甚至可能跨越整個(gè)表,將它們混合在同一個(gè)工作負(fù)載中可能會(huì)大大影響攝取延遲,因此Hudi 提供了以異步方式運(yùn)行表服務(wù)的選項(xiàng),其中大部分繁重的工作(例如通過(guò)壓縮服務(wù)實(shí)際重寫(xiě)列數(shù)據(jù))是異步完成的,消除了任何重復(fù)的浪費(fèi)重試,同時(shí)還使用Clustering技術(shù)。因此單個(gè)寫(xiě)入可以同時(shí)使用常規(guī)更新和 GDPR 刪除并將它們序列化到日志中。鑒于 Hudi 具有記錄級(jí)索引并且 avro 日志寫(xiě)入要便宜得多(與寫(xiě)入 parquet 相比,后者可能要貴 10 倍或更高),攝取延遲可以持續(xù),同時(shí)享受出色的可回溯性。事實(shí)上我們能夠在 Uber 將這個(gè)模型擴(kuò)展到 100 PB數(shù)據(jù)規(guī)模,通過(guò)將所有刪除和更新排序到同一個(gè)源 Apache Kafka 主題中,并發(fā)控制不僅僅是鎖,Hudi 無(wú)需任何外部鎖即可完成所有這一切。
5. 模型3:多寫(xiě)入
但是并不總是可以將刪除序列化到相同的寫(xiě)入流中,或者需要基于 sql 的刪除。 對(duì)于多個(gè)分布式進(jìn)程,某種形式的鎖是不可避免的,但就像真正的數(shù)據(jù)庫(kù)一樣,Hudi 的并發(fā)模型足夠智能,可以將實(shí)際寫(xiě)入表的內(nèi)容與管理或優(yōu)化表的表服務(wù)區(qū)分開(kāi)來(lái)。 Hudi 提供了類(lèi)似的跨多個(gè)寫(xiě)入器的樂(lè)觀并發(fā)控制,但表服務(wù)仍然可以完全無(wú)鎖和異步地執(zhí)行。 這意味著刪除作業(yè)只能對(duì)刪除進(jìn)行編碼,攝取作業(yè)可以記錄更新,而壓縮服務(wù)再次將更新/刪除應(yīng)用于基本文件。 盡管刪除作業(yè)和攝取作業(yè)可以像我們上面提到的那樣相互競(jìng)爭(zhēng)和餓死,但它們的運(yùn)行時(shí)間要低得多,浪費(fèi)也大大降低,因?yàn)閴嚎s完成了parquet/列數(shù)據(jù)寫(xiě)入的繁重工作。
綜上所述,在這個(gè)基礎(chǔ)上我們還有很多方法可以改進(jìn)。
首先,Hudi 已經(jīng)實(shí)現(xiàn)了一種標(biāo)記機(jī)制,可以跟蹤作為活動(dòng)寫(xiě)入事務(wù)一部分的所有文件,以及一種可以跟蹤表的活動(dòng)寫(xiě)入者的心跳機(jī)制。這可以由其他活動(dòng)事務(wù)/寫(xiě)入器直接使用來(lái)檢測(cè)其他寫(xiě)入器正在做什么,如果檢測(cè)到?jīng)_突,則盡早中止,從而更快地將集群資源返回給其他作業(yè)。
雖然在需要可序列化快照隔離時(shí)樂(lè)觀并發(fā)控制很有吸引力,但它既不是最佳方法,也不是處理寫(xiě)入者之間并發(fā)性的唯一方法。我們計(jì)劃使用 CRDT 和廣泛采用的流處理概念,通過(guò)我們的日志合并 API 實(shí)現(xiàn)完全無(wú)鎖的并發(fā)控制,這已經(jīng)被證明可以為數(shù)據(jù)湖維持巨大的連續(xù)寫(xiě)入量。
談到鍵約束,Hudi 是當(dāng)今唯一確保唯一鍵約束的湖事務(wù)層,但僅限于表的記錄鍵。我們將尋求以更通用的形式將此功能擴(kuò)展到非主鍵字段,并使用上述較新的并發(fā)模型。
最后,要使數(shù)據(jù)湖成功轉(zhuǎn)型為L(zhǎng)akehouse,我們必須從“Hadoop 倉(cāng)庫(kù)”愿景的失敗中吸取教訓(xùn),它與新的“Lakehouse”愿景有著相似的目標(biāo)。 設(shè)計(jì)人員沒(méi)有密切關(guān)注與數(shù)據(jù)倉(cāng)庫(kù)相關(guān)的缺失技術(shù)差距,并且對(duì)實(shí)際軟件產(chǎn)生了不切實(shí)際的期望。 隨著事務(wù)和數(shù)據(jù)庫(kù)功能最終成為數(shù)據(jù)湖的主流,我們必須應(yīng)用這些經(jīng)驗(yàn)教訓(xùn)并對(duì)當(dāng)前的缺點(diǎn)保持坦率。 如果您正在構(gòu)建一個(gè) Lakehouse,我希望這篇文章能鼓勵(lì)您仔細(xì)考慮圍繞并發(fā)控制的各種操作和效率方面。
https://hudi.apache.org/blog/2021/12/16/lakehouse-concurrency-control-are-we-too-optimistic
以上就是Lakehouse數(shù)據(jù)湖并發(fā)控制陷阱分析的詳細(xì)內(nèi)容,更多關(guān)于Lakehouse數(shù)據(jù)湖并發(fā)控制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Access與sql server的語(yǔ)法區(qū)別總結(jié)
這篇文章主要介紹了Access與sql server的語(yǔ)法區(qū)別總結(jié),需要的朋友可以參考下2007-03-03如何自己動(dòng)手寫(xiě)SQL執(zhí)行引擎
本文主要介紹了如何自己動(dòng)手寫(xiě)SQL執(zhí)行引擎,感興趣的同學(xué),可以參考下。2021-06-06SQL Server數(shù)據(jù)庫(kù)性能優(yōu)化技術(shù)
SQL Server數(shù)據(jù)庫(kù)性能優(yōu)化技術(shù)...2007-06-06JetBrains出品一款好用到爆的DataGrip數(shù)據(jù)庫(kù)工具使用入門(mén)
這篇文章主要介紹了JetBrains出品一款好用到爆的DataGrip數(shù)據(jù)庫(kù)工具使用入門(mén),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01