阿里CCO:基於 Hologres 的億級明細 BI 探索分析實踐

CCO是Chief Customer Officer的縮寫,也是阿里巴巴集團客戶體驗事業部的簡稱。隨着業務的多元化發展以及行業競爭的深入,用戶體驗問題越來越受到關注。CCO體驗業務運營小二日常會大量投入在體驗洞察分析中,旨在通過用戶的聲音數據結合交易、物流、退款等業務數據,洞察發現消費者/商家體驗鏈路上的卡點問題並推進優化,帶給消費者和商家更好服務體驗。

以今年3月爲例,通過統計日誌數據發現,共有80+業務同學提交了22000+個Query,都是圍繞着用戶心聲和業務數據的多維度交叉分析,如果按照每個Query小二平均投入10分鐘進行編寫、執行、檢查等操作來計算的話,共計投入458工作日,也就意味着這80+業務同學人均每個月至少有1周的時間全部投入在數據處理、運行上。業務側大量的洞察分析訴求也使得體驗洞察的數字化和智能化能力建設勢在必行,我們需要有能支持到業務複雜場景Ad-hoc查詢的數據能力和產品能力。

通過對數據產品的不斷迭代,我們採用Hologres+FBI支撐CCO體驗小二所有數據探索需求,月均50億+明細數據聚合查詢秒級返回,支持100+業務小二大促、日常的體驗運營洞察分析,助力業務小二單次洞察分析提效10倍以上,解放業務同學的生產力。在文本中,我們也將會介紹CCO數據洞察產品基於Hologres在BI查詢場景的最佳實踐。

體驗洞察各階段方案演變

結合業務,我們梳理了當前CCO體驗洞察數據應用的幾個特點:

  • 數據覆蓋場景廣。覆蓋了從用戶瀏覽、下單、支付、發貨物流到售後退款等全鏈路的業務場景,數據涉及範圍廣。
  • 數據量較大。如交易類數據(億級/日)、退款類數據(千萬級/日)。
  • 實時時效以及多時間窗口對比訴求。如大促活動期間實時對用戶Top求助場景是否異常的判斷,涉及多種窗口(環比、同比、歷史同時段、活動期同時段等)對比,來進行影響面評估和預警佈防。
  • 數據監控週期長。如大促期間的售後情況洞察,因爲售後期較長,往往會鎖定大促週期的訂單,觀察後續N天的退款、糾紛數據變化。數據需刷新的週期長。
  • 大量的快照類特徵訴求。如分析用戶諮詢時刻的交易狀態、物流狀態等特徵分佈,用以分析用戶求助的真實訴求。

因此在整體數據方案落地的過程中,如何快速響應業務不斷變化的需求,同時考慮業務上的數據特點,選擇相對穩定且高可用的方案是我們需要面對的問題。這裏主要經歷了三個階段。

階段一:預計算聚合Cube(MOLAP)+ADB加速查詢

這個階段還未支持實時的洞察能力,採用的方式是比較常規的預計算聚合Cube結果集,即在MaxCompute側將所需要的交叉維度指標預計算好,形成一個ADS層的聚合指標結果寬表,通過外表或者DataX工具將聚合結果寫入到OLAP引擎加速查詢。此階段CCO較爲主流的OLAP引擎選型主要是ADB、MySQL等。這種方案在應對較少且相對穩定的維度和指標組合時較爲適用,因爲結果已經預計算好,只需要針對結果表進行簡單聚合計算,ADB也提供了穩定的查詢加速能力。以下爲整體數據鏈路結構的簡單示意圖:

