實時計算部分參考自博文:數據庫
用戶分類,精準營銷。服務器
我司經常使用的標籤有:新用戶、老用戶、流失用戶、活躍用戶等。此外,還能夠根據用戶以往行爲,如投訴、訂單取消、查看報價等,爲用戶打上相應的標籤。標籤系統提供了從多維度進行用戶分類的方法 。在用戶分類的基礎上,實現差別化營銷、差別化優惠,則能夠節約營銷成本。異步
標籤如新用戶、流失用戶等 ,會隨用戶在系統中下單而失效。而活躍用戶會隨着用戶在系統中長期不下單而變成流失用戶。一般,用戶半年之前的行爲參考性較低。用戶標籤須要根據用戶近期行爲生成。所以,標籤必須與用戶的實際狀態同步,從而不誤導營銷決策。elasticsearch
使用標籤的需求有2種:設計
總而言之就是:從用戶角度查詢;從標籤角度查詢blog
爲用戶打上標籤本質上是爲識別用戶的某種歷史行爲特徵並標記出來。因爲標籤的時效性要求,須要分析用戶近期的行爲。所以,咱們將用戶的行爲做爲基本的記錄、分析單位。索引
一條記錄的例子以下:事件
用戶Id | 發生時間 | 行爲類型 | 訂單Id | 其它 |
---|---|---|---|---|
123 | 2016-10-20 12:10:32 | 取消訂單 | orderId | ..... |
每當用戶進行某個行爲時,則爲用戶添加一條記錄。爲方便實現更多的查詢、搜索擴展,咱們把用戶行爲數據實時導入到Elasticsearch中。get
當計算給定用戶標籤時,從elasticsearch/數據庫中查詢到指定時間段內用戶行爲,實時爲用戶計算標籤返回。同步
因爲用戶行爲是實時導入的,而用戶標籤是根據用戶最新行爲記錄生成的,所以生成的標籤具備實效性。因爲每一個用戶在一段時間內的訂單相關行爲數據量不大,所以計算開銷能夠忽略。
以上設計的好處在於,咱們能夠隨時調咱們生成標籤所關心的時間段。能夠關心最近3個月,或者忽然改到半年。而標籤的定義也能夠隨時更改。底層是最原始的用戶行爲數據,不須要任何改變。
根據標籤查詢用戶則要困難一些。咱們必須提早爲每一個用戶計算好標籤。才能夠根據標籤創建索引,最後實現查詢。在數據量較大的狀況下,計算一次可能須要1-2天。若是隻在少許時間節點使用此功能,這樣的時間開銷能夠接受。
咱們考慮若是須要常用此功能,如何實現 ?
因爲咱們已經有了實時計算給定用戶標籤的能力。所以,每當用戶有新的行爲時,咱們能夠從新爲此用戶計算標籤,併入庫。系統運行一段時間以後,在系統中有行爲的用戶在數據庫中都有了記錄。行爲越頻繁的用戶,其標籤狀態越實時。
爲了保證用戶標籤不過期,咱們記錄用戶標籤的更新時間。經過逐條掃庫的方式,更新數據庫中更新時間較爲久遠的數據,從新計算標籤。
因爲用戶最新的行爲會致使標籤更新,所以掃庫的方式只是爲了保證標籤不會由於時間的推移而過期。這方面的時效性要求在一週,一天之內均可以接受的。
一種監聽用戶行爲的方法是經過異步消息。用戶的行爲會在不一樣的服務器中發生。當服務器檢測到相關的事件時,經過消息系統發出消息通知,從而告知標籤系統。然而採用消息系統實現有如下2個問題:
消息重複的問題能夠經過去重來解決,而其它問題則沒法解決了。
所以咱們想到採用canal,經過監聽數據庫的變化,來得知訂單狀態變動的事件。這樣,不須要其它系統的配合,須要完成事件的可靠監聽。
咱們闡述了一種實現實時標籤系統的方法。經過存儲用戶的歷史行爲,咱們的底層系統具備了以不變應萬變的能力。經過實時計算標籤,用戶標籤的定義就能夠隨時修改了。經過將用戶行爲放入elasticsearch中,加快了用戶行爲查詢的速度。
另外一方面,經過實時從新計算用戶標籤,咱們保證了用戶標籤根據用戶行爲實時調整。而對於標籤的隨時間推移過期問題,咱們經過掃庫的方式來逐漸更新。從而作到了用實時更新應對快速變化,用後臺任務應對慢速化。
我司目前有不少用戶標籤都是都是經過離線數據分析計算出來的,好比:散單高頻用戶(散單:非包月包年套餐,高頻:每個月內連續下單超過3次)、餘額不足(會員卡內餘額小於50)、沉睡用戶(會員卡餘額大於200,但近30天內有完成單,近14天未建立訂單)等。這些標籤都是能夠經過各個業務表內的數據 進行彙總計算出來的。因此,咱們的方案是按期同步相關數據表到Hive數據表中,而後使用Hive SQL對數據進行離線數據分析,而後將數據清洗到現有的用戶標籤相關數據表中。