1、kudu介紹
kudu 定位是 「Fast Analytics on Fast Data」,是一個既支持隨機讀寫、又支持 OLAP 分析的大數據存儲引擎。
原數據存儲於HDFS或HBase都有優缺點:
-
直接存放於HDFS中,適合離線分析,卻不利於記錄級別的隨機讀寫。
-
2、kudu原理架構
采用了Master-Slave形式的中心節點架構,管理節點被稱作 Master Server,數據節點被稱作Tablet Server(可對比理解HBase中的RegionServer角色)。
-
Mater Server:負責集群(TS)管理、元數據管理等功能
-
Tablet Server:負責數據存儲,並提供數據讀寫服務
一個表的數據,被分割成1個或多個Tablet,Tablet被部署在Tablet Server來提供數據讀寫服務。 Kudu Master在Kudu集群中,發揮如下的一些作用:
-
用來存放一些表的Schema信息,且負責處理建表等請求。
-
跟蹤管理集群中的所有的Tablet Server,並且在Tablet Server異常之后協調數據的重部署。
-
存放Tablet到Tablet Server的部署信息。
tablets 在 Kudu 里面被切分成更小的單元 RowSets:
MemRowSets可以對比理解成HBase中的MemStore, 而DiskRowSets可理解成HBase中的HFile。MemRowSets中的數據按照行試圖進行存儲,數據結構為B-Tree。MemRowSets中的數據被Flush到磁盤之后,形成DiskRowSets。
DiskRowSet中的數據按照Column進行組織,與Parquet類似。這是Kudu可支持一些分析性查詢的基礎。
一個DiskRowSet包含兩部分數據:基礎數據(Base Data),以及變更數據(Delta Stores)。更新/刪除操作所生成的數據記錄,被保存在變更數據部分。
Delta數據部分包含REDO與UNDO兩部分:
-
REDO Delta Files包含了Base Data自上一次被Flush/Compaction之后的變更值。REDO Delta Files按照Timestamp順序排列。
-
UNDO Delta Files包含了Base Data自上一次Flush/Compaction之前的變更值。這樣才可以保障基於一個舊Timestamp的查詢能夠看到一個一致性視圖。UNDO按照Timestamp倒序排列。
kudu client 與 服務端交互,先從 Master Server 獲取元數據信息,然后去 Tablet Server 讀寫數據,如下圖:
3、讀寫流程
3.1、寫數據
當 Client 請求寫數據時,先根據主鍵從 Mater Server 中獲取要訪問的目標 Tablets,然后到依次對應的 Tablet 獲取數據。因為 KUDU 表存在主鍵約束,所以需要進行主鍵是否已經存在的判斷,這里就涉及到之前說的索引結構對讀寫的優化了。一個 Tablet 中存在很多個 RowSets,為了提升性能,我們要盡可能地減少要掃描的 RowSets 數量。首先,我們先通過每個 RowSet 中記錄的主鍵的(最大最小)范圍,過濾掉一批不存在目標主鍵的 RowSets,然后在根據 RowSet 中的布隆過濾器,過濾掉確定不存在目標主鍵的 RowSets,最后再通過 RowSets 中的 B-樹索引,精確定位目標主鍵是否存在。如果主鍵已經存在,則報錯(主鍵重復),否則就進行寫數據(寫 MemRowSet)。
3.2、更新數據
定位到具體位置后,然后將變更寫到對應的 delta store 中。
3.3、讀數據
先根據要掃描數據的主鍵范圍,定位到目標的 Tablets,然后讀取 Tablets 中的 RowSets。在讀取每個 RowSet 時,先根據主鍵過濾要 scan 范圍,然后加載范圍內的 base data,再找到對應的 delta stores,應用所有變更,最后 union 上 MenRowSet 中的內容,返回數據給 Client。
4、存儲設計
列式存儲
優勢**
-
查詢少量列時 IO 少,速度快
-
數據壓縮比高
-
便於查詢引擎性能優化:延遲物化、直接操作壓縮數據、向量化執行
劣勢
-
查詢列太多時性能下降(KUDU 建議列數不超過 300 )
-
不適合 OLTP 場景
分區
與大多數大數據存儲引擎類似,KUDU 對表進行橫向分區,KUDU 表會被橫向切分存儲在多個 tablets 中。不過相比與其他存儲引擎,KUDU 提供了更加豐富靈活的數據分區策略。
一般數據分區策略主要有兩種,一種是 Range Partitioning,按照字段值范圍進行分區,HBase 就采用了這種方式,如下圖:

Range Partitioning 的優勢是在數據進行批量讀的時候,可以把大部分的讀變成同一個 tablet 中的順序讀,能夠提升數據讀取的吞吐量。並且按照范圍進行分區,我們可以很方便的進行分區擴展。其劣勢是同一個范圍內的數據寫入都會落在單個 tablet 上,寫的壓力大,速度慢。
另一種分區策略是 Hash Partitioning,按照字段的 Hash 值進行分區,Cassandra 采用了這個方式,見下圖:

與 Range Partitioning 相反,由於是 Hash 分區,數據的寫入會被均勻的分散到各個 tablet 中,寫入速度快。但是對於順序讀的場景這一策略就不太適用了,因為數據分散,一次順序讀需要將各個 tablet 中的數據分別讀取並組合,吞吐量低。並且 Hash 分區無法應對分區擴展的情況。
各種分區策略的優劣對比見下圖:

既然各分區策略各有優劣,能否將不同分區策略進行組合,取長補短呢?這也是 KUDU 的思路,KUDU 支持用戶對一個表指定一個范圍分區規則和多個 Hash 分區規則,如下圖:

參考引用:
http://www.nosqlnotes.com/technotes/kudu-design/
https://zhuanlan.zhihu.com/p/26798353