但是隨着業務場景的更加複雜化,存在的問題也極爲明顯:

  • 靈活度差,擴展成本高。當業務上要增加新維度或指標時,需要在MaxCompute應用層多層添加邏輯、修改表結構並且需要回刷數據,數據的擴展成本十分高。
  • 數據量易爆炸。因爲預計算的結果集最細粒度是所有維度的枚舉值交叉,只要某幾個維度枚舉值比較多的話,交叉後的數據量就會存在大幅膨脹的可能,甚至膨脹到交叉後遠大於明細數據量級的情況。
  • 行業回刷成本高。因爲維度特徵預計算好的原因,類似淘系行業調整等較爲常見的因素帶來的回刷無法避免。每一次行業調整,爲了保證行業的準確性,都會需要一次全量的回刷。
  • UV類去重指標無法精確計算。遇到UV等需要去重計算的指標,因爲預計算按照維度最細組合計算,再次聚合的時候不可避免會出現結果膨脹,無法精確的實現去重計算。
  • 數據迴流時間長。離線數據通過Shell腳本操作外表或者DataX同步任務方式迴流ADB,在數據量較大的時候同步時間長,並且在迴流高峯的時候,因爲槽位資源打滿,容易頻繁出現任務超時、出錯,甚至庫抖動等問題,維護成本較高。

階段二:實體ID輕度彙總事實表+維度表關聯查詢

這個階段實時化洞察已經在很多場景有較強的訴求,故需要同時結合實時鏈路來考慮方案。方案一不適合實時鏈路的建設,主要在於預計算的多維彙總寬表難以確定PK,一旦維度組合發生變化,PK需要重新定義,無法穩定的支持upsert/update操作。

所以在這個階段主要針對擴展性靈活性等問題重新設計了方案。主要的思路是不做維度的預計算,而是抽取洞察場景內事實表的實體對象ID,構建基於這些實體對象ID的輕度彙總DWS指標層,然後將DWS指標事實表和實體對象的DIM表直接寫入到OLAP引擎,在數據服務或者FBI數據集這一層直接join查詢。

以共享零售爲例,業務的本質是買家下單,貨從賣家流轉到買方。這裏的參與的對象有商品、商家、買家、騎手等,我們構建以商品ID+商家ID+買家ID+騎手ID的聯合主鍵,計算在這個主鍵下的各業務模塊的指標彙總事實表,然後利用OLAP引擎的強大的交互分析能力直接關聯事實表和維表做多維分析查詢。數據鏈路結構的簡單示意圖如下:

這種方案對比方案一解決了擴展性問題,提升了靈活度,維度的擴展只需要簡單調整維表即可,遇上行業的調整甚至無需做任何處理;同時PK穩定,也能支持到實時upsert。但也因爲數據展現端關聯查詢邏輯複雜,性能上對OLAP引擎要求較高。存在的問題可以總結爲以下幾點:

  • 大數據量下性能較差。數據應用端大量的join操作,尤其PK不相同無法走Local Join,在數據量較大的場景如淘系業務裏,性能難以支持。
  • UV類去重指標無法精確計算。本質上指標值依然是預計算,所以維度上再聚合時仍然會出現膨脹,不能精確計算去重值。
  • 部分特徵維度無法支持。業務的洞察訴求越來越精細全面,交易特徵、物流特徵等一些屬性以及快照類數據,在這個方案中難以支持,如訂單的預售的類型、是否直播訂單等。
  • 實時離線對比窗口難實現。實時指標有較強的多時段不同點位的窗口對比訴求,當遇到當天XX小時同環比歷史同時段這類需求時,當前方案難以實現,預計算各種時長打點的歷史數據也不現實。

階段三:基於Hologres明細寬表的即席查詢

爲了能支持到更加豐富的場景以及支持到實時離線聯邦查詢下靈活的窗口應用,我們方案的考慮方向轉向爲不再做指標的預計算,直接將明細數據寫入到OLAP引擎,在數據集/數據服務等服務層直接關聯DIM表即席查詢。同樣這對OLAP引擎的性能要求極高,CCO在去年實時架構升級之後,參見CCO x Hologres:實時數倉高可用架構再次升級,雙11大規模落地,藉助Hologres列存強大的OLAP能力及實時離線聯邦查詢能力使該方案落地變爲可能。

沒有最好的方案,只有在對應場景下做出取捨後相對適用的方案。在這個階段,我們犧牲了一定的查詢性能,選擇了對場景支持更豐富、實時離線聯邦查詢以及擴展靈活度更支持更佳的方案。當然在淘系這類較大數據量的業務場景中,我們也做了一定的優化和取捨。如在實際處理中,對於相對穩定的維度我們在MaxCompute/Flink處理寫入了明細,只對於行業類目等這類易調整且相對敏感的維度直接在數據集/數據服務關聯查詢。

