首頁 > 軟體

Lakehouse資料湖並行控制陷阱分析

2022-03-30 19:04:34

1. 概述

如今資料湖上的事務被認為是 Lakehouse 的一個關鍵特徵。 但到目前為止,實際完成了什麼? 目前有哪些方法? 它們在現實世界中的表現如何? 這些問題是本部落格的重點。

有幸從事過各種資料庫專案——RDBMS (Oracle)、NoSQL 鍵值儲存 (Voldemort)、流資料庫 (ksqlDB)、閉源實時資料儲存,當然還有 Apache Hudi, 我可以肯定地說,工作負載的不同深刻地影響了不同資料庫中採用的並行控制機制。本部落格還將介紹我們如何重新思考 Apache Hudi 資料湖的並行控制機制。

首先,我們直截了當點,RDBMS 資料庫提供了最豐富的事務功能集和最廣泛的並行控制機制,不同的隔離級別、細粒度鎖、死鎖檢測/避免等其他更多機制,因為它們必須支援行級變更和跨多個表的讀取,同時強制執行鍵約束並維護索引。而NoSQL 儲存提供了非常弱的保證,例如僅僅提供最終一致性和簡單的行級原子性,以換取更簡單的工作負載的更好的擴充套件性。傳統資料倉儲基於列存或多或少提供了您在 RDBMS 中可以找到的全套功能,強制執行鎖定和鍵約束,而云資料倉儲似乎更多地關注存算分離架構,同時提供更少的隔離級別。作為一個令人驚訝的例子,沒有強制執行鍵約束。

2. 資料湖並行控制中的陷阱

從歷史看來,資料湖一直被視為在雲端儲存上讀取/寫入檔案的批次處理作業,有趣的是看到大多數新工作如何擴充套件此檢視並使用某種形式的“樂觀並行控制”(OCC)來實現檔案版本控制。 OCC 作業採用表級鎖來檢查它們是否影響了重疊檔案,如果存在衝突則中止操作,鎖有時甚至只是在單個 Apache Spark Driver節點上持有的 JVM 級鎖,這對於主要將檔案附加到表的舊式批次處理作業的輕量級協調來說可能沒問題,但不能廣泛應用於現代資料湖工作負載。此類方法是在考慮不可變/僅附加資料模型的情況下構建的,這些模型不適用於增量資料處理或鍵控更新/刪除。 OCC 非常樂觀地認為真正的衝突永遠不會發生。將 OCC 與 RDBMS 或傳統資料倉儲的完全成熟的事務功能進行比較的開發人員佈道是完全錯誤的,直接參照維基百科——“如果頻繁地爭用資料資源,重複重啟事務的成本會顯著損害效能,在這種情況下,其他並行控制方法可能更適合。” 當衝突確實發生時,它們會導致大量資源浪費,因為你有每次嘗試執行幾個小時後都失敗的批次處理作業!

想象一下兩個寫入程序的真實場景:一個每 30 分鐘生成一次新資料的攝取寫入作業和一個執行 GDPR 的刪除作業,需要 2 小時才能完成刪除。這些很可能與隨機刪除重疊檔案,並且刪除作業幾乎可以保證每次都餓死並且無法提交。 在資料庫方面,將長期執行的事務與樂觀混合會導致失望,因為事務越長,它們重疊的可能性就越高。

那麼有什麼替代方案呢?鎖?維基百科還說 - “但是,基於鎖(“悲觀”)的方法也可能提供較差的效能,因為即使避免了死鎖,鎖也會極大地限制有效的並行性。”。這就是 Hudi 採用不同方法的地方,我們認為這種方法更適合現代資料湖事務,這些事務通常是長期執行的,甚至是連續的。與資料庫的標準讀/寫相比,資料湖工作負載與高吞吐量流處理作業共用更多特徵,這就是我們借鑑的地方。在流處理中,事件被序列化為單個有序紀錄檔,避免任何鎖/並行瓶頸,使用者可以每秒連續處理數百萬個事件。Hudi 在 Hudi 時間線上實現了一個檔案級、基於紀錄檔的並行控制協定,而該協定又依賴於對雲端儲存的最低限度的原子寫入。通過將事件紀錄檔構建為程序間協調的核心部分,Hudi 能夠提供一些靈活的部署模型,與僅跟蹤錶快照的純 OCC 方法相比,這些模型提供更高的並行性。

3. 模型 1:單寫入,內聯表服務

