ITBear旗下自媒體矩陣:

滴滴 x StarRocks:極速多維分析創(chuàng)造更大的業(yè)務(wù)價值

   時間:2021-09-26 11:40:49 來源:互聯(lián)網(wǎng)編輯:星輝 發(fā)表評論無障礙通道

滴滴集團(tuán)作為生活服務(wù)領(lǐng)域的頭部企業(yè),正在全面測試和上線StarRocks。其中橙心優(yōu)選經(jīng)過一年多的數(shù)據(jù)體系建設(shè),我們逐漸將一部分需要實(shí)時交互查詢、即席查詢的多維數(shù)據(jù)分析需求由ClickHouse遷移到了StarRocks中,StarRocks在穩(wěn)定性、實(shí)時性方面也給了我們良好的體驗(yàn),接下來以StarRocks實(shí)現(xiàn)的漏斗分析為例介紹StarRocks在橙心優(yōu)選運(yùn)營數(shù)據(jù)分析應(yīng)用中的實(shí)踐。

作者:王鵬 滴滴橙心優(yōu)選數(shù)據(jù)架構(gòu)部資深數(shù)據(jù)架構(gòu)開發(fā)工程師,負(fù)責(zé)橙心優(yōu)選大數(shù)據(jù)基礎(chǔ)服務(wù)和數(shù)據(jù)應(yīng)用的開發(fā)與建設(shè)

需求介紹

當(dāng)前我們數(shù)據(jù)門戶上的漏斗分析看板分散,每個看板通常只能支持一個場景的漏斗分析,不利于用戶統(tǒng)一看數(shù)或橫向?qū)Ρ鹊?,看板無法支持自選漏斗步驟、下鉆拆解等靈活分析的功能。因此,我們需要一款能覆蓋更全的流量數(shù)據(jù),支持靈活篩選維度、靈活選擇漏斗,提供多種分析視角的漏斗分析工具,并定位流失人群、轉(zhuǎn)化人群,從而縮小問題范圍,精準(zhǔn)找到運(yùn)營策略、產(chǎn)品設(shè)計(jì)優(yōu)化點(diǎn),實(shí)現(xiàn)精細(xì)化運(yùn)營。

技術(shù)選型

電商場景的流量日志、行為日志一般會比傳統(tǒng)場景下的數(shù)據(jù)量大很多,因此在這樣的背景下做漏斗分析給我們帶來了兩大技術(shù)挑戰(zhàn):

·日增數(shù)據(jù)量大:日增千萬級數(shù)據(jù),支持靈活選擇維度,如何快速地對億級數(shù)據(jù)量進(jìn)行多維分析

·對數(shù)據(jù)分析時效性要求高:如何快速地基于億級數(shù)據(jù)量精確去重,獲取符合條件的用戶數(shù)量

StarRocks與ClickHouse在橙心內(nèi)部都有廣泛的應(yīng)用,我們也積累了豐富的經(jīng)驗(yàn),但StarRocks在易用性和可維護(hù)性上都比ClickHouse更勝一籌,下面這張表格是我們在使用過程中對兩者功能的一個簡單對比:

經(jīng)過不斷地對比和壓測,我們最終決定使用StarRocks來存儲需要進(jìn)行漏斗分析的數(shù)據(jù),因?yàn)镾tarRocks在SQL監(jiān)控、運(yùn)維方面相比ClickHouse的優(yōu)勢明顯,而且我們可以為了滿足不同的查詢場景,基于漏斗分析明細(xì)表創(chuàng)建各種各樣的物化視圖,提高多維數(shù)據(jù)分析的速度。

系統(tǒng)架構(gòu)

系統(tǒng)各層職責(zé)說明如下:

1、數(shù)據(jù)源:主要是web端、客戶端的埋點(diǎn)日志,這些埋點(diǎn)日志源源不斷地上傳給我們的數(shù)據(jù)接入層

2、數(shù)據(jù)接入層:

(1)數(shù)據(jù)接入總線:提供多種數(shù)據(jù)源的接入接口,接收并校驗(yàn)數(shù)據(jù),對應(yīng)用層屏蔽復(fù)雜的數(shù)據(jù)格式,對埋點(diǎn)日志進(jìn)行校驗(yàn)和簡單地清洗、轉(zhuǎn)換后,將日志數(shù)據(jù)推送到Kafka集群