三種方案對比:

場景 方案一:預聚合 方案二:輕度彙總 方案三:明細即席查詢
查詢性能(較大數據量) 較好 一般 一般
維度支持 支持豐富但數據量易爆炸 支持範圍固定 維度支持豐富
擴展性 較差 較好
去重計算 存在膨脹 存在膨脹 可精確計算
實時離線聯邦查詢窗口對比 不支持 不支持 靈活支持
行業回刷 需要回刷 無需回刷 無需回刷

Hologres+FBI一體化體驗洞察數據實踐

結合CCO體驗業務在數據洞察應用場景中數據量大、週期長、鏈路範圍廣、維度特徵多、實時離線對比窗口及快照特徵訴求多等需求特點,我們利用Hologres+FBI的各種特性不斷在實踐中設計優化整體的解決方案。從數據應用訴求來說,用戶可以接受一定時間的返回延遲,涉及較大數據量讀寫但同時查詢QPS較低,因而我們選擇犧牲一定的查詢RT,選擇使用基於Hologres明細的即席查詢的方案,整體流批兩條鏈路結構如下:

如上所示,整體的方案是相對典型的Lambda結構:

  • 在實時的鏈路中,我們讀取各主題的實時公共層Holo Binlog或者TT/MQ消息,利用Flink的流處理能力,通過查詢持久化存儲的Hologres維表補齊模型所需的字段,同時通過事件觸發的消息,查詢維表/HSF接口完成狀態快照的採集,構建成ADS/MDS明細寬表,寫入到Hologres分區表的當日實時分區。
  • 在離線的鏈路中,我們讀取各主題的公共層及維表,以及T日實時採集的快照信息,在T+1日構建離線的ADS/MDS明細寬表,通過MaxCompute外表方式Batch寫入到Hologres表的各歷史分區。爲了保證T日分區在T+1日的無感切換,我們會通過中間表rename的方式保證瞬間切換。
  • 在上游應用時通過搭建FBI數據集或數據服務,提供查詢Hologres明細表的即席查詢能力,支持多維交叉分析、大數據量下的去重計算、實時離線聯邦查詢等OLAP場景。

以下爲我們針對上面提到的前階段數據使用存在的各種問題,在實踐應用中的一些詳細的技術方案。

表設計、Table Group及索引選擇

  • 表設計

主要查詢場景是基於明細按時間範圍的OLAP查詢,數據規模單日分區超數十億,同時也需要按天更新回刷數據,所以Hologres表的屬性選擇上,是列存+業務主鍵PK+日期分區表。

  • Table Group設置

Table Group的設置一般根據使用場景、數據量大小、Join頻次綜合考慮。需要關聯的表放入同一個Table Group,通過Local Join減少數據的Shuffle,可極大提升查詢效率。

Shard Count根據數據量選擇合適的大小。Shard數過小數據的讀寫會存在瓶頸,而Shard數過大會導致日常固定的開銷以及查詢啓動的開銷增大造成浪費,大量的Shard數過大的表同時啓動查詢也容易給集羣的負載造成壓力,影響使用性能。目前體驗洞察實踐中,日增量億級的交易類明細結果Shard Count設置爲128,退款、諮詢求助等日增量千萬左右的明細表Shard Count設置爲32。

  • 索引設置

Hologres提供了Distribution Key、Clustering Key、Segment Key、Bitmap Columns等一系列的索引方式對錶進行優化,合理的使用各類索引,可以大幅提升使用性能。分佈建Distribution Key只能是PK或PK的部分字段,選擇基於PK來設定;對於商家、類目、行業等經常用在Filter和Range場景的字段,我們對應的設置了聚簇索引Clustering Key。而對於大量的二分類的維度特徵以及枚舉較少的字段,如是否直播訂單、商家分層等,我們對應設置了位圖索引Bitmap Columns等。

