基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

人群圈選系統基本邏輯架構

人群圈選並不是一個新業務, 幾乎所有的網際網路公司都在做,因為這是一個基本營銷場景,選定的人群要發代金券,要匯入流量,要做針對性促銷,要選擇合適的人群,那怎麼做這件事情呢?實際上要透過人群的行為特徵,採購特性,關注特徵,興趣特性,甚至是教育程度等等,把人群劃分成不同的組。透過劃分人群組,在有限的營銷預算裡面,將資源投放給轉化率或點選率最高的人群。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

那這個業務需求的背後技術要求是什麼呢?

典型人群業務版塊的核心是洞察分析,洞察分析一般的場景是,要支撐幾萬個不同的廣告主,他們會在平臺上自由選擇更感興趣的人群,每個廣告主對人群的訴求是不一樣的,某些人關注的購買力,有些關注的是收藏行為。每天數萬廣告主發出數百萬次的查詢請求,構建數萬次各種人群包,各個系統的計算複雜度是要求非常高的。這裡的核心訴求包含幾個點,毫秒級洞察,因為所有的查詢希望是互動式的,需要在介面上每一次互動,每一次下拉選單,每一次選擇,每一次條件組合,都希望看到一個互動結果,整個人群是變大還是變小,目標人群是不是跟期望的相似。這一點對效能要求是非常大的。同時提醒大家,資料一定要脫敏處理,保護好使用者的個人隱私,所有的分析都是建立在合規資料基礎之上的分析。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

人群圈選系統服務引擎核心訴求

規模資料上的互動式分析效能

數萬廣告主提交數百萬次的資料查詢,需要毫秒級的響應,查的快是必須的。這個快加了一個限定詞,是規模資料。百萬級不算規模,行為日誌是非常大的,希望是百億級別以上,依舊有一個很好的互動式分析能力,能夠在秒級響應。

靈活篩選能力

使用者的篩選行為多種多樣,等值比較、數值大小範圍比較、時間範圍比較等。各種各樣的篩選條件能夠靈活組合,表達這些篩選結果就體現出來計算引擎的能力。

高吞吐更新能力

使用者標籤並不是靜態的,當前一切實時化,一切線上化,所有的行為資料變化,都希望能夠實時觸發,實時反饋下一時刻的系統決策。比如最新收藏夾裡放了什麼商品,這種行為能不能成為線上畫像的一部分。所以對高實時的吞吐能力要求會很高。

從計算層面來講,可以分成下圖幾種計算模式。

標籤過濾分為等值過濾,可以用Equal/In/Between,這些過濾可以在百億級別上進行操作。操作之後的結果集,要做很多的交差並集,舉個常見例子,一個使用者既關注了競品品牌也關注了本公司商品,卻沒有買,這裡面其實有並的關係,有差的關係,有交的關係。所以這些人群關係之間要組合,有很高的交差並集計算。最後還有很強的精確去重的需求,因為最終要把計算結果,變成一個唯一定位使用者的ID,這個ID會用來做廣告的投遞。那這些需求,在引擎層面上就是資料讀取效率怎麼樣,如果用行存讀取是不是會出現IO放大的問題,資料按行去存,真正過濾是按照某一列過濾,但是IO讀取,會把整行讀取,會出現IO放大問題。列存還會有索引問題、過濾效果問題。計算運算元上表連線時是Hash JOIN方式還是用Nest Loop JOIN方式。精確去重的效果如何。這些都是對計算引擎效率上有很高的要求。所以本質上是要解決高效資料儲存與過濾、關係運算記憶體/CPU消耗、精確去重記憶體/CPU消耗問題。

這裡就有很多不同的解決最佳化思路,是用更多的記憶體還是CPU。行業內大致的思路有兩種。

一種是透過預結算思路,有Kylin/Druid這樣的技術。這些技術可以在一些預定義的維度上,進行一次提前的預加工。預加工後,資料集會在本質上進行減少。比如要找一個使用者群體,關注了第一個商品卻沒有關注第二個商品。每一個結果集都可以用bitmap陣列來表達,陣列之間做交差並集效率是非常高的。預計算技術實際上是把精確去重和交差並集上計算是有很大好處的。但缺陷也比較明顯,最大的缺陷就是不靈活,同時完整SQL表達能力也比較弱。另一種是屬於MPP分散式資料庫技術,一些透過列存、分散式、索引方式提供更好的查詢效能。