(2)Kafka集群:數(shù)據(jù)接入總線與數(shù)據(jù)計(jì)算集群的中間層。數(shù)據(jù)接入總線的對應(yīng)接口將數(shù)據(jù)接收并校驗(yàn)完成后,將數(shù)據(jù)統(tǒng)一推送給Kafka集群。Kafka集群解耦了數(shù)據(jù)接入總線和數(shù)據(jù)計(jì)算集群,利用Kafka自身的能力,實(shí)現(xiàn)流量控制,釋放高峰時日志數(shù)據(jù)量過大對下游計(jì)算集群、存儲系統(tǒng)造成的壓力

3、數(shù)據(jù)計(jì)算與存儲層:

(1)數(shù)據(jù)計(jì)算集群:數(shù)據(jù)存入Kafka集群后,根據(jù)不同的業(yè)務(wù)需求,使用Flink或者Spark對數(shù)據(jù)進(jìn)行實(shí)時和離線ETL,并批量保存到StarRocks數(shù)據(jù)倉庫

(2)StarRocks數(shù)據(jù)倉庫:Spark+Flink通過流式數(shù)據(jù)處理方式將數(shù)據(jù)存入StarRocks,我們可以根據(jù)不同的業(yè)務(wù)場景在StarRocks里創(chuàng)建明細(xì)表、聚合表和更新表以及物化視圖,滿足業(yè)務(wù)方多樣的數(shù)據(jù)使用要求

4、數(shù)據(jù)服務(wù)層:內(nèi)部統(tǒng)一指標(biāo)定義模型、指標(biāo)計(jì)算邏輯,為各個應(yīng)用方提供統(tǒng)一的離線查詢接口和實(shí)時查詢接口

5、漏斗分析系統(tǒng):支持靈活創(chuàng)建和編輯漏斗,支持漏斗數(shù)據(jù)查看,漏斗明細(xì)數(shù)據(jù)導(dǎo)出

6、數(shù)據(jù)中臺:圍繞大數(shù)據(jù)數(shù)據(jù)生產(chǎn)與使用場景,提供元數(shù)據(jù)管理、數(shù)據(jù)地圖、作業(yè)調(diào)度等通用基礎(chǔ)服務(wù),提升數(shù)據(jù)生產(chǎn)與使用效率

詳細(xì)設(shè)計(jì)

目前,基于StarRocks的bitmap類型只能接受整型值作為輸入,由于我們原始表的user_id存在字母數(shù)字混合的情況,無法直接轉(zhuǎn)換成整型,因此為了支持bitmap計(jì)算,需要將當(dāng)前的user_id轉(zhuǎn)換成全局唯一的數(shù)字ID。我們基于Spark+Hive的方式構(gòu)建了原始用戶ID與編碼后的整型用戶ID一一映射的全局字典,全局字典本身是一張Hive表,Hive表有兩個列,一個是原始值,一個是編碼的Int值。以下是全局字典的構(gòu)建流程:

1、將原始表的字典列去重生成臨時表:

臨時表定義:

create table 'temp_table'{

'user_id' string COMMENT '原始表去重后的用戶ID'

}

字典列去重生成臨時表:

insert overwrite table temp_table select user_id from fact_log_user_hive_table group by user_id

2、臨時表和全局字典進(jìn)行l(wèi)eft join,懸空的詞典項(xiàng)為新value,對新value進(jìn)行編碼并插入全局字典:

全局字典表定義:

create table 'global_dict_by_userid_hive_table'{

'user_id' string COMMENT '原始用戶ID',

'new_user_id' int COMMENT '對原始用戶ID編碼后的整型用戶ID'

}

將臨時表和全局字典表進(jìn)行關(guān)聯(lián),未匹配中的即為新增用戶,需要分配新的全局ID,并追加到全局字典表中。全局ID的生成方式,是用歷史表中當(dāng)前的最大的用戶ID加上新增用戶的行號:

--4 更新Hive字典表

insert overwrite global_dict_by_userid_hive_table

select user_id, new_user_id from global_dict_by_userid_hive_table

--3 與歷史的字段數(shù)據(jù)求并集

union all select t1.user_id,

--2 生成全局ID:用全局字典表中當(dāng)前的最大用戶ID加上新增用戶的行號

(row_number() over(order by t1.user_id) + t2.max_id) as new_user_id

