連續兩篇文章都聊了不一樣的存儲格式,這篇咱們繼續深刻來看看在存儲格式的演變之上有什麼新的"黑科技"。華爲公司在2016年開源了類parquet的列存格式:CarbonData,而且貢獻給了Apache社區。CarbonData僅僅用了不到一年的時間就成功畢業,成爲了Apache社區的頂級項目,CarbonData是首個由華人公司主導的Apache頂級項目,(來源自eBay的Kylin算是首個由華人主導的頂級開源項目)筆者這裏仍是要向華爲的小夥伴們致敬,可以完成這樣一個從0到1的突破。
本篇筆者嘗試從技術細節來梳理CarbonData與其「前輩」到底有何不一樣之處,咱們在實際應用與設計存儲格式時有什麼能夠借鑑汲取之處。程序員
首先咱們來看看CarbonData自己的定位,以下圖所示:
性能優化
對於OLAP查詢來講,存在多種不一樣類型的查詢,存儲結構的不一樣會影響到不一樣查詢的數據表現。因此CarbonData的定位是做爲一種通用的查詢存儲數據,經過Spark SQL來解決海量查詢的問題,而且可以與Hadoop生態圈進行無縫對接。CarbonData最初的應用是與Spark SQL和Spark DataFrame深度結合,後續由攜程團隊將CarbonData引入了Presto,滴滴團隊將CarbonData引入Hive。分佈式
其實不管是多維的OLAP查詢,仍是完整的掃描查詢,仍是部分範圍查詢。CarbonData的前輩ORCFile與Parquet均可以一樣完成任務,那麼做爲新人,CarbonData有什麼過人之處呢?oop
下圖是華爲提供進行實測的數據,在絕大多數的測試場景之中CarbonData的性能都略優於Parquet。
性能
固然快速的查詢是須要付出代價的,查詢的快速所犧牲的是壓縮率的減少與入庫時間的延長。學習
那咱們接下來就是要詳盡討論CarbonData的性能表現與底層設計之間的邏輯關係。測試
下圖展現了CarbonData的數據存儲格式:
優化
File Header
文件頭的格式比較簡單,保存了存儲格式的版本和模式信息。(這部分一般是穩定不可變的內容)編碼
Blocklet
單Blocklet最大的容量閥值爲64M,也就是說單個HDFS的Block能夠容納多個Blocklet(視Block的大小而定)。這塊內容與ORCFile與Parquet的設計一脈相承,都是利用Pax的存儲模型來優化數據查詢時的性能表現。設計
File Footer
在文件尾部保存了存儲數據的索引和摘要,索引是CarbonData最爲核心的關鍵實現,正是因爲索引的存在,大大提升了CarbonData在不一樣查詢場景之下的性能表現。
CarbonData經過支持了二級索引,大大的提升了CarbonData數據查詢的性能表現。
由上圖所示CarbonData在HDFS Block級別與內部的Blocklet級別都分別創建起索引,這樣能夠大大減小非必要的任務啓動與非必要的磁盤IO操做。衆所周知,引入索引的的確確可以加快數據的查詢速率,可是天下沒有免費的午飯。我想CarbonData壓縮率縮減與數據導入時間的延長的緣由,想必讀者心中也有了答案。
咱們能夠看到在CarbonData的文件尾部,經過B+樹的方式來實現索引。因爲HDFS追加寫的特性,因此我想讀者應該也能明白爲什麼這些索引數據與統計數據須要存放在CarbonData的末尾。
上圖完整的展示了一次過濾查詢的流程,這個過程在二級索引的做用之下,規避了大量非必要的查詢交互,由此帶來的性能優化是十分明顯的。
相對於ORCFile與Parquet相對簡要的摘要索引,CarbonData在索引層面頗費心思。經過這樣的方式來超越前輩,固然這樣的選擇設計一樣也要付出額外的代價。
這是CarbonData之中頗具爭議的功能,在CarbonData以前的版本是默認添加的內容,目前在1.3版本之中是做爲可選項加入其中的。(筆者在華爲高斯部門工做的師兄也曾經和筆者吐槽過在生產環境之中,全局字典編碼的彷佛還存在一些'坑')因此看起來可以運用好字典編碼的確是個值得探討的問題,筆者在此也簡單聊一聊:
如上圖所示,全局字典編碼的方式很簡單,就是經過數字和字典來替換表格之中重複出現的數據。 這樣的好處很明顯:
大大減小了表格數據所須要存儲的數據量
某些須要進行group by的字段進行全局字典編碼,能夠大量減小計算時的shuffle的數據量。以達到性能提高的目的。
可是在將數據導入CarbonData的過程之中,對與重複率較低的列,一旦創建起全局字典,顯然會大大拖慢數據的導入速度,而且影響數據的壓縮程度。而若是對於數據重複率較高的數據,例如性別,年齡等高重複數據,經過創建全局字典可以大大提高CarbonData的壓縮程度,而且對數據導入的速率影響不大。
筆者建議:對於字典編碼的使用,仍是要根據具體也業務場景進行分析壓測,給出較爲合適的使用方式,盲目使用字典編碼反而會對性能帶來負優化。
到此爲止,筆者也大體聊完了對CarbonData存儲結構的理解以及筆者在簡單實踐之中所引起的思考。 做爲華人圈子之中首個由華人公司主導的Apache的頂級項目,筆者也會繼續對CarbonData進行關注與學習,也但願未來華人程序員可以在開源圈之中繼續擴大影響力。