所以真正落地一套人群篩選方案時,一般不是隻選擇一個方案。因為不管是預計算方案還是MPP方案都有一些本質的缺陷。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

那市場上哪些技術更適合做儲存和查詢呢?

第一類技術,大家都比較熟悉的事務資料庫。事務資料庫是行儲存,對單行資料寫入儲存效率是非常高的,用來做查詢,做過濾統計,在千萬級以上會發現消耗資源是非常大的。所以一般不會拿TP系統直接做分析操作。

第二類系統,AP系統,是我們常見OLAP系統。這一類系統針對大規模資料掃描場景做了最佳化,包括利用分散式技術,列存技術,壓縮技術、索引的技術等等。這類技術查的都很快,但本質缺陷是大部分系統更新上做的不太友好,因為資料查的快,所以資料該緊湊緊湊,該壓縮壓縮,所以在更新能力上弱一些。還有一類系統,在大資料分析也常見,我們把它叫Serving系統,支援線上業務的一類系統,這類系統查的是足夠快,但犧牲的其實是查詢的靈活性。比如,文件資料庫、KeyValue系統查詢方式有很大的侷限,只能按照它的key去查詢。這樣靈活性減少了,但是效能上無限放大,因為可以橫向擴充套件,因為key相對來說訪問效率是最高的,而且更新效率也非常高,按照key更新,可以替換整條記錄。我們過去就不得不針對不同場景,把資料拆分到TP、AP、Serving,資料在幾個系統之間來回傳遞。讓我們對整個系統的依賴度變的更高,只要資料有一次依賴,就會產生一次資料不一致,產生資料不一致就意味著資料的修正,資料的開發成本變的更高。所以大家都會在很多領域做創新,第一類創新是在TP和AP領域裡做一個混合負載能力。嘗試透過一個技術把這兩個場景解決掉。有支援事務,又能支援分析,也希望未來有一天這個系統真正很好的落地。這類系統也有一定的侷限,要支援事務操作,各種分散式鎖開銷還是必不可少的。這類系統因為具備了一些能力,所以在整個併發和效能上,開銷是比較大的,所以有一定的效能瓶頸。

在下圖左側部分也是可以做一些創新的,左側的創新會發現最大的問題是不支援事務。把事務能力弱化,不需要那麼多事務,希望查的足夠快,更新的足夠快。所以這個地方是有可能做技術創新,這個技術既具備很好的靈活的分析能力,也具備很好的資料寫入能力,有具備完整的SQL表達能力。所以左側的交集部分的技術,很適合剛才提到的三點技術要求。這就是今天要分享的產品Hologres。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

Hologres=向量化SQL引擎 + 靈活的多維分析+高吞吐實時更新

Hologres,一站式實時數倉,提供實時分析(OLAP)與線上服務(點查)兩種能力,與MaxCompute無縫打通,實現一套架構,多種負載(OLAP、線上服務、互動式分析)共存,減少資料孤島,避免資料割裂,簡化鏈路,提升使用者體驗。

統一儲存

一份資料支援多種負載 (OLAP、線上服務、MaxCompute互動式分析),減少資料割裂

資料無孤島,無頻繁資料匯入匯出,提高資料開發效率、簡化鏈路

統一介面

介面相容開源Postgres協議,支援主流開發和BI工具,無需應用層重寫,生態開放

統一用SQL描述多種場景,提高資料應用開發效率

統一資料模型,透過“表”來描述數倉模型,語義一致

實時離線一體

支援實時寫入、實時更新、寫入即可查,原生整合Flink

與MaxCompute儲存無縫打通,透明加速,無需資料移動,支援互動式分析能力,支援實時資料關聯歷史資料

高效能

OLAP場景效能好於Clickhouse、Impala、Presto,支援亞秒級響應與高QPS

線上服務(點查)場景效能好於HBase,點查支援100K+QPS

Hologres:一站式實時數倉

Hologres為什麼能支援高效能,高吞吐寫入?

