趙煜楊
百度 | 資深研發(fā)工程師
負(fù)責(zé)手百小程序數(shù)據(jù)產(chǎn)品的工程架構(gòu)工作,從0到1主持設(shè)計(jì)了精細(xì)化用戶分層系統(tǒng),實(shí)現(xiàn)了百億級(jí)TB量級(jí)小程序用戶畫像、行為數(shù)據(jù)秒級(jí)預(yù)估,保障了小程序私域運(yùn)營的落地。具有超過6年在高可用、大數(shù)據(jù)方向的工作經(jīng)驗(yàn),一直專注在數(shù)據(jù)工程架構(gòu)、個(gè)性化推薦工程等工作上,對(duì)技術(shù)團(tuán)隊(duì)管理也比較有經(jīng)驗(yàn),目前個(gè)人專注于大數(shù)據(jù)、個(gè)性化推薦、高可用架構(gòu)等技術(shù)方向。
本文的主題為基于Doris的小程序用戶增長實(shí)踐,將從實(shí)際案例出發(fā)介紹基于 Doris 用戶分層解決方案,重點(diǎn)分享了項(xiàng)目中的難點(diǎn)和架構(gòu)解決方案,以及怎么使用 Doris做用戶分層,如何做到秒級(jí)的人數(shù)預(yù)估和快速產(chǎn)出用戶包。主要內(nèi)容包括:
- 小程序私域精細(xì)化運(yùn)營能力介紹
- 用戶分層技術(shù)難點(diǎn)
- 用戶分層的架構(gòu)和解決方案
- 未來規(guī)劃
01小程序私域精細(xì)化運(yùn)營能力介紹
好,現(xiàn)在開始?,F(xiàn)在首先介紹一下我們小程序當(dāng)前的私域精細(xì)化運(yùn)營的能力有哪些。
首先我們?yōu)樯兑鏊加蚓?xì)化運(yùn)營呢,這起源于兩個(gè)痛點(diǎn):
- 私域用戶的價(jià)值不突出比如:我有100萬個(gè)用戶,我想給高收入人群去推薦奢侈品的包包,但是我不知道在這100萬人里面有多少人是這種高收入人群
- 缺乏主動(dòng)觸達(dá)的能力
然后針對(duì)這兩個(gè)問題,我們產(chǎn)品上面提出了一個(gè)解決方案 — 就是分層運(yùn)營,它主要分為兩部分:一個(gè)是運(yùn)營觸達(dá),還有一個(gè)是精細(xì)化的人群。
舉個(gè)例子:如圖示,從上往下看:當(dāng)運(yùn)營想搞一個(gè)活動(dòng)時(shí)(比如 DataFun Talk 這個(gè)活動(dòng)),可以選擇消息、私信、卡券、小程序內(nèi)這四個(gè)通路中的一個(gè)進(jìn)行推送,選完通路之后,就需要選擇需要推送的人群,這時(shí)候就要用到精細(xì)化人群,精細(xì)化人群是基于百度大數(shù)據(jù)平臺(tái)提供的畫像數(shù)據(jù)、新聞數(shù)據(jù)生成的,最后根據(jù)選擇人群、推送通路完成推送。之后我們還會(huì)提供觸達(dá)效果的分析,主要包括下發(fā)量、點(diǎn)展、到達(dá)之類的,另外針對(duì)人群也會(huì)提供整個(gè)用戶群體更細(xì)致化的分析。
這套解決方案的收益和價(jià)值:
對(duì)于開發(fā)者來說:
- 合理地利用私域流量提升價(jià)值
- 促進(jìn)用戶活躍和轉(zhuǎn)化
對(duì)于整個(gè)生態(tài)來講:
- 提高了私欲利用率和活躍度
- 激活了開發(fā)者主動(dòng)經(jīng)營的意愿
- 促進(jìn)了生態(tài)的良性循環(huán)
以上講的是一個(gè)產(chǎn)品的方案,接下來跟大家講一下具體的功能
1. 分層運(yùn)營-B端視角
首先介紹下 B 端視角下分層運(yùn)營平臺(tái)是如何工作的,比如說我是開發(fā)者,我是怎么去做去創(chuàng)建用戶分層的。
這里我們提供了自定義配置篩選的功能,可以從用戶關(guān)注、卡券、交易、活躍行為、性別、年齡等多種維度選擇,同時(shí)提供了預(yù)估人數(shù)的功能,可以實(shí)時(shí)的算出來你當(dāng)前圈選的用戶有多少人,方便評(píng)估一下人數(shù)是否 OK,如果 OK 的話,就直接生成人群,如果不 OK 的話,就重新選擇篩選條件。
完成人群篩選之后,會(huì)進(jìn)入分層管理列表,在列表里面可以根據(jù)需要點(diǎn)擊對(duì)應(yīng)的推送按鈕就可以直接推送,推送方式包括私信、群發(fā)。當(dāng)然了,這里也有群體分析功能。
B 端功能入口:
小程序開發(fā)者后臺(tái) -> 運(yùn)營中心 -> 分層運(yùn)營 -> 分層管理 -> 自定義篩選
2. 分層運(yùn)營-C端視角
簡單展示下 C 端視角下分層運(yùn)營的一個(gè)樣式:如圖截取的是百度APP 上通知和私信的樣式。
02用戶分層技術(shù)難點(diǎn)
1. 分層運(yùn)營經(jīng)典案例
下面給大家介紹分層運(yùn)營的一個(gè)經(jīng)典的案例 — 我們跟汽車大師的合作案例:
需求是汽車大師要對(duì)近一周付費(fèi)且活躍的用戶進(jìn)行一個(gè)評(píng)價(jià)送券的活動(dòng)。圖中截圖展示了這個(gè)活動(dòng)的交互過程:汽車大師推送一個(gè)通知(圖中:8/6日通知),然后用戶在《 百度APP -> 我的 -> 通知 》里面就可以看到汽車大師的通知消息,點(diǎn)開之后跳轉(zhuǎn)到《咨詢待評(píng)價(jià)頁面》,然后寫完評(píng)價(jià)后系統(tǒng)會(huì)自動(dòng)發(fā)券并通知給用戶;在這個(gè)活動(dòng)中達(dá)成的效果如下:
- 準(zhǔn)確判斷了用戶需求,活躍用戶價(jià)值,頁面的打開率達(dá)到了 9.51%
- 用戶次均使用時(shí)長提升 2.5 倍
- 活動(dòng)帶來新增付費(fèi)轉(zhuǎn)化率達(dá) 17.71%
簡單介紹下一些這里面的基本運(yùn)營技巧:
- 結(jié)合和實(shí)際的業(yè)務(wù)場景,無中間頁跳轉(zhuǎn)的折損
- 拼接消息組件,自動(dòng)發(fā)券場景過度順轉(zhuǎn)
- 場景可定期復(fù)用,節(jié)省人力成本。創(chuàng)建完人群之后,可以一直使用,不需要重復(fù)創(chuàng)建
- “分享和使用” 雙按鈕強(qiáng)強(qiáng)勢引導(dǎo)
上面的分享主要是讓大家了解用戶分層運(yùn)營給開發(fā)者帶來運(yùn)營效率以及轉(zhuǎn)化效果的一個(gè)提升,從而促進(jìn)用戶增長。這種看起來是特別的香,對(duì)不對(duì) ?但是它有沒有什么技術(shù)難點(diǎn),答案是當(dāng)然有,而且還特別大,不過沒關(guān)系,大家不用擔(dān)心了,你們認(rèn)真聽完煜楊老師接下來的分享這些難點(diǎn)就會(huì)變得很 Easy了,用之前一句特別流行的廣告語就是:媽媽再也不用擔(dān)心我的工作了。
2. 分層運(yùn)營難點(diǎn)
難點(diǎn)的話,大家可以看下圖,可以看到我把難點(diǎn)跟方法論都放到了一起,其實(shí)最開始我是想先講難點(diǎn),然后后面再講方法論的,這樣的話就可以調(diào)一下大家的胃口??。后來我又一想,大家都是程序員對(duì)不對(duì),既如此,程序員何苦為難程序員,還是少一些套路,多一些真誠比較好。所以最后,我就把難點(diǎn)跟方法論都放到一起了,這樣可以給大家一個(gè)直觀的一個(gè)認(rèn)識(shí)。
首先給大家簡單介紹遇到的四個(gè)難點(diǎn):
- TB級(jí)數(shù)據(jù)。數(shù)據(jù)量特別大,前面講到我們是基于畫像和行為去做的一個(gè)用戶分層,數(shù)據(jù)量是特別大的,每天的數(shù)據(jù)量規(guī)模是 1T +
- 查詢的頻響要求極高,毫秒級(jí)到秒級(jí)的一個(gè)要求。前面介紹 B 端視角功能時(shí)大家有看到,我們有一個(gè)預(yù)估人數(shù)的功能,用戶只要點(diǎn)擊 ”預(yù)估人數(shù)“ 按鈕,我們就需要從 TB 級(jí)的數(shù)據(jù)量級(jí)里面計(jì)算出篩選出的人群人數(shù)是多少,這種要在秒級(jí)時(shí)間計(jì)算 TB 級(jí)的數(shù)量的一個(gè)結(jié)果的難度其實(shí)可想而知
- 計(jì)算復(fù)雜,需要?jiǎng)屿o組合。怎么理解?就是現(xiàn)在很多維度我們是沒辦法去做預(yù)聚合的,必須去存明細(xì)數(shù)據(jù),然后去實(shí)時(shí)的計(jì)算,這個(gè)后面也會(huì)細(xì)講
- 產(chǎn)出用戶包的時(shí)效性要求高。這個(gè)比較好理解,如果產(chǎn)出特別慢的話,肯定會(huì)影響用戶體驗(yàn)
針對(duì)上面的四個(gè)難點(diǎn),我們的解法是:
針對(duì)第一個(gè)難點(diǎn) –> 壓縮存儲(chǔ),降低查詢的數(shù)量級(jí)。
具體選型就是使用 Bitmap 存儲(chǔ),這解法其實(shí)很好理解,不管現(xiàn)在主流的 OLAP引 擎有多么厲害,數(shù)據(jù)量越大,查詢肯定會(huì)越慢,不可能說數(shù)據(jù)量越大,我查詢還是一直不變的,這種其實(shí)不存在的,所以我們就需要降低存儲(chǔ)。
針對(duì)第二和第三個(gè)難點(diǎn) –> 選擇合適計(jì)算引擎
我們調(diào)研了當(dāng)前開源的包括 ClickHouse, Doris, Druid 等多種引擎,最終選擇了基于 MPP 架構(gòu)的OLAP引擎 Doris。
這里可以簡單跟大家介紹一下選擇 Doris 的原因,從性能來說其實(shí)都差不多,但是都 Doris 有幾個(gè)優(yōu)點(diǎn):
- 第一:它是兼容 Mysql 協(xié)議,也就是說你的學(xué)習(xí)成本非常低,基本上大家只要了解mysql, 就會(huì)用Doris, 不需要很大的學(xué)習(xí)成本。
- 第二:Doris 運(yùn)維成本很低,基本上就是自動(dòng)化運(yùn)維。
針對(duì)第四個(gè)難點(diǎn) –> 選擇合適的引擎
通過對(duì)比 Spark 和 Doris,我們選擇了 Doris ,后面會(huì)詳細(xì)講為什么會(huì)用 Doris。
03用戶分層的架構(gòu)和解決方案
介紹難點(diǎn)以及解法之后,接下來從架構(gòu)跟解決方案里面跟大家細(xì)講一下,難點(diǎn)是怎么解決的。
分層運(yùn)營架構(gòu):
首先介紹一下我們分層運(yùn)營的架構(gòu)。架構(gòu)的話分為兩部分,就是在線部分跟離線部分。
在線部分:
分為了四層:服務(wù)層、解析層、計(jì)算層跟存儲(chǔ)層,然后還有調(diào)度平臺(tái)和監(jiān)控平臺(tái)。
服務(wù)層,主要功能包含:
- 權(quán)限控制:主要是戶權(quán)限、接口權(quán)限的控制
- 分層管理:主要是是對(duì)用戶篩選的增刪改查
- 元數(shù)據(jù)管理:主要是對(duì)頁面元素、ID-Mapping 這類數(shù)據(jù)的管理
- 任務(wù)管理:主要是支持調(diào)度平臺(tái)任務(wù)的增刪改查
解析層,是對(duì)DSL的一個(gè)解析、優(yōu)化、路由以及Sql模板:
比如要查在線預(yù)估人數(shù),首先會(huì)在解析層做一個(gè) DSL 的解析,之后根據(jù)不同情景做 DSL 的優(yōu)化,比如選擇了近七天活躍且近七天不活躍的用戶,這種要七天活躍和七天不活躍的交集顯然就是零了,對(duì)不對(duì)?像這樣情況在優(yōu)化層直接將結(jié)果 0 返回給用戶就不會(huì)再往下走計(jì)算引擎,類似還有很多其他優(yōu)化場景。然后優(yōu)化完之后會(huì)使用 DSL 路由功能,根據(jù)不同查詢路由到不同的 Sql 模板進(jìn)行模板的拼接。
計(jì)算層,計(jì)算引擎我們使用 Spark 和 Doris:
- Spark:離線任務(wù)
- Doris:實(shí)時(shí)任務(wù)
存儲(chǔ)層:
- Mysql:主要用來存用戶分層的一些用戶信息
- Redis:主要用作緩存
- Doris:主要存儲(chǔ)畫像數(shù)據(jù)和行為數(shù)據(jù)
- AFS:主要是存儲(chǔ)產(chǎn)出的用戶包的一些信息
調(diào)度平臺(tái):
- 主要是離線任務(wù)的調(diào)度
監(jiān)控平臺(tái):
- 整個(gè)服務(wù)穩(wěn)定性的監(jiān)控
離線部分:
離線部分的話主要是對(duì)需要的數(shù)據(jù)源(比如說畫像、關(guān)注、行為等數(shù)據(jù)源)做 ETL 清洗,清洗完之后會(huì)做一個(gè)全局字典并寫入 Doris。任務(wù)最終會(huì)產(chǎn)出用戶包,并會(huì)分發(fā)給小程序 B 端跟百度統(tǒng)計(jì):
- 小程序 B 端:推送給手機(jī)端用戶
- 百度統(tǒng)計(jì):拿這些用戶包做一次群體分析
以上就是一個(gè)整體的架構(gòu)。
圖中大家可以看到有幾個(gè)標(biāo)紅的地方,同時(shí)也用數(shù)字 1、2、3 做了標(biāo)記,這幾個(gè)標(biāo)紅是重點(diǎn)模塊,就是針對(duì)于上面提到的四個(gè)難點(diǎn)做的重點(diǎn)模塊改造,接下來會(huì)針對(duì)這三個(gè)重點(diǎn)模塊一一展開進(jìn)行講解。
1. 全局字典
首先講解全局字典這個(gè)模塊,全局字典的目的主要是為了解決難點(diǎn)一:數(shù)據(jù)量大,需要壓縮存儲(chǔ)同時(shí)壓縮存儲(chǔ)之后還要保證查詢性能。
為啥要用全局字典:
這里大家可能會(huì)有一個(gè)疑問,就是說我用 BitMap 存儲(chǔ)為啥還要做全局字典?這個(gè)主要是因?yàn)?Doris 的 BitMap 功能是基于 RoaringBitmap 實(shí)現(xiàn)的,因此假如說用戶 ID 過于離散的時(shí)候,RoaringBitmap 底層存儲(chǔ)結(jié)構(gòu)用的是 Array Container 而不是 BitMap Container,Array Container 性能遠(yuǎn)遠(yuǎn)差于 BitMap Container。因此我們要使用全局字典將用戶 ID 映射成連續(xù)遞增的 ID,這就是使用全局字典的目的。
全局字典的更新邏輯概況:
這里是使用 Spark 程序來實(shí)現(xiàn)的,首先加載經(jīng)過 ETL 清洗之后各個(gè)數(shù)據(jù)源(畫像、關(guān)注、行為這些數(shù)據(jù)源)和全局字典歷史表(用來維護(hù)維護(hù)用戶 ID 跟自增 ID 映射關(guān)系),加載完之后會(huì)判斷 ETL 里面的用戶ID 是否已經(jīng)存在字典表里面,如果有的話,就直接把 ETL 的數(shù)據(jù)寫回 Doris 就行了,如果沒有就說明這是一個(gè)新用戶,然后會(huì)用 row_number 方法生成一個(gè)自增 ID ,跟這個(gè)新用戶做一次映射,映射完之后更新到全局字典并寫入 Doris。
2. Doris
接下來介紹第二個(gè)重點(diǎn)模塊 Doris。
2.1 Doris 分桶策略
分桶策略的目的是為了解決難點(diǎn)二:查詢頻響要求高。
為啥要做分桶策略:
我們之前使用了全局字典保證用戶的連續(xù)遞增,但是我們發(fā)現(xiàn)用了全局字典之后,BitMap 的查詢性能其實(shí)并沒有達(dá)到我們預(yù)期的那樣絲滑般柔順的感覺,哈哈哈。。。對(duì),還是特別慢,然后我們就特別郁悶了,開始懷疑 BitMap 并不像傳說中的那么快,難道童話都是騙人的嗎?我們就在想怎么解決這個(gè)問題,后來我們發(fā)現(xiàn) Doris 其實(shí)是分布式的一個(gè)集群,它會(huì)按照某些 Key 進(jìn)行分桶,也就是分桶之后用戶ID 在桶內(nèi)就不連續(xù),又變成零散的了。
舉個(gè)例子,如圖中左側(cè)原始數(shù)據(jù),可以看到 appkey 有A1、A2,channel 有C1、C2、C3,然后 userid 是0、1、2、3、4、5 六個(gè)連續(xù)的 userid 。我們按照 appkey 和 channel 進(jìn)行分桶,這樣的話分完桶之后的結(jié)果就是右邊這張圖:桶一 key 是A1、C1,userid 就是0、2;桶二 key 是 A1、C2,userid 就是 1、4;桶三 key 是A2、C3,userid 是3、5;大家能比較直觀地看到在桶中 userid 已經(jīng)不連續(xù)了,不連續(xù)的話,BitMap 的性能就沒法發(fā)揮出來的,它會(huì)走 Array Container 去存儲(chǔ),它的性能會(huì)比較差。
解決方式:
這里,其實(shí)我想問一下大家,這種怎么去保證桶內(nèi)的連續(xù)?大家如果有想法,可以私下一起討論下,現(xiàn)在大家不要給自己加戲啊, 今天的star是我啊, 大家要focus on me 身上啊。開個(gè)玩笑啊, 活躍下直播間氣氛。
接下來我會(huì)跟大家分享一下我們的一個(gè)方案,對(duì)了,給大家五秒鐘的時(shí)間,大家可以現(xiàn)在記筆記了,真的,這個(gè)方案是我們經(jīng)歷了無數(shù)個(gè)日日夜夜跟無數(shù)根頭發(fā)總結(jié)出來的,非常有實(shí)戰(zhàn)意義。
好,現(xiàn)在講一下我們的方案,我們的方案是在表里面增加了一個(gè) hid 的字段,然后讓 Doris 按照 hid 字段進(jìn)行分桶,這里 hid 生成算法是:
hid = V/(M/N) 然后取整
其中:
- V:全局字典的用戶ID 對(duì)應(yīng)的整數(shù)
- M:預(yù)估的用戶總數(shù)
- N:分層數(shù)
還是結(jié)合上面的例子,大家可以看一下:userid 是六個(gè)即 0~5,所以 M= 6;分為三個(gè)桶,N = 3;因此 M 除以 N 就等于二。這樣的話我就要用 userid 去除以二,然后取整作為 hid。可以看一下,比如說 userid 是零,0÷2 取整為 0 ,userid 是一的話,hid 還是這樣,因?yàn)?1÷2 的整數(shù)部分是零;同理 2÷2 、3÷2 是一,4÷2、5÷2 是二,這樣的話就把 userid 跟 hid 做對(duì)應(yīng),然后再根據(jù) hid 做分層。大家可以看到分層結(jié)果,hid = 0 時(shí) userid 是0、1,hid = 1 時(shí) userid 是2、3,hid = 2時(shí) userid 是 4、5,這樣就保證了桶內(nèi)連續(xù)。
2.2 doris之用戶畫像標(biāo)簽優(yōu)化
前面給大家講了分桶與全局字典這兩個(gè)通用的策略,就是說大家要做 BitMap 的話,這兩個(gè)東西肯定是要考慮的,但是只考慮這兩個(gè)東西,還并不能說達(dá)到性能的最優(yōu),還要結(jié)合自己的實(shí)際業(yè)務(wù)去做針對(duì)性的優(yōu)化,這樣才能達(dá)到一個(gè)性能的最優(yōu),接下來我會(huì)給大家介紹我們的具體業(yè)務(wù)優(yōu)化:畫像標(biāo)簽的優(yōu)化。
畫像標(biāo)簽優(yōu)化解決的難點(diǎn)也是難點(diǎn)二:查詢頻響要求高。這個(gè)問題當(dāng)時(shí)是有兩個(gè)方案。
方案一:
tag_type, tag_value 。tag_type 是用來記錄標(biāo)簽的類型,tag_value 是用來記錄標(biāo)簽的內(nèi)容。
如圖所示:比如說 tag_type 是性別,tag_value 可能是男或女,bitmap 這里就是存儲(chǔ)所有性別是男的用戶 id 列表。
同樣對(duì)于 tag_type 是地域、tag_value 是北京,bitmap 存儲(chǔ)的是所有地域在北京的用戶 id 列表。
方案二:
大寬表,使用大寬表在一行記錄了所有的標(biāo)簽,然后使用 bitmap 記錄這個(gè)標(biāo)簽的用戶 id 列表。
最終我們選擇了方案二,為什么沒有選方案一呢 ?因?yàn)榉桨敢凰且粋€(gè)標(biāo)簽對(duì)應(yīng)一個(gè)用戶 bitmap,當(dāng)我想查一個(gè)聯(lián)合的結(jié)果就比較耗時(shí),比如我想查詢性別是男且區(qū)域是北京的所有用戶,這樣的話我需要取出 “男” 的用戶和 “北京“ 的用戶,兩者之間做一個(gè)交集,對(duì)吧?這種的話肯定會(huì)有計(jì)算量會(huì)有更多的時(shí)間消耗,但是如果用大寬表去做存儲(chǔ)的話,就可以根據(jù)用戶常用的查詢?nèi)?gòu)建一個(gè)物化視圖,當(dāng)用戶的查詢(比如在北京的男性)命中了物化視圖,就可以直接去取結(jié)果,而不用再去做計(jì)算,從而降低耗時(shí)。
這里還有一個(gè)知識(shí)點(diǎn)跟大家分享一下:在使用 Doris 的時(shí)候,一定要盡量去命中它的前綴索引跟物化視圖,這樣會(huì)大大的提升查詢效率。
2.3 doris之動(dòng)靜組合查詢
好,用戶標(biāo)簽講完之后繼續(xù)講下一個(gè)難點(diǎn)的解決方案:動(dòng)靜組合查詢,對(duì)應(yīng)的難點(diǎn)是難點(diǎn)三:計(jì)算復(fù)雜。
首先介紹一下什么叫動(dòng)靜組合查詢:
- 靜態(tài)查詢:我們定義為用戶維度是固定的,就是可以進(jìn)行預(yù)聚合的查詢?yōu)殪o態(tài)查詢。比如說男性用戶,男性用戶個(gè)就是一個(gè)固定的群體,不管怎么查用戶肯定不會(huì)變,就可以提前進(jìn)行預(yù)聚合的。
- 動(dòng)態(tài)查詢:主要偏向于一些行為,就是那種查詢跟著用戶的不同而不同。比如說查近30天收藏超過三次的用戶,或者還有可能是近30天收藏超過四次的用戶,這種的話就很隨意,用戶可能會(huì)查詢的維度會(huì)特別的多,而且也沒法沒辦法進(jìn)行一個(gè)預(yù)聚合,所以我們稱之為動(dòng)態(tài)的一個(gè)查詢。
然后小程序用戶分層,相比于同類型的用戶分層功能增加了用戶行為篩選,這也是小程序產(chǎn)品的特點(diǎn)之一。比如說我們可以查近 30 天用戶支付訂單超過 30元的男性, 這種 ”近 30天用戶支付訂單超過 30元“ 的查詢是沒辦法用 bitmap 做記錄的,也沒辦法說提前計(jì)算好,只能在線去算。這種就是一個(gè)難點(diǎn),就是說我怎么用非 bitmap 表和 bitmap 做交并補(bǔ)集的運(yùn)算,為了解決這個(gè)問題,我們結(jié)合上面的例子把查詢拆分為四步:我要查近30天用戶支付訂單超過30元的男性,且年齡在 20 ~30 歲的用戶(具體查詢語句參考 PPT 圖片)
第一步我先查 20~30歲的男性用戶。因?yàn)槭潜容^固定,這里可以直接查 bitmap 表,
第二步我要查近30天用戶支付訂單超過30元的用戶。這種的話就沒辦法去查 bitmap 表了,因?yàn)?bitmap 沒有辦法做這種聚合,只能去查行為表。
第三步就是要做用戶ID 跟在 線 bitmap 的一個(gè)轉(zhuǎn)化。Doris 其實(shí)已經(jīng)提供了這樣的功能函數(shù):to_bitmap,可以在線將用戶 id 轉(zhuǎn)換成 bitmap。
第四步是求交集。就是第一步和第四步的結(jié)果求交集。
然后,請大家要注意一下,整篇的核心其實(shí)是在第三步:Doris 提供了 to_bitmap 的功能,它幫我們解決了非 bitmap 表和 bitmap 聯(lián)合查詢的問題。講到這里,我其實(shí)想給大家表現(xiàn)出那種Doris特別驚艷、特別帥那種感覺,但是我線下練習(xí)了好多遍都無法表演出來, 你們看我現(xiàn)在的表演 有點(diǎn)太浮夸了, 用力過猛了。誰讓我是個(gè)程序員,不是個(gè)演員呢,沒有辦法演出那種感覺、那種感情。所以我只能把我想表達(dá)的感情跟大家說出來,大家一定要懂我,對(duì),就是那種很驚艷的感覺,大家一定要懂我~
以上是我們基于 Doris 用戶分層方案的一個(gè)講解,基于上述方案整體的性能收益是:
- 95分位耗時(shí)小于一秒
- 存儲(chǔ)耗降低了9.67倍
- 行數(shù)優(yōu)化了八倍
說明了基于 Doris 的用戶存儲(chǔ)方案還是特別有效果的, 希望我們的經(jīng)驗(yàn)?zāi)芙o大家能有所幫助。
3. 如何快速產(chǎn)出用戶包
現(xiàn)在講一下第三部分:用戶包。這部分主要是用來解決難點(diǎn)四:產(chǎn)出用戶包要求時(shí)效性高。這個(gè)其實(shí)我們也有兩個(gè)方案:
方案一:調(diào)度平臺(tái) + spark。
這個(gè)其實(shí)比較容易理解,因?yàn)槟阋茈x線任務(wù)很容易就想到了 spark。在這個(gè)調(diào)度平臺(tái)里面用了 DAG 圖,分三步:先產(chǎn)出用戶的 cuid,然后再產(chǎn)出用戶的 uid,最后是回調(diào)一下做一次更新。
方案二:調(diào)度平臺(tái) + solo。
- 執(zhí)行的 DAG 圖的話就是:solo 去產(chǎn)出 cuid,uid,還有回調(diào)。
- solo:是百度云提供的 Pingo 單機(jī)執(zhí)行引擎,大家可以理解為是一個(gè)類似于虛擬機(jī)的產(chǎn)品,這個(gè)其實(shí)是公有云:《百度智能云》里面已經(jīng)有的功能,大家感興趣的可以去登錄百度智能云官網(wǎng) 去看一下。
最終的方案選型我們是選用了 Doris,因?yàn)?Doris 比 Spark 更快,為啥快?
首先介紹下方案一,方案一使用的是 Spark ,它存在幾個(gè)問題:比如 Yarn 調(diào)度比較耗時(shí),有時(shí)候也會(huì)因?yàn)殛?duì)列的資源緊張而會(huì)有延遲,所以有時(shí)候會(huì)出現(xiàn)一個(gè)很極端的情況就是:我產(chǎn)出零個(gè)用戶,也要30分鐘才能跑完,這種對(duì)用戶的體驗(yàn)度非常不好。
方案二的話就是我們利用了 Doris 的 SELECT INTO OUTFILE 產(chǎn)出結(jié)果導(dǎo)出功能,就是你查出的結(jié)果可以直接導(dǎo)出到 AFS,這樣的效果就是最快不到三分鐘就可以產(chǎn)出百萬級(jí)用戶,所以 Doris 性能在某些場景下比 Spark 要好很多。
最后大家可以看到其實(shí)我這里敘述的時(shí)候語氣依然是比較平淡的,是吧?沒有帶什么感情,但是我其實(shí)還想表達(dá)出那種驚嘆和喜悅的感情,就是 Doris 性能在某些場景下比 Spark 還要好,但是大家要懂我,我畢竟是個(gè)程序員不是一個(gè)演員,沒法表達(dá)出那種感覺,但是你們一定要懂我啊,哈哈,開個(gè)玩笑,活躍一下直播間氣氛。
04未來規(guī)劃
未來的規(guī)劃:
首先在產(chǎn)品上我們會(huì)繼續(xù)的豐富分層的應(yīng)用場景,拓展關(guān)系維度豐富觸達(dá)的形式,然后探索分層和商業(yè)的結(jié)合模式。
在技術(shù)上我們會(huì)從時(shí)效性豐富性跟通用性上做文章:
- 時(shí)效性:我們會(huì)把交易,訂單,關(guān)注等行為時(shí)實(shí)化
- 豐富性:我們會(huì)接入更多的用戶畫像,標(biāo)簽和行為
- 通用性:我們會(huì)把全局字典插件化,然后通用到各個(gè)業(yè)務(wù)上
這就是我們的未來規(guī)劃。后面有機(jī)會(huì)再根大家從 Doris 的架構(gòu)方面跟大家介紹下 Doris 的性能為何如此強(qiáng)悍。今天的分享就到這里,謝謝大家。
—— 歡迎在線投稿 ——
特別提示:關(guān)注本專欄,別錯(cuò)過行業(yè)干貨!
PS:本司承接 小紅書推廣/抖音推廣/百度系推廣/知乎/微博等平臺(tái)推廣:關(guān)鍵詞排名,筆記種草,數(shù)據(jù)優(yōu)化等;
咨詢微信:139 1053 2512 (同電話)
首席增長官CGO薦讀:
更多精彩,關(guān)注:增長黑客(GrowthHK.cn)
增長黑客(Growth Hacker)是依靠技術(shù)和數(shù)據(jù)來達(dá)成各種營銷目標(biāo)的新型團(tuán)隊(duì)角色。從單線思維者時(shí)常忽略的角度和高度,梳理整合產(chǎn)品發(fā)展的因素,實(shí)現(xiàn)低成本甚至零成本帶來的有效增長…
本文經(jīng)授權(quán)發(fā)布,不代表增長黑客立場,如若轉(zhuǎn)載,請注明出處:http://m.gptmaths.com/cgo/user/37464.html