MaxCompute索引優化實踐
摘要:2017雲棲大會阿裏雲大數據計算服務(MaxCompute)專場,阿裏雲高級專家戴謝寧帶來MaxCompute的索引與優化實踐分享。本文主要maxcompute數據模型開始談起,接著分享了哈希分片和區域分片,著重分析了索引優化和join優化,並且列出了應用實例,最好作出了簡要總結。
以下是精彩內容整理:
MaxCompute 除了是計算引擎之外,它也是個存儲引擎,阿裏巴巴99%數據都在這個平台上。那麼,怎麼去優化存儲效率,從而提高計算效率是我們一直努力的目標。
MaxCompute的數據模型
目前MaxCompute的數據模型包括:項目,表,分區。在分區下,分區下沒有定義數據組織方式,數據無序存放。
那麼,在分區下能否通過定義數據分片、排序和索引提高效率?答案是肯定的。
在MaxCompute2.0中,我們提供了兩種切片方式,哈希分片和區域分片。
哈希分片 – Hash Clustering
哈希分片是指用戶在創建table時,可以指定幾個column作鍵值的鏈,MaxCompute可以按照這幾個column做hash function,將hash value相同的record記錄放到同一個分片中去,不同的顏色代表不同的record出來相同的hash值。同時,我們通過語法定義每一個切片數據是不是要有序存放,如果指定sorted by 子句,就會要求數據排序存放。這樣就會呈現出兩個效果,一是在每個file裏建立index,一是在分片以上還有top level index,上層索引信息規定了表有多少個分片、哈希方式是什麼、依據哪幾個列,這些都可以幫助我們到後麵的查詢。
區域分片 – Range Clustering
區域分片比哈希分片更加靈活高級,它的基本思想是指定區域分片的column後,語法為range clustered by ,MaxCompute根據column值域分布作全排序,根據值域分布按照合理方式進行切分,切分的原則包括分片大小、分片差異合理化,減少並行處理時遇到的種種數據問題。圖中9個record,我們對其進行全排序,把它切到四個片上,同樣也有個sorted by 的子句指定每個分片數據如何存放,有序存放會建立兩個級別的索引,一是文件級別索引,一是上層索引,上層索引維護了每個分片,每個分片對應某個range和區間。
基於索引的查詢優化
那麼如何進行優化呢?例如id<3,如果id列剛好是我做的數據分片和排序索引,謂詞會下推到存儲層,利用謂詞信息去做過濾信息,首先會到上層索引做一級索引,一級索引擁有所有分片的信息,id<3查詢條件很快可以確定把bucket2和bucket3兩個分片去掉;同時,我們還可以將謂詞推到文件下麵去,bucket1中有小於3和等於3的,還可以在文件內部進一步過濾,將數據量再減少,如果沒有做數據分片index之前,對於id<3 懂得查詢,需要去掃整個表,把所有數據全部讀一遍,現在不需要讀整個表,直接可以通過index把一大堆數直接去掉,效率也是非常可觀的。
圖為TPC-H Q6查詢,TPC-H是數據庫和大數據領域的標準測試集,我們在100GB的測試數據集上拿到了數據,左邊時間是使用index的時間,右邊是沒有使用index的時間,可以看到提升了10倍左右,無論是query的執行時間,還是CPU的使用時間和IO的使用時間,都會大大減少,通過index減少了很多IO操作,減少了很多數據裝載。
Join優化
除了在filter上應用index,還有對join的優化。Sort merge join是指有兩個數據源在一個機器上將數據join完,一般是將數據源用哈希方式分到N個分片中去,保證join key相同的record會落到相同的分片上,每個分片內部對兩個數據源進行排序,排序後再做merge join,就可以把key值相同的找出來,這個過程很複雜,也非常耗時,需要將數據進行哈希運算,再把數據傳到另外一個機器上去,你需要先寫在一個機器上,另外一個機器再從機器上讀取,需要二次磁盤IO,這個過程叫做data shuffle。
如圖,兩個table scan從數據磁盤加載進來,streaming read和streaming write來做data shuffle,如果數據已經做完分片和排序,並且把組織結構都存放在磁盤上麵,在做join時就不需要再進行shuffle和排序過程,這就是join優化。演化如右圖,如果M1和M2已經做了哈希分片排序,可以直接做如圖執行計劃。
TPC-H Q4
沒有哈希分片之前,執行計劃如右邊圖中所示,共有7個stage,多個join和shuffle過程,如果把表改成哈希分片表,並且在join key上做哈希分片,隻需要3個stage即可完成,簡化了執行計劃,基本上都提升了2倍效率。
應用實例
淘寶交易記錄查詢
淘寶交易量巨大,百億級甚至千億級的數據,我們內部可能需要拿一個user的id去做查找,比如查找某個人過去一周在淘寶購物情況,這是一個大海撈針的操作。原有係統在改造以前執行如圖,共有一千多個worker去掃描表,400多億條記錄,最後找到26條記錄,共用1分48秒。
以用戶id為主鍵,對表進行數據哈希切片排序,同樣查詢隻需要4個mapper,掃描一萬條記錄6秒鍾即可。
淘係交易表增量更新
淘寶中有核心交易表,這是集團內部很多BU都會引用的數據來源,對它的正確性要求非常高。我們經常會有增量更新的操作,按周期性以增量表數據插入或者更新到原來表中,全量表數據量巨大,記錄數在百億、千億,增量表可能是十分之一甚至百分之一,每次更新需要對原表和增量表進行shuffle,非常耗時。圖中M1和M2在做增量表的shuffle和全量表的shuffle,增量表需要1分49秒,全量表共用2000個worker做了33分鍾。
全量表哈希分片後排序存儲,更新時隻需要按增量表shuffle,避免了對全量表的多次shuffle,整個join執行時間從60分鍾降低到22分鍾。
總結
我們通過對數據進行分片和排序,並建立索引,MaxCompute可以更好的理解數據。
查詢條件謂詞下推,減少了表掃描的IO量,以及運行時過濾操作的時間。
利用數據分片和排序特性,直接避免了多次對數據Shuffle的操作,簡化了執行計劃,節約資源,節省時間。
最後更新:2017-10-25 12:33:37