實際上沒有神秘的地方,Hologres更多還是依賴於整個IT行業,有很多底層技術上的進步。比如,頻寬變寬,延遲變低。好處是之前必須依賴本地的操作,比如之前依賴本地磁碟,現在可以依賴網盤。其實Hologres底層的儲存,分多副本儲存,高可靠儲存,把這些負責狀態管理的事情,都交給阿里雲,底層是盤古儲存引擎,自帶多副本,自帶壓縮,自帶快取,自帶高可靠。這就會使整個計算節點的邏輯變的輕薄和簡單,也讓高可靠更加簡單。任何一個節點宕掉之後,可以很快從一個分散式的網盤裡恢復狀態。會讓計算層變的無狀態,這是第一點。第二點是磁碟的利用,過去磁碟的轉速有機械瓶頸。機械磁碟是按圈去轉的,一秒鐘多少轉。所以我們的IO場景都是面向掃描場景做了大量的最佳化。我們希望所有的資料都是以塊為單位,進行更新、讀寫。所以在過去這種高更新場景,在整個數倉裡很難實現。Hologres是採用SSD設計,固態硬碟支援更好的隨機讀寫能力。這讓我們設計儲存架構的時可以拋開過去必須依賴於這種掃描場景,去設計整個儲存的資料結構。Hologres可以行存也可以列存,分別適應不同的場景,同時也採用log structured merge tree 的方式。支援高吞吐資料的寫入和更新的場景。第三個是CPU多核化,CUP的主頻已經不會有本質的提升。但是在多核化場景下,如果可以把一CPU內部多個核並行利用起來,就能把CPU資源充分發揮到極致。這就要求對作業系統的底層語言掌握的要比較好,Hologres使用C++實現的數倉。Hologres底層的運算元都會用向量化方式重寫,儘量發揮多核化平行計算能力,吧計算力發揮到極致。

從下圖可以看出,我們在網路上、儲存上、計算上、硬體層面有很多改進,這些改進都充分發揮出來,能夠做出一個不一樣的效果的系統。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

人群圈選場景之前提到,既有預計算場景,又有MPP分散式計算場景。使用單一某一個技術往往不太適合,真正落地的時候,希望既有預計算又有分散式計算,要把兩個技術更好的整合在一起。比如維度過濾場景就很適合用BITMAP,因為可以在BITMAP上做點陣圖索引。如true和false的場景,購買級別、對什麼產品關注等等,這些需要過濾的場景就適合做點陣圖索引。Hologres是支援點陣圖索引的。

第二種是關係運算,關係運算是我們提到的各種資料集之間的交差並,也非常適合點陣圖計算。因為點陣圖計算相當於是0和1之間,做很多與或差的操作,而且是並行操作,效率也是非常高的。

精確去重是BITMAP天生就具備的能力,因為點陣圖在構建時,就透過下標位,就唯一確定了ID。透過不同下標位之間上面一的值的簡單累加,就可以很快計算出精確去重的值是多少。這幾乎是把一個O(N)的問題變成O(1)的場景,效果也非常明顯。所以在做人群圈選場景裡面,預計算是很重要的技術。Hologres支援RoaringBitmap資料型別,高效率實現Bitmap的交叉並計算。

上文提到預計算是靈活性不足,需要透過分散式計算把計算力發揮出來,就用到了Hologres的向量化執行引擎。對MaxCompute資料外表直接加速,包括MaxCompute資料同步到Hologres裡,是會比MaxCompute同步到其它資料來源效能提高10倍已上。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

典型架構圖

典型架構圖如下,資料來源基本是透過埋點資料,透過訊息中介軟體kafka,第一件時間投遞到Flink,做一次輕量級資料加工,包括資料治理的修正,資料輕度彙總,資料維度拉寬。其中維度關聯是一個很重要的場景,真正的埋點資料都是記錄某些ID,這些ID都要轉換成有屬性意義的維度資訊。第一件事就是做維度拉寬,這是就可以使用Hologres的行存表,維度關聯時,基本是透過主鍵去關聯的,使用Hologres的行存表,可以存幾億幾十億的維度資訊。這些資訊可以實時的被更新。加工的結果集會寫到kafka裡面,因為並不是一次加工,可能是加工幾個迴圈。透過kafka做訊息驅動的方式,在Flink裡面做幾次加工,加工的結果基本上雙寫的場景會比較多,一部分實時寫入Hologres,另一部分以批次方式寫到MaxCompute裡面。離線數倉到實時數倉是一個很好的資料修正的場景,資料是一定會被修正的,所以會有大量透過離線數倉對實時數倉進行修正的場景,包括標籤加工也是典型的離線數倉來補充實時數倉的場景。所以一些行為是需要透過離線數倉加工好之後,把資料同步到實時數倉裡。但有另外一些屬性,是跟當下決策有關係的。這些是可以直接寫到實時數倉Hologres裡。所以可以把標籤分為離線和實時兩部分,實時寫到Hologres,離線透過MaxCompute加工後同步到Hologres。