並行控制的最簡單形式就是完全沒有並行。 資料湖表通常在其上執行公共服務以確保效率,從舊版本和紀錄檔中回收儲存空間、合併檔案(Hudi 中的Clustering)、合併增量(Hudi 中的Compaction)等等。 Hudi 可以簡單地消除對並行控制的需求,並通過支援這些開箱即用的表服務並在每次寫入表後內聯執行來最大化吞吐量。

執行計劃是冪等的,持久化至時間線並從故障中自動恢復。對於大多數簡單的用例,這意味著只需寫入就足以獲得一個不需要並行控制的管理良好的表。

4. 模型2:單寫入,非同步表服務

我們上面的刪除/攝取範例並不是那麼簡單。雖然攝取/寫入可能只是更新表上的最後 N 個分割區,但刪除甚至可能跨越整個表,將它們混合在同一個工作負載中可能會大大影響攝取延遲,因此Hudi 提供了以非同步方式執行表服務的選項,其中大部分繁重的工作(例如通過壓縮服務實際重寫列資料)是非同步完成的,消除了任何重複的浪費重試,同時還使用Clustering技術。因此單個寫入可以同時使用常規更新和 GDPR 刪除並將它們序列化到紀錄檔中。鑑於 Hudi 具有記錄級索引並且 avro 紀錄檔寫入要便宜得多(與寫入 parquet 相比,後者可能要貴 10 倍或更高),攝取延遲可以持續,同時享受出色的可回溯性。事實上我們能夠在 Uber 將這個模型擴充套件到 100 PB資料規模,通過將所有刪除和更新排序到同一個源 Apache Kafka 主題中,並行控制不僅僅是鎖,Hudi 無需任何外部鎖即可完成所有這一切。

5. 模型3:多寫入

但是並不總是可以將刪除序列化到相同的寫入流中,或者需要基於 sql 的刪除。 對於多個分散式程序,某種形式的鎖是不可避免的,但就像真正的資料庫一樣,Hudi 的並行模型足夠智慧,可以將實際寫入表的內容與管理或優化表的表服務區分開來。 Hudi 提供了類似的跨多個寫入器的樂觀並行控制,但表服務仍然可以完全無鎖和非同步地執行。 這意味著刪除作業只能對刪除進行編碼,攝取作業可以記錄更新,而壓縮服務再次將更新/刪除應用於基本檔案。 儘管刪除作業和攝取作業可以像我們上面提到的那樣相互競爭和餓死,但它們的執行時間要低得多,浪費也大大降低,因為壓縮完成了parquet/列資料寫入的繁重工作。

綜上所述,在這個基礎上我們還有很多方法可以改進。

首先,Hudi 已經實現了一種標記機制,可以跟蹤作為活動寫入事務一部分的所有檔案,以及一種可以跟蹤表的活動寫入者的心跳機制。這可以由其他活動事務/寫入器直接使用來檢測其他寫入器正在做什麼,如果檢測到衝突,則儘早中止,從而更快地將叢集資源返回給其他作業。

雖然在需要可序列化快照隔離時樂觀並行控制很有吸引力,但它既不是最佳方法,也不是處理寫入者之間並行性的唯一方法。我們計劃使用 CRDT 和廣泛採用的流處理概念,通過我們的紀錄檔合併 API 實現完全無鎖的並行控制,這已經被證明可以為資料湖維持巨大的連續寫入量。

談到鍵約束,Hudi 是當今唯一確保唯一鍵約束的湖事務層,但僅限於表的記錄鍵。我們將尋求以更通用的形式將此功能擴充套件到非主鍵欄位,並使用上述較新的並行模型。

最後,要使資料湖成功轉型為Lakehouse,我們必須從“Hadoop 倉庫”願景的失敗中吸取教訓,它與新的“Lakehouse”願景有著相似的目標。 設計人員沒有密切關注與資料倉儲相關的缺失技術差距,並且對實際軟體產生了不切實際的期望。 隨著事務和資料庫功能最終成為資料湖的主流,我們必須應用這些經驗教訓並對當前的缺點保持坦率。 如果您正在構建一個 Lakehouse,我希望這篇文章能鼓勵您仔細考慮圍繞並行控制的各種操作和效率方面。 

https://hudi.apache.org/blog/2021/12/16/lakehouse-concurrency-control-are-we-too-optimistic

以上就是Lakehouse資料湖並行控制陷阱分析的詳細內容,更多關於Lakehouse資料湖並行控制的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com