--1 獲得新增的去重值集合

from

(

select user_id from temp_table

where user_id is not null

) t1

left join

(

select user_id, new_user_id, (max(new_user_id) over()) as max_id from

global_dict_by_userid_hive_table

) t2

on

t1.user_id = t2.user_id

where t2.newuser_id is null

3、原始表和更新后的全局字典表進(jìn)行l(wèi)eft join,將新增用戶的ID和編碼后的整型用戶ID插入到原始表中:

insert overwrite fact_log_user_hive_table

select

a.user_id,

b.new_user_id

from

fact_log_user_hive_table a left join global_dict_by_userid_hive_table b

on a.user_id=b.user_id

4、創(chuàng)建Spark離線同步任務(wù)完成Hive原始表到StarRocks明細(xì)表的數(shù)據(jù)同步:StarRocks表fact_log_user_doris_table定義(Hive表fact_log_user_hive_table與該表的結(jié)構(gòu)一致):

CREATE TABLE `fact_log_user_doris_table` (

`new_user_id` bigint(20) NULL COMMENT "整型用戶id",

`user_id` varchar(65533) NULL COMMENT "用戶id",

`event_source` varchar(65533) NULL COMMENT "端(1:商城小程序 2:團(tuán)長小程序 3:獨(dú)立APP 4:主端)",

`is_new` varchar(65533) NULL COMMENT "是否新用戶",

`identity` varchar(65533) NULL COMMENT "用戶身份(團(tuán)長或者普通用戶)",

`biz_channel_name` varchar(65533) NULL COMMENT "當(dāng)天首次落地頁渠道名稱",

`pro_id` varchar(65533) NULL COMMENT "省ID",

`pro_name` varchar(65533) NULL COMMENT "省名稱",

`city_id` varchar(65533) NULL COMMENT "城市ID",

`city_name` varchar(65533) NULL COMMENT "城市名稱",

`dt` date NULL COMMENT "分區(qū)",

`period_type` varchar(65533) NULL DEFAULT "daily" COMMENT ""

) ENGINE=OLAP

DUPLICATE KEY(`index_id`, `user_id`, `biz_channel_name`, `pro_id`, `city_id`)

PARTITION BY RANGE(`dt`)(

PARTITION p20210731 VALUES [('2021-07-31'), ('2021-08-01')),

PARTITION p20210801 VALUES [('2021-08-01'), ('2021-08-02')),

PARTITION p20210802 VALUES [('2021-08-02'), ('2021-08-03')),

PARTITION p20210803 VALUES [('2021-08-03'), ('2021-08-04')),

PARTITION p20210804 VALUES [('2021-08-04'), ('2021-08-05')),

PARTITION p20210805 VALUES [('2021-08-05'), ('2021-08-06')),

PARTITION p20210806 VALUES [('2021-08-06'), ('2021-08-07')),

PARTITION p20210807 VALUES [('2021-08-07'), ('2021-08-08')),

PARTITION p20210808 VALUES [('2021-08-08'), ('2021-08-09')))

DISTRIBUTED BY HASH(`index_id`, `user_id`) BUCKETS 10

PROPERTIES (

"replication_num" = "3",

"dynamic_partition.enable" = "true",

"dynamic_partition.time_unit" = "DAY",

"dynamic_partition.time_zone" = "Asia/Shanghai",

"dynamic_partition.start" = "-2147483648",

"dynamic_partition.end" = "1",

"dynamic_partition.prefix" = "p",

"dynamic_partition.replication_num" = "-1",

"dynamic_partition.buckets" = "3",

"in_memory" = "false",

"storage_format" = "DEFAULT"

);

在這里我們使用了StarRocks的明細(xì)模型來建表,滿足用戶查詢漏斗明細(xì)數(shù)據(jù)的使用場景,在明細(xì)表上根據(jù)不同的多維漏斗分析查詢需求創(chuàng)建相應(yīng)的物化視圖,來滿足用戶選擇不同維度查看漏斗模型每一步驟用戶精確去重?cái)?shù)量的使用場景。

5、創(chuàng)建bitmap_union物化視圖提升查詢速度,實(shí)現(xiàn)count(distinct)精確去重:

由于用戶想要在漏斗模型上查看一些城市用戶轉(zhuǎn)化情況。

查詢一般為:

select city_id, count(distinct new_user_id) as countDistinctByID from fact_log_user_doris_table where `dt` >= '2021-08-01' AND `dt` <= '2021-08-07' AND `city_id` in (11, 12, 13) group by city_id

針對這種根據(jù)城市求精確用戶數(shù)量的場景,我們可以在明細(xì)表fact_log_user_doris_table上創(chuàng)建一個帶 bitmap_union 的物化視圖從而達(dá)到一個預(yù)先精確去重的效果,查詢時StarRocks會自動將原始查詢路由到物化視圖表上,提升查詢性能。針對這個case創(chuàng)建的根據(jù)城市分組,對user_id進(jìn)行精確去重的物化視圖如下:

create materialized view city_user_count as select city_id,bitmap_union(to_bitmap(new_user_id)) from fact_log_user_doris_table group by city_id;

在StarRocks中,count(distinct)聚合的結(jié)果和bitmap_union_count聚合的結(jié)果是完全一致的。而bitmap_union_count等于bitmap_union的結(jié)果求 count,所以如果查詢中涉及到count(distinct) 則通過創(chuàng)建帶bitmap_union聚合的物化視圖方可加快查詢。因?yàn)閚ew_user_id本身是一個INT類型,所以在 StarRocks 中需要先將字段通過函數(shù)to_bitmap轉(zhuǎn)換為bitmap類型然后才可以進(jìn)行bitmap_union聚合。

采用這種構(gòu)建全局字典的方式,我們通過每日凌晨跑Spark離線同步任務(wù)實(shí)現(xiàn)全局字典的更新,以及對原始表中 Value 列的替換,同時對Spark任務(wù)配置基線和數(shù)據(jù)質(zhì)量報(bào)警,保障任務(wù)的正常運(yùn)行和數(shù)據(jù)的準(zhǔn)確性,確保次日運(yùn)營和市場同學(xué)能看到之前的運(yùn)營活動對用戶轉(zhuǎn)化率產(chǎn)生的影響,以便他們及時調(diào)整運(yùn)營策略,保證日常運(yùn)營活動效果。

最終效果及收益

經(jīng)過產(chǎn)品和研發(fā)同學(xué)的共同努力,我們從需要查詢的城市數(shù)量、時間跨度、數(shù)據(jù)量三個維度對精確去重功能進(jìn)行優(yōu)化,億級數(shù)據(jù)量下150個城市ID精確去重查詢整體耗時3秒以內(nèi),以下是漏斗分析的最終效果:

未來規(guī)劃

1.完善StarRocks內(nèi)部工具鏈的開發(fā),同滴滴大數(shù)據(jù)調(diào)度平臺和數(shù)據(jù)開發(fā)平臺整合,實(shí)現(xiàn)MySQL、ES、Hive等數(shù)據(jù)表一鍵接入StarRocks。

2.StarRocks流批一體建設(shè),由于StarRocks提供了豐富的數(shù)據(jù)模型,我們可以基于更新模型和明細(xì)模型以及物化視圖構(gòu)建流批一體的數(shù)據(jù)計(jì)算與存儲模型,目前正在方案落地階段,完善后會推廣到橙心各個方向的數(shù)據(jù)產(chǎn)品上。

3.基于StarRocks On ElasticSearch的能力,實(shí)現(xiàn)異構(gòu)數(shù)據(jù)源的統(tǒng)一OLAP查詢,賦能不同場景的業(yè)務(wù)需求,加速數(shù)據(jù)價值產(chǎn)出。

后續(xù)我們也會持續(xù)關(guān)注StarRocks,在內(nèi)部不斷的升級迭代。期待StarRocks能提供更豐富的功能,和更開放的生態(tài)。StarRocks后續(xù)也會作為OLAP平臺的重要組件,實(shí)現(xiàn)OLAP層的統(tǒng)一存儲,統(tǒng)一分析,統(tǒng)一管理。

舉報(bào) 0 收藏 0 打賞 0評論 0
 
 
更多>同類資訊
全站最新
熱門內(nèi)容
網(wǎng)站首頁  |  關(guān)于我們  |  聯(lián)系方式  |  版權(quán)聲明  |  網(wǎng)站留言  |  RSS訂閱  |  違規(guī)舉報(bào)  |  開放轉(zhuǎn)載  |  滾動資訊  |  English Version