百倍壓縮、秒級查詢!觀遠智能拉鍊表這樣高效處理海量數據

<!-- /\* Font Definitions \*/ @font-face {font-family:宋體; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 680460288 22 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:等線; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:DengXian; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:-1610612033 953122042 22 0 262159 0;} @font-face {font-family:"Microsoft YaHei UI"; panose-1:2 11 5 3 2 2 4 2 2 4; mso-font-charset:134; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-2147483001 718224464 22 0 262175 0;} @font-face {font-family:"\\@Microsoft YaHei UI"; mso-font-charset:134; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-2147483001 718224464 22 0 262175 0;} @font-face {font-family:"\\@宋體"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 680460288 22 0 262145 0;} @font-face {font-family:"\\@等線"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:-1610612033 953122042 22 0 262159 0;} /\* Style Definitions \*/ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:等線; mso-ascii-font-family:等線; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:等線; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:等線; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-family:等線; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /\* Page Definitions \*/ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page WordSection1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.WordSection1 {page:WordSection1;} /\* List Definitions \*/ @list l0 {mso-list-id:1756394649; mso-list-template-ids:-1063857600;} @list l0:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level2 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:72.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level3 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:108.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level4 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:144.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level5 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:180.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level6 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:216.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level7 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:252.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level8 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:288.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level9 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:324.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

作更有溫度的智能數據分析產品算法

觀遠智能數據分析平臺不只要在分析結果上爲企業打造智能決策大腦,更要在分析過程當中,經過一系列黑科技產品幫助企業擺脫數據存儲、採集、清洗、分析到可視化過程當中高成本、高代碼、低效率的困境,解鎖更多貼心的數據分析新姿式。數據庫

1.jpg

隨着互聯網+大數據時代的發展,海量數據在爲企業帶來價值的同時也爲數據存儲、清洗、查詢的工做帶來了不少困擾。數組

「歷史拉鍊表」功能強大,但一樣要求複雜的操做流程和高人天投入ide

面對動輒幾十億行的庫存數據,不少企業都會面對「留之累贅棄之擔心」的尷尬。最多見的解決辦法就是把每一天的全量快照數據都存下來,提供日期主鍵,而後開放給用戶去查詢。但這樣實際上會保存不少不變的信息,對存儲是極大的浪費;再者,設計不當還很是影響查詢效率,拖垮數據庫。函數

舉個例子性能

一家連鎖藥店企業,門店數3000,SKU數1000,若是存庫存快照數據,天天就是300萬,一年就是10個億。若是要求可以查詢5年的歷史數據,那麼就須要保存近50億的歷史快照數據。學習

面對這類問題,「歷史拉鍊表」被公認爲是處理海量歷史數據壓縮存儲與查詢的最佳手段。既能知足反應數據的歷史狀態,又能夠最大程度的節省存儲空間,提升查詢效率。大數據

可是,通常在關係型數據庫上構建和維護拉鍊表,須要包含拉鍊初始化、開鏈、封鏈、增量更新等多個複雜的操做步驟,每一個步驟都須要用戶對拉鍊表的操做思路很是清楚,且對SQL使用很是熟悉。所以通常狀況下若是不是經驗豐富的數倉工程師是很難掌握這套方法的,更不用說在一個BI分析平臺內作拉鍊表的設計。ui

有沒有既能節省存儲空間、提升查詢效率,又能下降學習門檻,提高用戶體驗的方法?本期技術乾貨將爲你們揭曉如何利用觀遠Smart ETL平臺製做智能歷史拉鍊表,半小時實現百倍壓縮,秒級響應。spa

基於觀遠Smart ETL平臺30分鐘製做智能歷史拉鍊表

區別於複雜的拉鍊表製做過程,觀遠數據分析平臺依託於Spark計算引擎,完全簡化了歷史拉鍊表的構建和維護的流程,總結和封裝出一套用於構建與查詢歷史拉鍊表自定義函數(UDF),將本來須要高階數據分析師經過複雜設計完成的工做,簡化成普通數據分析員經過簡單幾個函數也能構建拉鍊表,並能支持高效查詢。

