追求卓越
打造極致文化與產(chǎn)品研發(fā)結合的最佳實踐
神策已啟動「卓越產(chǎn)品計劃」
產(chǎn)品功能、性能、穩(wěn)定性不斷邁向新臺階
在上一篇文章《卓越產(chǎn)品計劃丨神策分析之五重性能優(yōu)化》中,我們了解了神策分析性能優(yōu)化的的五重實踐,主要包括批量導入性能優(yōu)化、智能聚合表優(yōu)化、數(shù)據(jù)重組織查詢優(yōu)化、查詢?nèi)ブ貎?yōu)化、頁面首次首屏加載時間優(yōu)化。今天我們將重點講述數(shù)據(jù)重組織查詢優(yōu)化。
在過去 7 年多的發(fā)展過程中,我們基于 Apache Impala 做了大量的二次開發(fā),極大地優(yōu)化了 Apache Impala 的查詢性能。經(jīng)過不斷地探索與實踐,我們開發(fā)的一些基于數(shù)據(jù)組織的性能優(yōu)化效果顯著,其中 shuffle merge 是其中重要的一項優(yōu)化。
如下圖所示,神策分析中,Event 數(shù)據(jù)按天和 EventBucket 做分區(qū),即同一天的數(shù)據(jù)置于同一一級分區(qū)內(nèi),同一天的數(shù)據(jù)再按 EventBucket 分區(qū),這樣可以保證同一事件的數(shù)據(jù)在同一分區(qū)內(nèi),同時將分區(qū)內(nèi)的文件按{User_id, Time}排序。
神策分析的 10+ 分析模型,大多基于按時間排序的用戶事件序列進行分析,對該功能的性能優(yōu)化,可以有效提升查詢性能。
一、相關名詞解讀
在進行數(shù)據(jù)重組織查詢優(yōu)化的過程中,經(jīng)常會提及不少名詞,你都了解嗎?為了幫助各位閱讀,我們提取了常見的 5 個名詞并做了詳細解釋。
1、數(shù)據(jù)模型
指神策分析中的事件模型。簡單來說,事件模型包括事件(Event)和用戶(User)兩個核心實體,同時配合物品(Item)實體可以做各種維度分析。
2、數(shù)據(jù)組織
指按照一定的方式和規(guī)則來存儲模型數(shù)據(jù),比如數(shù)據(jù)如何做分區(qū)、如何建索引等。
3、數(shù)據(jù)重組織
對應數(shù)據(jù)組織,針對不合理的數(shù)據(jù)存儲,重新組織模型數(shù)據(jù),以提升數(shù)據(jù)的使用效率。
4、EventBucket
每個事件都有唯一的 Event_id, EventBucket 是對 Event_id 的分桶,在數(shù)據(jù)組織上,會將 Event 均勻地存放在 EventBucket 中,當前 EventBucket 默認為 10。
5、SamplingGroup
是對 User_id 的虛擬分桶。在數(shù)據(jù)重組織中, 會盡可能地將同一 User_id 的數(shù)據(jù)存放在同一 SamplingGroup 下,當前 SamplingGroup 默認為 64。
二、shuffle merge 原理
通常,exchange 算子后會接一個 sort 算子將數(shù)據(jù)按{User_id, Time}來排序,此時的排序為全排序,未利用底層數(shù)據(jù)的有序性,復雜度比較高,代價較大。shuffle merge 則可以充分利用底層數(shù)據(jù)的有序性,將全排序轉化為歸并排序,跳過耗時的 sort 算子,降低排序的時間復雜度,加速計算過程。
其優(yōu)化前后的查詢計劃分別如下:
最終,基于此優(yōu)化,我們可以實現(xiàn)如下邏輯的查詢:
三、神策的數(shù)據(jù)重組織查詢優(yōu)化實踐
在 shuffle merge 的實際應用中,對于數(shù)據(jù)量較大的客戶,其分區(qū)內(nèi)文件數(shù)量較多,再加上客戶數(shù)據(jù)或存在延遲上報的情況,會形成比較多的小文件,進一步增加單分區(qū)內(nèi)的文件數(shù)量,造成了以下問題:
● 同一分區(qū)內(nèi)同一 User_id 的數(shù)據(jù)分散在不同的文件里,在 shuffle 時需要一次打開多個文件,每個文件僅讀一部分,帶來大量的隨機 IO。因為同一 User_id 的數(shù)據(jù)分散在不同的文件里,在多讀取不同的 User_id 序列時,會存在同一文件多次讀取的情況,IO 會成倍放大
● 同一 User_id 的數(shù)據(jù)分散在不同的文件里,導致歸并排序時歸并路數(shù)過多,維護敗者樹的代價過高。單個文件讀取較慢則會阻塞整個查詢進程
為了減少上述問題帶來的影響,我們需要盡可能地將同一分區(qū)下同一 User_id 的數(shù)據(jù)存放于同一文件中,這樣可以明顯減少歸并路數(shù),進而降低隨機 IO,提升數(shù)據(jù)掃描性能。針對此,我們設計了虛擬分桶 SamplingGroup,它是 User_id 的 hash 值。在數(shù)據(jù)重組織具體應用過程中,將同一 SamplingGroup 的數(shù)據(jù)組織到同一文件中。重組織后的 Event 數(shù)據(jù)組織形式如下:
當數(shù)據(jù)量較大,且歸并路數(shù)較多時,遇到慢文件的概率大大提升,很容易拖慢整體的 shuffle merge 速度;另外,在數(shù)據(jù)規(guī)整后,shuffle merge 的歸并是按 SamplingGroup 串行執(zhí)行的,未能充分利用 SamplingGroup 以提升并行度。針對此,我們提出了 merge all 的方案——將歸并從 union 算子下移到 scan 階段,直接桶對桶(SamplingGroup to SamplingGroup)做歸并,如下圖所示:
該方案能夠直接在計算節(jié)點上,通過 hdfs api 對時間線上的同一 SamplingGroup 數(shù)據(jù)做歸并,大大節(jié)省了網(wǎng)絡間 shuffle 的數(shù)據(jù)量;更容易將謂詞及列裁剪下推到 scan 階段,以進一步減少數(shù)據(jù)掃描量;充分利用 hdfs api 的讀優(yōu)化功能,以提升 scan 效率;在計算節(jié)點較少或者內(nèi)存不充足的情況下,可主動控制歸并數(shù)量,按 SamplingGroup 分批歸并,以降低計算所需內(nèi)存。
另外,在和 profile 表做聯(lián)合 join 時,可以采用 sort merge bucket join,進一步提升 join 效率,在 profile 表較大和內(nèi)存資源有限的情況下發(fā)揮較大作用。
數(shù)據(jù)重組織查詢優(yōu)化后,神策數(shù)據(jù)幫助某客戶實現(xiàn)了 shuffle merge 場景下 1 倍左右的性能提升,開啟 merge all 后,其漏斗分析場景中的性能提升高達 40%~150%。
關注神策數(shù)據(jù)公眾號,了解更多產(chǎn)品技術解讀。
(免責聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準確性及可靠性,但不保證有關資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責。本網(wǎng)站對有關資料所引致的錯誤、不確或遺漏,概不負任何法律責任。
任何單位或個人認為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權或存在不實內(nèi)容時,應及時向本網(wǎng)站提出書面權利通知或不實情況說明,并提供身份證明、權屬證明及詳細侵權或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關文章源頭核實,溝通刪除相關內(nèi)容或斷開相關鏈接。 )