BEGIN;
CREATE TABLE "public"."ads_case_di" 
(
 "date_id" TEXT NOT NULL,
 "case_id" INT8 NOT NULL,
 "industry_name"  TEXT NOT NULL, 
 "seller_id"    INT8 NOT NULL,
 "seller_nick"  INT8 NOT NULL,
 "is_presale_order" TEXT,
 "is_live_order"    TEXT,
  XXX ,
 PRIMARY KEY ("date_id","case_id")
)
PARTITION BY LIST (date_id);
CALL SET_TABLE_PROPERTY('"public"."ads_case_di"', 'orientation', 'column');
CALL SET_TABLE_PROPERTY('"public"."ads_case_di"', 'segment_key', '"date_id"');
CALL SET_TABLE_PROPERTY('"public"."ads_case_di"', 'clustering_key', '"industry_name","seller_nick"');
CALL SET_TABLE_PROPERTY('"public"."ads_case_di"', 'bitmap_columns','"is_presale_order","is_live_order"');
CALL SET_TABLE_PROPERTY('"public"."ads_case_di"', 'dictionary_encoding_columns', '"industry_name","seller_nick","is_presale_order","is_live_order"');
CALL SET_TABLE_PROPERTY('"public"."ads_case_di"', 'time_to_live_in_seconds', '17280000');
COMMIT;

T+1分區覆蓋方案

在Flink作業定義Hologres Sink表時,需要配置`partitionRouter`和`createPartTable`參數來保證流作業數據Sink到實時的分區以及在路由不到分區時自動創建分區。

partitionRouter = 'true' 
createPartTable = 'true'

Holo的分區表是子母表結構,子表的當日分區作爲流作業的Sink表,T+1及之前的分區爲離線任務Batch寫入,在每天上午離線任務調度結束數據生成後覆蓋實時作業寫入的數據。而在T+1的離線數據寫入的時候,如何避免寫入時出現空分區或者查詢抖動,目前的方案是批寫入臨時子表然後rename並掛載到母表,可以瞬間完成T+1分區的數據切換,避免影響應用端使用體驗。以下以某個表示例。

BEGIN;
--線上表分區子表,如果不存在分區,就創建該分區
create table if not exists ads_tb_di_${bizdate} partition of ads_tb_di
  for values in ('${bizdate}');
--批數據寫入的中間表子表
create table if not exists ads_tb_di_batch_${bizdate} partition of ads_tb_di_batch
  for values in ('${bizdate}');
  
--解除線上表依賴關係
ALTER TABLE ads_tb_di DETACH PARTITION ads_tb_di_${bizdate};
--解除中間表依賴關係
ALTER TABLE ads_tb_di_batch DETACH PARTITION ads_tb_di_batch_${bizdate};
--名稱互換
ALTER TABLE ads_tb_di_${bizdate} RENAME to ads_tb_di_temp_${bizdate};
ALTER TABLE ads_tb_di_batch_${bizdate} RENAME to ads_tb_di_${bizdate};
--掛依賴
ALTER TABLE ads_tb_di ATTACH PARTITION ads_tb_di_${bizdate} FOR VALUES in ('${bizdate}');
--刪除臨時批表
drop TABLE ads_tb_di_temp_${bizdate};
commit;

FBI的Velocity語法和Fax函數裁剪SQL優化查詢

在BI的使用上,我們選擇FBI(阿里集團內部的一款BI分析產品)。目前FBI一個組件只支持一個數據集,爲了支持多維交叉分析應用,我們比較常見的方案是在數據集SQL中將所有可能用到的表拼接起來以備查詢。但實際的即席查詢場景中,用戶選擇的指標和維度可能只使用到了數據集中的部分表,如果全量查詢數據集,會造成浪費同時也會影響查詢性能。

結合FBI的 Velocity語法和Fax函數等特性配置動態查詢可以實現根據用戶的選擇動態路由裁剪,在數據集中如下使用Velocity語法添加判斷語句,在擴展指標中配置動態查詢的參數。這裏的${tableindexorder} == 'order' 代表交易明細表,數據量較大。