經過觀遠Smart ETL平臺製做歷史拉鍊表,不管在性能表現仍是拓展學習層面都具備獨特的優點:

· 性能表現:根據客戶庫存快照數據查詢爲例,12億行數據的庫存快照表精處理後生成的數據集爲800萬行。基於該數據集進行指定倉庫、指定日期的庫存快照數據查詢,響應時間基本在2~3秒;

· 拓展學習:實際上,觀遠數據分析平臺針對時序相關的大數據量問題提供了一系列內置的UDF來解決一些常見的指標計算問題,能夠作到快速、增量構建,同時又能夠進行快速查詢。這些函數能夠用來作庫存快照查詢,銷售額的WTD、MTD、YTD計算等各類與時間軸相關的大數據量查詢與跨行計算問題。具體提供的函數列表以下:

2.jpg

如下爲利用觀遠Smart ETL平臺製做歷史拉鍊表的實操介紹:

1. 庫存拉鍊表構建

首先,將一份歷史庫存快照表(包含日期、商品基本信息、以及庫存金額的基本數據)導入到觀遠數據平臺中,去構建一個Smart ETL處理這份數據。

3.jpg

接着,咱們使用一個分組聚合節點,並添加一個聚合字段 - 「庫存拉鍊」,改字段的表達式爲:

 date_range_build(collect_list(`date`), collect_list(`庫存金額`)),而後把商品信息字段拖入維度區域,庫存拉鍊字段拖入數值區域,進行分組聚合計算。

4.jpg

固然若是你更習慣用SQL來處理數據,也可使用「SQL輸入」節點來處理該過程。SQL表達式爲:

5.jpg

這樣,咱們就能夠獲得一個帶庫存拉鍊字段的輸出數據集。預覽一下,就能夠看到該字段實際上是一個k-v鍵值對,其中k是一個排序的日期數組,v是相應的庫存金額數組。

6.jpg

到這一步,咱們其實已經對庫存快照數據進行了大幅的壓縮。以觀遠數據的一個客戶庫存快照數據壓縮爲例,1年6億行的數據經這一步壓縮後,只剩下500萬行;2年12億行的數據經壓縮後,只剩800萬行。

進一步咱們知道,對於庫存數據來講,有些商品可能很長時間內庫存都不會發生變化,也就是說上面的庫存金額數組裏可能會存在大量連續重複的數。這個時候,咱們就可使用date_range_remove_adjacent_same_values函數對庫存快照鍵值再度進行壓縮,構建庫存拉鍊字段。

7.jpg

拉鍊表構建完成後,咱們把結果表輸出爲數據集,這樣就能夠開始構建卡片進行快照數據查詢了。

8.png

對於以上結構的庫存拉鍊字段,咱們提供了相應的函數進行快照查詢。您能夠經過如下方式進行快照數據的參數化查詢:

date_range_lookup([庫存拉鍊], to_date([DYNAMIC_PARAMS.時間參數])

2. 庫存拉鍊表增量更新

以上是基於歷史庫存快照數據構建庫存拉鍊表。那麼當有新的快照數據進來,該如何Merge到現有的庫存拉鍊表裏面去呢?不慌,咱們替你都想好了!咱們提供了date_range_merge函數,能夠幫你將多個時間區段的拉鍊表進行合併。好比:date_range_merge([庫存拉鍊_2018],[庫存拉鍊_2019])。

觀遠數據離線計算引擎基於Spark構建,咱們針對零售行業業務場景,研究和實踐了大量算法黑科技產品,幫助客戶有效解決各種大數據量或複雜計算問題,若是你想解鎖更多數據分析新姿式,歡迎與咱們聯繫。

wei.jpg

下 期 預 告

下一篇,將爲你們講解《如何藉助Spark高階函數,依託Smart ETL來實現複雜邏輯的指標計算》,敬請期待!

相關文章
相關標籤/搜索