在對外提供資料服務是,有幾種方式。建議的方式是,對外提供服務時,加一個閘道器,閘道器服務裡面會做很多限流、熔斷等等,這也是能提高資料服務穩定性的一個很好的幫助。如果是對內使用互動式分析的長治,可以直接透過JDBC的方式連線Hologres,如果是一個線上應用,建議透過API閘道器連線到Hologres。

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

資料結構層

離線數倉加工兩張表,一個是使用者基礎屬性表,記錄一些使用者屬性,性別城市年齡等。一個是交易明細表,記錄某個人在某一天針對某個商品買過多少,看過多少,收藏多少等。這些透過離線數倉加工好後,資料匯入Hologres。在透過配置把表列描述資訊以人類可讀的方式描述出來,再配置相關屬性標籤。把標籤上線後,廣告主會透過互動介面進行配置篩選。這種篩選背後都是翻譯成各種SQL語句,其實就是個各種SQL表示式。真正把查詢下發到底層引擎。那下發時底層引擎該如何建表呢?

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

寬表模式

每行描述一個使用者的標籤組合,每個key是一列,每一行對應value。

列不建議超過300列,列多會降低實時寫入的效能。分為熱點標籤和非熱點標籤

熱點標籤獨立為列,具備明確的資料型別,可以針對性設計索引,對查詢友好

非熱點標籤,透過陣列型別和JSON支援,適合動態更新,但索引不是最優,可擴充套件性更好

適應場景:維度屬性數量較低;實時寫入頻繁;更新以人的單位

優勢:開發簡單快速上線

方案描述:

使用者資料:例如user_tags表,寬表

行為資料:例如shop_behavior表,事實表

更新時,可以實時、批次更新不同的列

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

案例

—————————— 使用者標籤維度表 ——————————-begin;——3個熱點標籤欄位(text、integer、boolean型別),2個擴充套件標籤欄位(text[]型別和JSON型別)create table user_tags( user_id text not null primary key, city_id text, consume_level integer, marriaged boolean, tag_array text[], tag_json json);call set_table_property(‘user_tags’, ‘orientation’, ‘column’);—— 分佈列call set_table_property(‘user_tags’, ‘distribution_key’, ‘user_id’);—— text型別設定bitmap索引call set_table_property(‘user_tags’, ‘bitmap_columns’, ‘city_id,tag_array’);—— 熱點標籤,這是字典編碼call set_table_property(‘user_tags’, ‘dictionary_encoding_columns’, ‘city_id:auto’);commit;

—————————— 使用者行為事實表 ——————————-begin;create table shop_behavior( user_id text not null, shop_id text not null, pv_cnt integer, trd_amt integer, ds integer not null);call set_table_property(‘shop_behavior’, ‘orientation’, ‘column’);call set_table_property(‘shop_behavior’, ‘distribution_key’, ‘user_id’);——- 聚合鍵 對group by等運算更加友好call set_table_property(‘shop_behavior’, ‘clustering_key’, ‘ds,shop_id’);Commit;

窄表模式

將user_tag錶轉為窄表,每一個標籤一行記錄,標籤名為一列,標籤值為一列。

資料型別均退化為字串型別,適合標籤不固定,標籤稀疏,允許犧牲部分效能但提高標籤定義的靈活度。支援幾十到幾十萬不同標籤規模。

適應場景:維度屬性數量高;更新以標籤的單位

優勢:開發簡單快速上線

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

案例

基於 MaxCompute + Hologres 的人群圈選和資料服務實踐

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