在實際的即席查詢場景中,如用戶只選擇了“糾紛介入率”這類指標和維度,和交易數據沒有關係,那麼最終執行的query將不會命中${tableindexorder} == 'order' 這個分支下的SQL,藉此實現對數據集SQL的裁剪,從而避免了每次查詢都全量執行整體數據集,可以根據實際使用場景按照“不使用則不查詢”的原則提升查詢效率。

實時離線聯邦查詢靈活窗口對比

大促場景下實時離線聯邦查詢的訴求十分常見,尤其當前時間點位同環比歷史同期時段點位這類對比需求,目前基於明細寬表的即席查詢架構更加靈活高效。首先離線部分無需再進行預計算,尤其如果對比點位比較細的話,如5分鐘、10分鐘這類窗口點位的對比,那離線需要預計算準備的數據較爲複雜,數據量也十分大。另外對於活動當天退款量、退款金額的累計趨勢這類很常規的訴求的實現,也不再需要通過Flink計算每個點位的數值,再通過窗口函數進行聚合。直接對關鍵時間字段增加打點字段,一個簡單的窗口函數即可完成累計趨勢圖的繪製。比如以下爲一個10分鐘窗口累計趨勢的示例:

select  date_id
        ,create_time_10min ---10分鐘向後打點
        ,rfd_cnt --當前時間窗口退款量
        ,rfd_amt --當前時間窗口退款金額
        ,sum(rfd_cnt) over(partition by date_id order by create_time_10min asc) as total_rfd_cnt --累計退款量
        ,sum(rfd_amt) over(partition by date_id order by create_time_10min asc) as total_rfd_amt---累計退款金額
from    (
            select  date_id
                    ,create_time_10min
                    ,count(*) rfd_cnt
                    ,sum(refund_real_amt) as rfd_amt
            from    ads_tb_di
            where   date_id in ('20201111','20211111') --大促當天和歷史同比
            group by date_id
                     ,create_time_10min
        ) t
;
--create_time_10min 這裏是對退款發起時間的打點字段,等同於replace(substr(FROM_UNIXTIME(UNIX_TIMESTAMP(case_create_time) - (UNIX_TIMESTAMP(case_create_time)% (10 * 60)) + (10 * 60)),12,5),':','')

Hologres動態分區回刷

由於採用了Hologres分區表的設計方式,當遇到需要同時回刷多個歷史分區的情況時,由於Hologres分區是子母表結構且不支持向母表Insert數據,這裏實現動態回刷多分區這類場景相對麻煩一些,Hologres當前不支持程序塊腳本,一般需要通過python/perl等腳本來進行對分區子表的循環操作。在這裏我們採用DataWorks的控制節點配置用以相對簡單的實現對Hologres分區表的動態回刷。

UV類去重計算優化

在體驗洞察的場景裏,有着大量的去重計算的訴求,比如諮詢萬筆訂單求助量等這類指標,諮詢場景中會話量的計算大多是基於非主鍵列的計算,在目前這種基於明細的查詢下,雖然避免了預計算結果集上聚合數據值膨脹的情況,但大量的distinct操作極其影響性能。因而應對去重計算,在不同場景下我們做了些不同的優化方案選擇。

  • 重要場景精確計算&長緩存週期

在首屏核心指標塊這類重要的呈現場景,比如萬單求助量、小蜜發起量等重要觀測指標的大數概覽統計,因爲指標的精確性要求,我們會使用distinct去重計算,這類指標數量不多,也因爲不涉及下鑽分析只是概覽統計,對於離線場景可以在FBI等展示端設置較長的緩存週期,查詢命中緩存的概率較高,可以一定程度的減少distinct帶來的性能影響。

  • 高頻維度場景使用RoaringBitmap高效去重

對於行業、類目等這一類重要並且高頻被使用到的的維度場景,並且這些維度對計算的精度也有着較高的訴求,爲了保證去重計數查詢的性能,我們利用Hologres的RoaringBitmap的數據壓縮和去重特性在較大數據量下進行計算。因爲RoaringBitmap本質上還是做了一層預聚合計算,如果維度太多粒度太細數據量也會膨脹的比較厲害,爲了保證優化的效果,這裏我們選取部分重要維度,結合前文提到的FBI Velocity語法判斷,當查詢的維度命中在RoaringBitmap基礎聚合的維度範圍時,通過RoaringBitmap快速返回結果。RoaringBitmap去重示例如下:

CREATE EXTENSION IF NOT EXISTS roaringbitmap; --創建roaringbitmap extention

-----創建映射表,用以映射去重字段serv_id到32位int類型
    BEGIN;
 CREATE TABLE public.serv_id_mapping (
     serv_id text NOT NULL,
     serv_id_int32 serial,
     PRIMARY KEY (serv_id) 
 );
CALL set_table_property('public.serv_id_mapping', 'clustering_key', 'serv_id');
CALL set_table_property('public.serv_id_mapping', 'distribution_key', 'serv_id');
CALL set_table_property('public.serv_id_mapping', 'orientation', 'column');
COMMIT;

-----創建基礎聚合結果表
BEGIN;
CREATE TABLE ads_tb_roaringbitmap_agg (
    date_id text NOT NULL,  --日期字段
    bu_type text,
    industry_name text,
    cate_level1_name text,
    cate_level2_name text, 
    cate_level3_name text, 
    uid32_bitmap roaringbitmap, -- 去重計算結果計算
  primary key(bu_type, industry_name,cate_level1_name,cate_level2_name, cate_level3_name, date_id)--查詢維度和時間作爲主鍵,防止重複插入數據
);
CALL set_table_property('public.ads_tb_roaringbitmap_agg', 'orientation', 'column');
CALL set_table_property('public.ads_tb_roaringbitmap_agg', 'clustering_key', 'date_id');
CALL set_table_property('public.ads_tb_roaringbitmap_agg', 'event_time_column', 'date_id');
CALL set_table_property('public.ads_tb_roaringbitmap_agg', 'distribution_key', 'bu_type,industry_name,cate_level1_name,cate_level2_name,cate_level3_name');
end;

--------將映射表裏沒有的serv_id寫入進去
WITH
     serv_ids AS ( SELECT serv_id  FROM ads_xxx_crm_serv_total_chl_di WHERE date_id = '${bizdate}' GROUP BY serv_id )
    ,new_serv_ids AS ( SELECT a.serv_id  FROM serv_ids a LEFT JOIN serv_id_mapping b ON (a.serv_id = b.serv_id) WHERE b.serv_id IS NULL )
INSERT INTO serv_id_mapping SELECT  serv_id
FROM    new_serv_ids
;

------按照聚合條件聚合後插入roaringbitmap聚合結果表
WITH
    aggregation_src AS( SELECT date_id,bu_type, industry_name,cate_level1_name,cate_level2_name, cate_level3_name, serv_id_int32 FROM ads_xxx_crm_serv_total_chl_di a INNER JOIN serv_id_mapping b ON a.serv_id = b.serv_id WHERE a.date_id = '${bizdate}' )
INSERT INTO ads_tb_roaringbitmap_agg 
SELECT   date_id
        ,bu_type
        , industry_name
        ,cate_level1_name
        ,cate_level2_name
        ,cate_level3_name
        ,RB_BUILD_AGG(serv_id_int32)
FROM    aggregation_src
where cate_level3_name is not null 
and   bu_type is not null 
GROUP BY date_id 
        ,bu_type
        , industry_name
        ,cate_level1_name
        ,cate_level2_name
        ,cate_level3_name
;

-------執行查詢,RB_CARDINALITY 和 RB_OR_AGG 聚合計算
SELECT  bu_type
        , industry_name
        ,cate_level1_name
        ,cate_level2_name
        ,cate_level3_name
        ,RB_CARDINALITY(RB_OR_AGG(serv_id32_bitmap)) AS serv_cnt ---去重計算結果字段
FROM    ads_tb_roaringbitmap_agg
WHERE   date_id = '${bizdate}'
GROUP BY bu_type
        , industry_name
        ,cate_level1_name
        ,cate_level2_name
        ,cate_level3_name;
  • 多維交叉分析使用近似計算

