淺析Tencent Analytics騰訊網(wǎng)站分析系統(tǒng)的架構(gòu)

TA(Tencent Analytics,騰訊分析)是一款面向第三方站長的免費網(wǎng)站分析系統(tǒng),在數(shù)據(jù)穩(wěn)定性、及時性方面廣受站長好評,其秒級的實時數(shù)據(jù)更新頻率也獲得業(yè)界的認(rèn)可。本文將從實時數(shù)據(jù)處理、數(shù)據(jù)存儲等多個方面帶你深入探尋TA的系統(tǒng)架構(gòu)及實現(xiàn)原理。
網(wǎng)站分析(Web Analytics)主要指的是基于網(wǎng)站的用戶瀏覽行為,對網(wǎng)站的點擊流數(shù)據(jù)和運營數(shù)據(jù)進(jìn)行分析,以監(jiān)控網(wǎng)站的運營狀況,為網(wǎng)站的優(yōu)化提供決策依據(jù)。網(wǎng)站分析系統(tǒng)已成為站長日常運營必不可少的工具,業(yè)界比較流行的網(wǎng)站分析系統(tǒng)主要有Google Analytics、CNZZ和百度統(tǒng)計等產(chǎn)品。
TA作為網(wǎng)站分析產(chǎn)品的后起之秀在社區(qū)分析、用戶畫像、網(wǎng)站工具等多方面形成了自己的特色,其秒級的實時數(shù)據(jù)更新頻率更是業(yè)界翹楚。在數(shù)據(jù)穩(wěn)定性、準(zhǔn)確性和及時性方面,TA在站長圈也是享有良好的口碑。隨著接入業(yè)務(wù)量的不斷發(fā)展,TA日均需要處理和計算的數(shù)據(jù)量達(dá)到TB級。如此龐大的數(shù)據(jù)量想要達(dá)到秒級實時且保證系統(tǒng)的高可用并非件易事。
TA的實時計算框架借鑒了一些業(yè)界流行的流式計算系統(tǒng)的思路。雖然在構(gòu)建系統(tǒng)中遇到了一些問題,但由于海量數(shù)據(jù)的實時處理、實時存儲具備一定的典型性與通用性,所以將TA的解決方案分享出來,希望能給大家一些啟示。
基本原理及系統(tǒng)架構(gòu)
TA的基本原理是通過嵌入站長網(wǎng)站的JavaScript腳本收集用戶訪問行為數(shù)據(jù),并發(fā)送TA采集集群,采集集群收到數(shù)據(jù)后將其過濾、編碼、格式化后繼續(xù)向后分發(fā)。數(shù)據(jù)處理集群負(fù)責(zé)按照業(yè)務(wù)邏輯計算數(shù)據(jù),并將計算結(jié)果“寫入”到數(shù)據(jù)存儲集群,最后將結(jié)果數(shù)據(jù)展現(xiàn)給廣大站長使用。TA的基本原理如圖所示。
TA后臺是一套完整的數(shù)據(jù)流處理系統(tǒng):由JavaScript采集的用戶行為數(shù)據(jù)像川流不息的河水一樣流入TA后臺,經(jīng)過清洗、計算后源源不斷地流出到TA存儲集群,供用戶瀏覽和查詢。TA的具體架構(gòu)及核心部件如圖所示。
TA的后臺分為離線和實時兩部分:實時部分負(fù)責(zé)系統(tǒng)的主要功能計算,數(shù)據(jù)更新頻率為秒級;離線部分負(fù)責(zé)系統(tǒng)復(fù)雜的關(guān)聯(lián)分析及跨天計算,數(shù)據(jù)更新頻率為天級。
Http Access:主要負(fù)責(zé)HTTP協(xié)議的解析,數(shù)據(jù)的清洗及格式化。
ESC:Event Streaming Coder,主要負(fù)責(zé)將系統(tǒng)不可枚舉的數(shù)據(jù)類型編碼成為整型,并將對應(yīng)關(guān)系持久化。
ESP:Event Streaming Processor,主要負(fù)責(zé)將數(shù)據(jù)按照站點、UID重新組織并計算PV、UV、停留時長和蹦失率等網(wǎng)站分析指標(biāo)。
ESA:Event Streaming Aggregator,主要負(fù)責(zé)匯總ESP計算后的數(shù)據(jù)按照站點,并寫入到Redis。
Center:系統(tǒng)的中心節(jié)點,負(fù)責(zé)系統(tǒng)配置、數(shù)據(jù)路由管理,并承擔(dān)容災(zāi)切換功能。
Logserver:負(fù)責(zé)將Access收集到的數(shù)據(jù)以字符串形式寫入文件,并上傳到TDCP上。
TDCP:騰訊分布式計算平臺,負(fù)責(zé)離線數(shù)據(jù)的計算,并由腳本將結(jié)果數(shù)據(jù)寫入MySQL中。
實時解決方案
前TA日均需要處理幾十萬網(wǎng)站的上TB級數(shù)據(jù),處理過后的URL個數(shù)仍有上億條,系統(tǒng)存儲的key個數(shù)超過十億。如何高效、低延遲地處理如此大量的業(yè)務(wù)數(shù)據(jù)是TA實時系統(tǒng)面臨的主要挑戰(zhàn)。TA解決方案的主要思路可以概括為數(shù)據(jù)全二進(jìn)制化、計算全內(nèi)存化、存儲NoSQL化。下面就實時計算和實時存儲這兩大子系統(tǒng)進(jìn)行深入的討論。
實時計算
對于計算子系統(tǒng),我們參考了Hadoop、S4和Storm等開源項目,力圖設(shè)計為一個較為通用,擴展性較強的全內(nèi)存實時Event處理系統(tǒng)(或者套用流行的術(shù)語稱為流式實時Event處理系統(tǒng))。對于這樣的一個系統(tǒng),我們設(shè)計支持的典型輸入輸出流程大致如圖所示。
實時計算系統(tǒng)的設(shè)計要點在數(shù)據(jù)組織、協(xié)議和增量計算模型上。
數(shù)據(jù)組織。萬物皆int,考慮到內(nèi)存以及計算過程的性能需求,我們將所有非int的數(shù)據(jù)類型轉(zhuǎn)化為int??梢悦杜e的數(shù)據(jù)類型,將其配置化映射為唯一int;不可枚舉的數(shù)據(jù)類型,則利用MD5算法近似得到唯一的int。例如,頁面URL屬于不可枚舉的類型,則預(yù)處理通過MD5算法近似得到唯一的int;UserAgent里的瀏覽器類型字符串則屬于可枚舉的數(shù)據(jù),則預(yù)先配置化映射為int。這個方法節(jié)省了較多內(nèi)存,提高了整個系統(tǒng)的計算性能。
協(xié)議。協(xié)議層面上,我們首先設(shè)計實現(xiàn)了一種可擴展的Event結(jié)構(gòu),這種Event結(jié)構(gòu)支持半自動化的序列化/反序列化機制(參考自msgpack的設(shè)計)和緊湊的二進(jìn)制編碼(基于Zigzag編碼,參考Protobuf的實現(xiàn))。這種Event結(jié)構(gòu)在流式高性能I/O(網(wǎng)絡(luò)傳輸和持久化)方面表現(xiàn)得相當(dāng)良好。實時計算子系統(tǒng)被設(shè)計為可以擴展支持任意的Event實現(xiàn)。
增量計算模型。增量計算模型,指的是基本計算過程,被定義為以下三部分(如圖所示)
Processor:負(fù)責(zé)具體業(yè)務(wù)邏輯的計算處理。
Data Holder:負(fù)責(zé)保存增量結(jié)果數(shù)據(jù),以及計算依賴的中間狀態(tài)數(shù)據(jù)。
Emitter:負(fù)責(zé)定期輸出清空增量計算結(jié)果。
具體到流程方面,分為以下三步(如圖所示)。
接收Event,計算處理—Processor。
保存計算結(jié)果以及計算依賴中間數(shù)據(jù)—DataHolder。
定時觸發(fā)輸出時間片內(nèi)計算結(jié)果,清空計算結(jié)果—Emitter。
增量計算模型弱化了分布式系統(tǒng)中單臺機器的事務(wù)狀態(tài),相應(yīng)地簡化了分布式計算系統(tǒng)的實現(xiàn),同時也提高了整個系統(tǒng)的性能。
實時存儲
在TA系統(tǒng)中,實時存儲的數(shù)據(jù)都是需要通過Web展示層讀取的統(tǒng)計數(shù)據(jù)。這類數(shù)據(jù)存在兩個典型特點。
頻繁更新寫。更新頻度視系統(tǒng)實時性而定,每條統(tǒng)計結(jié)果更新頻度最快可以達(dá)到1秒。
少量讀取。“少量”是相對上述更新而言的。同時根據(jù)業(yè)務(wù)邏輯,可將統(tǒng)計數(shù)據(jù)劃分為兩類。
固定不變數(shù)據(jù):主要是URL、搜索關(guān)鍵詞等數(shù)據(jù)。這一部分?jǐn)?shù)據(jù)理論上是在不停地增加,不會修改舊有數(shù)據(jù)。
動態(tài)數(shù)據(jù):主要是頻繁更新的結(jié)果統(tǒng)計數(shù)據(jù)。這一部分?jǐn)?shù)據(jù)則需要不停地更新。例如,www.qq.com域名下的PV和UV統(tǒng)計結(jié)果。
考慮到上述的TA實時統(tǒng)計數(shù)據(jù)的特點,我們選擇NoSQL實現(xiàn)我們的存儲系統(tǒng);同時,針對兩類不同的數(shù)據(jù)類型,分別選用LevelDB和Redis來存儲。
Redis
TA實時存儲的主要構(gòu)件??紤]到TA系統(tǒng)本身就是一個比較完善的分布式集群系統(tǒng),因此我們需要的存儲構(gòu)件是“not clustering, but sharding”。也就是說像HBase和MongoDB這樣的“重武器”并不適合TA,而NoSQL數(shù)據(jù)庫中的“瑞士軍刀”Redis憑借其出色的性能走入我們的視野。同時TA的結(jié)果數(shù)據(jù)類型也比較豐富,有像站點PV、UV、VV和IP等Hash類型的數(shù)據(jù),也有像用戶訪問軌跡這樣set類型的“動態(tài)數(shù)據(jù)”,而Redis豐富的數(shù)據(jù)結(jié)構(gòu)很好地完成了這項任務(wù)。
選擇Redis的另一個原因是它足夠簡單且易于擴展。在實際應(yīng)用的過程中,我們發(fā)現(xiàn)的問題都可以通過擴展Redis命令來解決。
例如,TA中有這樣的一種應(yīng)用場景:為了消除ESA模塊的狀態(tài),存儲在Redis中的數(shù)據(jù)往往并不是最終的結(jié)果數(shù)據(jù),而是還需要進(jìn)一步運算的中間數(shù)據(jù)。像bounce rate這個指標(biāo)(bouncerate=bounce session數(shù)/total session數(shù)),需要前臺查詢兩次再做一次運算后最終展示給用戶。在高并發(fā)的情況下,無疑會影響系統(tǒng)的響應(yīng)速度。
本著“移動計算,而不是移動數(shù)據(jù)”的原則,我們對Redis的sort、hmget命令進(jìn)行了擴展使其支持四則運算,成功地將原來的兩次查詢優(yōu)化為一次。擴展四則運算的另外一個目的是可以“通過計算換取存儲”,例如需要將兩種類型加總成總和的類型數(shù)據(jù),可以只存儲兩份,加總數(shù)據(jù)“通過計算換取”。
除了數(shù)據(jù)讀取,數(shù)據(jù)的寫入也可以進(jìn)行類似合并數(shù)據(jù)的優(yōu)化。例如,TA在寫入URL的PV、UV、VV、IP、停留時長和bounce rate這6個指標(biāo)時,需要調(diào)用6次Redis命令。而實際上這6個指標(biāo)是存儲在同一個Hash內(nèi)的,通過擴展hmincrby命令,支持將Hash的所有field一次更改,便能將調(diào)用次數(shù)優(yōu)化至一次。上線之后也取得了良好的效果,峰值時的CPU利用率幾乎下降了一半,同時也大幅提升了上層模塊ESA的吞吐量。
LevelDB
它是Redis的有效補充??紤]到Redis為內(nèi)存數(shù)據(jù)庫,而使用內(nèi)存的成本要高于硬盤,因此選擇引入了基于磁盤存儲的LevelDB作為補充。由于LevelDB的寫性能足夠好,而讀性能也遠(yuǎn)遠(yuǎn)超過目前“在線少量讀取”的需求,所以我們選擇LevelDB存儲“固定不變數(shù)據(jù)”。
在數(shù)據(jù)存儲的架構(gòu)設(shè)計上,由于實時數(shù)據(jù)服務(wù)與在線系統(tǒng),可靠性要求較高,因此我們主要采取雙寫復(fù)制+Sharding的設(shè)計方法。
雙寫復(fù)制。所有的數(shù)據(jù)存儲都會至少同步寫兩份,以提高在線系統(tǒng)服務(wù)的可用性。
數(shù)據(jù)分片(Sharding)。
基于域名:所有的數(shù)據(jù)以域名為單位組織分片;任何域名可以調(diào)整到任意分片中;單個域名數(shù)據(jù)原則上存儲在一個分片中。
動態(tài)調(diào)整(如圖所示):只調(diào)整分片策略,不移動數(shù)據(jù);基于數(shù)據(jù)量計算分片負(fù)載。
此外,針對分片集群數(shù)據(jù)的查詢,我們主要做了三項工作(如圖所示)。
Redis Protocol Stack是一個較為完整的Redis協(xié)議棧,是上層應(yīng)用的基礎(chǔ)。直接用Redis協(xié)議作為對外提供查詢的通用協(xié)議,這樣外部用戶可直接通過目前各種Redis Client實現(xiàn)來查詢訪問數(shù)據(jù)。Query Rule Engine是一個靈活的查詢引擎。能夠根據(jù)規(guī)則智能地在多個Redis、LevelDB數(shù)據(jù)源中查詢,執(zhí)行類join的操作;也簡單擴展支持其他的異構(gòu)數(shù)據(jù)源,如MySQL、HBase等。
Query Compute Engine是一個實時查詢計算引擎,能根據(jù)基礎(chǔ)查詢結(jié)果實時計算。引入此部分的主要目的在于減少Redis數(shù)據(jù)空間占用。
未來展望
目前TA雖然在后臺上已經(jīng)做到數(shù)據(jù)秒級更新,但展示方式仍為傳統(tǒng)的靜態(tài)方式。后續(xù)TA會在數(shù)據(jù)的動態(tài)刷新上進(jìn)行更多嘗試,讓站長可以第一時間了解網(wǎng)站營銷效果,時刻感受網(wǎng)站心跳。
相關(guān)文章
初窺Google網(wǎng)站的服務(wù)器基本架構(gòu)
這篇文章主要簡單介紹了Google網(wǎng)站的服務(wù)器基本架構(gòu),文中的分析事件較早因而由于谷歌內(nèi)部技術(shù)的快速迭代,一些注入MapReduce之類的技術(shù)可能已經(jīng)不在應(yīng)用范圍中,但整體的架構(gòu)2016-01-27分析整理YouTube網(wǎng)站用到的技術(shù)架構(gòu)及擴展經(jīng)驗
這篇文章主要介紹了YouTube網(wǎng)站用到的技術(shù)架構(gòu)及擴展經(jīng)驗,作為全球最大在線視頻網(wǎng)站的YouTube一直堅持簡潔的架構(gòu)原則并且在可擴展性方面做得相當(dāng)出色,需要的朋友可以參考下2016-01-26簡要解析Twitter服務(wù)器的數(shù)據(jù)請求處理架構(gòu)
這篇文章主要介紹了Twitter服務(wù)器的請求處理架構(gòu),Twitter作為一個大型微博網(wǎng)站需要在同一時間內(nèi)處理大量的實時信息請求,幾年時間下來Twitter也在信息洪峰處理方面積累下了2016-01-25全面了解Facebook的大數(shù)據(jù)處理架構(gòu)及應(yīng)用的軟件
這篇文章主要介紹了Facebook的大數(shù)據(jù)處理架構(gòu)及應(yīng)用的軟件,得益于Facebook的開放精神,人們能夠更多地了解到這家全球頭號社交網(wǎng)絡(luò)巨頭所采用的先進(jìn)技術(shù),需要的朋友可以參考2016-01-22淺析新浪微博的集群技術(shù)利用及網(wǎng)站業(yè)務(wù)架構(gòu)
這篇文章主要介紹了新浪微博的集群技術(shù)利用及網(wǎng)站業(yè)務(wù)架構(gòu),講到了緩存和消息隊列等微博的負(fù)載解決方案,需要的朋友可以參考下2016-01-20- 這篇文章主要介紹了新浪微博的網(wǎng)站整體架構(gòu),作為國內(nèi)最大的社交網(wǎng)站,以傳統(tǒng)的LAMP結(jié)構(gòu)架起的新浪微博的承載性能的確相當(dāng)強悍,其中自然少不了微博自身的不斷開發(fā)與優(yōu)化,需要2016-01-12
淺談SegmentFault對網(wǎng)站架構(gòu)的改進(jìn)與優(yōu)化
這篇文章主要介紹了SegmentFault對網(wǎng)站架構(gòu)的改進(jìn)與優(yōu)化,談到了云計算的使用以及代碼上線模式的改變等等,需要的朋友可以參考下2016-01-11eBay的網(wǎng)站架構(gòu)演進(jìn)以及技術(shù)特點解析
這篇文章主要介紹了eBay的網(wǎng)站架構(gòu)演進(jìn)以及技術(shù)特點解析,eBay是全球最大的在線拍賣網(wǎng)站,其網(wǎng)站架構(gòu)特別是數(shù)據(jù)庫的技術(shù)發(fā)展自然也受到很多人的關(guān)注,需要的朋友可以參考下2015-12-22- 這篇文章主要介紹了了解知乎網(wǎng)站的架構(gòu)演進(jìn)史,知乎使用Python的異步框架Tornado的經(jīng)驗事例非常經(jīng)典,值得Python學(xué)習(xí)以及愛好者們借鑒,需要的朋友可以參考下2015-12-07
解析豆瓣的網(wǎng)站建設(shè)技術(shù)架構(gòu)
這篇文章主要介紹了解析豆瓣的網(wǎng)站建設(shè)技術(shù)架構(gòu),豆瓣除了作為國內(nèi)的Python使用大戶,在數(shù)據(jù)庫和集群方面的架設(shè)同樣頗具亮點,需要的朋友可以參考下2015-12-07