我們原來一直用的買的三方的用戶行爲分析系統,它裏面提供了比較完善的功能,但是有個問題,就是我們業務系統數據導入比較費勁,不提供批量導入的接口,和他們提了需求,但是也沒有實現,另外我們買的是部署在我們自己機房的服務,但是對方可以直接訪問,數據安全也存在問題。正好最近分佈式數據庫技術的完善,給我們提供了另一種方式記錄海量數據的簡單方式。我們就基於TiDB自己設計開發了一套記錄用戶行爲的系統,設計如下:
user_behavior記錄用戶的行爲,是整個系統中最大的表,裏面記錄的都是各種外鍵id,儘可能壓縮空間,詳細信息如下
字段名 |
字段類型 |
字段意義 |
system |
TINYINT |
系統id(聯合主鍵) |
uid |
INT |
用戶id(聯合主鍵) |
access_time |
BIGINT |
訪問時間,精確到毫秒(聯合主鍵) |
func_id |
SMALLINT |
URL id(聯合主鍵) |
time_interval |
SMALLINT |
調用耗費總時間 |
ip |
INT |
設備ip |
ua |
INT |
設備ua對應的id |
result |
SMALLINT |
返回的code |
msg |
SMALLINT |
返回的錯誤原因id |
func表記錄所有的調用URL
func_msg表記錄所有調用URL的失敗返回信息
user_ip表記錄所有用戶訪問服務的ip
user_ua表記錄所有用戶瀏覽器UA
當然除了記錄用戶的行爲外,我們還在各種維度上對數據進行統計,爲線上的運營提供統計數據。
前端頁面的埋點是在接口層給前端提供了一個通用的get接口,後端的接口調用是在接口層aop攔截,由於我們這個系統兼顧了反爬蟲的職責,因此消息的實時性比較高,就沒有走寫日誌文件後異步採集上報的方式,而是直接推送到消息隊列中了。
我們用的是普通的磁盤來保存用戶行爲,一開始保存數據採用每次接收數據後直接保存到tidb的方式,但是發現效率不高,每次寫入數據平均要20ms,後來改爲每次接收數據後先寫入到redis裏面,然後批量寫入redis。
現在user_behavior表已經有10億條數據了,按照目前的主鍵設計(系統-用戶id-訪問時間-訪問URL),同一個系統每個人的數據都是聚合在一起的。和公司後來招聘的大數據開發討論了一下我們設計的系統,沒有發現短板,他們也說了下他們用HDFS保存數據的思路,是按照天來保存數據的,每天每個人的數據是在一起的,如此設計既兼顧了時間維度來分析數據,也兼顧了用戶維度來分析數據,是一個比較不錯的中和的方案。參照這個思路,我的主鍵設計也改爲了(系統-訪問日期-用戶id-訪問時間-訪問URL),即增加一列日期,加入聯合索引中。
整個系統之所以可以按照任意維度來插入數據還不影響效率,LSM Tree功不可沒。整個系統之所以能任意擴展,tidb功不可沒。以前我們要實現大數據,需要用到hdfs相關的一整套東西,需要一個團隊來專門處理,但是技術進步使得普通的團隊也可以實現大數據應用。