而對於大多數維度場景,對去重並不是要求100%精確,使用Hologres自身的APPROX_COUNT_DISTINCT近似計算,去重精度誤差可達1%以內,在可接受範圍內且不會大幅影響查詢性能。同時可如下通過調整精度參數來控制計算的精確度,但也會相應的增加計算開銷,實測默認參數值17就可以達到較好的去重精度。

set hg_experimental_approx_count_distinct_precision = 20;

同時Hologres 1.3版本也支持了UNIQ函數,跟count distinct是一樣的語義,但是計算效率更高,更節省內存,後續我們將會使用。

快照採集及持久化離線存儲

前文提到了CCO側體驗洞察分析存在大量的快照類特徵訴求,比如用戶諮詢時刻的貨物狀態、物流節點等,這類快照對分析用戶求助、退款時候的真實的境況和訴求及其重要。而這類快照在各類系統中不太可能都有業務埋點,因此需要數據側去加工得到對應的數據。這類快照數據如果通過批任務處理存在的主要問題是無法精準的獲取快照狀態,比如諮詢時的物流節點,通過離線ETL處理需要比對諮詢時間和物流各節點的時間卡先後順序得出當時的節點狀態,對節點的枚舉是否全面要求極高,並且處理複雜程度也較高。

因此,通過實時的消息結合實時更新的持久化存儲的維表或線上接口來生成快照類數據是較爲合適的方案,以諮詢時訂單狀態的實現爲例,我們接入諮詢創建的TT/MQ,發生諮詢之後去查詢對應訂單維表或者TC接口,返回的數據寫入當天的實時分區,在T+1日我們通過Hologres的外表導出的功能,將T日實時寫入的這類快照狀態字段從Hologres導出到MaxCompute做持久化離線存儲,在批任務的鏈路裏離線分區的快照類字段可JOIN這份數據產出,同時也可以用以後續的數據回刷、業務洞察分析。

--回寫至MaxCompute
INSERT INTO ads_holo_imp_di_foreign --外表,映射ODPS表ads_xxx_holo_imp_di
        ( 
           date_id               
          ,serv_id 
          ,xxx
        )
SELECT   date_id               
         ,serv_id   
         ,xxx
FROM ads_total_chl_di
WHERE date_id= '${bizdate}';

業務效果

一體化體驗洞察於本年初上線,目前主要支持在淘系退款、諮詢萬求等場景的實時多維交叉分析、智能異常檢測,月均50億+數據量級下的聚合查詢基本均能在秒級返回,支持到100+業務小二大促、日常的體驗運營洞察分析,助力業務小二單次洞察分析提效10倍以上。

雙11大促期間(11.1-11.20),一體化洞察提交執行的Query數爲66w+,假設50%的Query爲有效查詢,同樣按照每個Query小二過去平均需要投入10分鐘進行編寫、執行、檢查等操作來計算,共計節省了6875人日,當然如果沒有對應的數據/產品能力,小二受限於SQL技能以及開發成本也不會產生這麼多查詢,但也側面反映了一體化洞察對小二們工作效率的有力提升。

未來方向和思考

流批一體化

由於目前上游依賴的中間層離線和實時模型還不能完全統一,整體的數據架構還是比較傳統的Lambda架構,需要維護離線、實時兩套任務,開發、任務運維的成本較高,並且實時、離線數據存在一定的差異。當然從一套代碼實現原先流批兩條鏈路的的角度來說,目前基於Hologres的架構下存儲統一、計算統一的前提都是具備的,後續我們主要推進DWD中間層的模型統一,完成一體化體驗洞察整體數據架構流批一體。

數據集服務管理

爲了整體快速上線,目前仍有大量的FBI數據集直連Hologres庫而非託管在數據服務平臺。因而數據集的監控、壓測、慢查詢的預警優化等沒法依託數據服務平臺的能力納入統一管理,爲了保障數據的穩定性、高可用性,後續需要將體驗洞察的所有數據集依託服務平臺集中管控。

作者:張乃剛(花名:雋馳),CCO數據開發

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章