KUDU學習總結
題記:瞭解KUDU的相關技術,對其技術產生的背景、資料模型、架構和儲存進行知識梳理。
API:https://kudu.apache.org/docs/index.html
1. 技術產生的背景
在 KUDU 之前,大資料主要以兩種方式儲存:
- 靜態資料:以HDFS為儲存引擎
- 優勢:適用於高吞吐量的離線大資料分析場景
- 侷限:資料無法進行隨機的讀寫
- 動態資料:HBase和Cassandra 作為儲存引擎
- 優勢:適用於大資料隨機讀寫場景
- 侷限:批次讀取吞吐量遠不如 HDFS,不適用於批次資料分析的場景
KUDU進行了折中處理:
2. 資料模型
2.1 核心API
KUDU 的對外 API 主要分為寫跟讀兩部分。其中寫包括:Insert、Update、Delete,所有寫操作都必須指定主鍵;讀 KUDU 對外只提供了 Scan 操作,Scan 時使用者可以指定一個或多個過濾器,用於過濾資料。
2.2 一致性模型
跟大多數關係型資料庫一樣,KUDU 也是透過 MVCC(Multi-Version Concurrency Control)來實現內部的事務隔離。
3. 架構
3.1 兩個角色
- Mater Server:負責叢集管理、後設資料管理等功能
- Tablet Server:負責資料儲存,並提供資料讀寫服務
KUDU Client 在與服務端互動時,先從 Master Server 獲取後設資料資訊,然後去 Tablet Server 讀寫資料,如下圖:
3.2 資料分割槽策略
一般資料分割槽策略主要有兩種:
- Range Partitioning:按照欄位值範圍進行分割槽,HBase
- 優勢:資料進行批次讀的時候,可以把大部分的讀變成同一個 tablet 中的順序讀,能夠提升資料讀取的吞吐量。並且按照範圍進行分割槽,我們可以很方便的進行分割槽擴充套件。
- 侷限:是同一個範圍內的資料寫入都會落在單個 tablet 上,寫的壓力大,速度慢
- Hash Partitioning: 按照欄位的 Hash 值進行分割槽,Cassandra
- 優勢:資料的寫入會被均勻的分散到各個 tablet 中,寫入速度快
- 侷限:對於順序讀的場景這一策略就不太適用了,因為資料分散,一次順序讀需要將各個 tablet 中的資料分別讀取並組合,吞吐量低。並且 Hash 分割槽無法應對分割槽擴充套件的情況。
KUDU將不同分割槽策略進行組合,取長補短。
4.儲存
4.1 設計目標
- 快速的列掃描
- 低延遲的隨機更新
- 穩定的效能表現
4.2 儲存方式
列式儲存
優勢
- 查詢少量列時 IO 少,速度快
- 資料壓縮比高
- 便於查詢引擎效能最佳化:延遲物化、直接操作壓縮資料、向量化執行
劣勢
- 查詢列太多時效能下降(KUDU 建議列數不超過 300 )
- 不適合 OLTP 場景
4.3 儲存實現
與其他大資料儲存引擎類似,KUDU 的儲存也是透過 LSM 樹(Log-Structured Merge Tree)來實現的。KUDU 的最小儲存單元是 RowSets,KUDU 中存在兩種 RowSets:MemRowSets、DiskRowSets,資料先寫記憶體中的 MemRowSet,MemRowSet 滿了後刷到磁碟成為一個 DiskRowSet,DiskRowSet 一經寫入,就無法修改了。見下圖:
4.4 應對資料變更
DiskRowSet 是不可修改了,那麼 KUDU 要如何應對資料的更新呢?在 KUDU 中,把 DiskRowSet 分為了兩部分:
- base data: 負責儲存基礎資料
- delta stores:負責儲存 base data 中的變更資料
如上圖所示,資料從 MemRowSet 刷到磁碟後就形成了一份 DiskRowSet(只包含 base data),每份 DiskRowSet 在記憶體中都會有一個對應的 DeltaMemStore,負責記錄此 DiskRowSet 後續的資料變更(更新、刪除)。DeltaMemStore 內部維護一個 B-樹索引,對映到每個 row_offset 對應的資料變更。DeltaMemStore 資料增長到一定程度後轉化成二進位制檔案儲存到磁碟,形成一個 DeltaFile,隨著 base data 對應資料的不斷變更,DeltaFile 逐漸增長。
4.5 最佳化讀寫效能
在具體的資料(列資料、變更記錄)上,KUDU 都做了 B- 樹索引,以提高隨機讀寫的效能。在 base data 中,KUDU 還針對主鍵做了好幾類索引(實際上由於 delta store 只記錄變更資料,base data 中對主鍵的索引即本 DiskRowSet 中全域性的主鍵索引):
- 主鍵範圍索引:記錄本 DiskRowSet 中主鍵的範圍,用於粗粒度過濾一些主鍵範圍
- 布隆過濾器:透過主鍵的布隆過濾器來實現不存在資料的過濾
- 主鍵索引:要精確定位一個主鍵是否存在,以及具體在 DiskRowSet 中的位置(即:row_offset),透過以 B-樹為資料結構的主鍵索引來快速查詢。
隨著時間的推移,KUDU 中的小檔案會越來越多,主要包括各個 DiskRowSet 中的 base data,還有每個 base data 對應的若干份 DeltaFile。小檔案的增多會影響 KUDU 的效能,特別是 DeltaFile 中還有很多重複的資料。為了提高效能,KUDU 會進行定期 compaction,compaction 主要包括兩部分:
- DeltaFile compaction:過多的 DeltaFile 影響讀效能,定期將 DeltaFile 合併回 base data 可以提升效能。在通常情況下,會發生頻繁變更的欄位是集中在少數幾個欄位中的,而 KUDU 是列式儲存的,因此 KUDU 還在 DeltaFile compaction 時做了最佳化,檔案合併時只合並部分變更列到 base data 中對應的列。
- DiskRowSet compaction:除了 DeltaFile,定期將 DiskRowSet 合併也能提升效能,一個原因是合併時我們可以將被刪除的資料徹底的刪除,而且可以減少同樣 key 範圍內資料的檔案數,提升索引的效率。