轉帖|實施案例|編輯:我只采一朵|2017-07-03 16:14:30.000|閱讀 247 次
概述:此系統基于Java NIO網絡通信框架(Netty)和分布式消息隊列(Kafka)存儲框架實現,其具有實時性、高吞吐、通用性好等優點。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
【作者簡介】王小波,攜程技術中心框架研發部高級工程師,主要負責用戶行為數據采集系統及相關數據產品研發設計工作。之前主要從事互聯網廣告、RTB相關系統研發和設計工作。本文來自王小波在“攜程技術沙龍——移動開發工程實踐與性能優化”上的分享。
隨著移動互聯網的興起,特別是近年來,智能手機、pad等移動設備憑借便捷、高效的特點風靡全球,同時各類APP的快速發展進一步降低了移動互聯網的接入門檻,越來越多的網民開始從傳統PC轉移至移動終端上。但傳統的基于PC網站和訪問日志的用戶數據采集系統已經無法滿足實時分析用戶行為、實時統計流量屬性和基于位置服務(LBS)等方面的需求。
我們針對傳統用戶數據采集系統在實時性、吞吐量、終端覆蓋率等方面的不足,分析了在移動互聯網流量劇增的背景下,用戶數據采集系統的需求,研究在多種訪問終端和多種網絡類型的場景下,用戶數據實時、高效采集的方法,并在此基礎上設計和實現實時、有序和健壯的用戶數據采集系統。此系統基于Java NIO網絡通信框架(Netty)和分布式消息隊列(Kafka)存儲框架實現,其具有實時性、高吞吐、通用性好等優點。
1、技術選型和設計方案:
一個典型的數據采集分析統計平臺,對數據的處理,主要由如下五個步驟組成:
圖1、數據平臺處理流程
其中,數據采集步驟是最核心的問題,數據采集是否豐富、準確和實時,都直接影響整個數據分析平臺的應用的效果。本論文關注的步驟主要在數據采集、數據傳輸和數據建模存儲這三部分。
為滿足數據采集服務實時、高效性、高吞吐量和安全性等方面的要求,同時能借鑒互聯網大數據行業一些優秀開源的解決方案,所以整個系統都將基于Java技術棧進行設計和實現。整個數據采集分析平臺系統架構如下圖所示:
圖2(數據采集分析平臺系統架構)
其中整個平臺系統主要包括以上五部分:客戶端數據采集SDK以Http(s)/Tcp/Udp協議根據不同的網絡環境按一定策略將數據發送到Mechanic(UBT-Collector)服務器。服務器對采集的數據進行一系列處理之后將數據異步寫入Hermes(Kafka)分布式消息隊列系統。為了關聯業務服務端用戶業務操作埋點、日志,業務服務器需要獲取由客戶端SDK統一生成的用戶標識(C-GUID),然后業務服務器將用戶業務操作埋點、日志信息以異步方式寫入Hermes(Kafka)隊列。最后數據消費分析平臺,都從Hermes(Kafka)中消費采集數據,進行數據實時或者離線分析。其中Mechanic(UBT-Collector)系統還包括對采集數據和自身系統的監控,這些監控信息先寫入Hbase集群,然后通過Dashboard界面進行實時監控。
(1)基于NIO的Netty網絡框架方案
要滿足前面提到的高吞吐、高并發和多協議支持等方面的要求。我們調研了幾種開源異步IO網絡服務組件(如Netty、MINI、xSocket),用它們和NginxWeb服務器進行了性能對比,決定采用Netty作為采集服務網絡組件。下面對它進行一些概要介紹:Netty是一個高性能、異步事件驅動的NIO框架,它提供了對TCP、UDP和文件傳輸的支持,Netty的所有IO操作都是異步非阻塞的,通過Future-Listener機制,用戶可以方便的主動獲取或者通過通知機制獲得IO操作結果。
圖3(Netty框架內部組件邏輯結構)
Netty的優點有:
a、功能豐富,內置了多種數據編解碼功能、支持多種網絡協議。
b、高性能,通過與其它主流NIO網絡框架對比,它的綜合性能最佳。
c、可擴展性好,可通過它提供的ChannelHandler組件對網絡通信方面進行靈活擴展。
d、易用性,API使用簡單。
e、經過了許多商業應用的考驗,在互聯網、網絡游戲、大數據、電信軟件等眾多行業得到成功商用。
Netty采用了典型的三層網絡架構進行設計,邏輯架構圖如下:
圖4(Netty三層網絡邏輯架構)
第一層:Reactor通信調度層。該層的主要職責就是監聽網絡的連接和讀寫操作,負責將網絡層的數據讀取到內存緩沖區中,然后觸發各種網絡事件,例如連接創建、連接激活、讀事件、寫事件等,將這些事件觸發到Pipeline中,再由Pipeline充當的職責鏈來進行后續的處理。
第二層:職責鏈Pipeline層。負責事件在職責鏈中有序的向前(后)傳播,同時負責動態的編排職責鏈。Pipeline可以選擇監聽和處理自己關心的事件。
第三層:業務邏輯處理層,一般可分為兩類:a. 純粹的業務邏輯處理,例如日志、訂單處理。b. 應用層協議管理,例如HTTP(S)協議、FTP協議等。
我們都知道影響網絡服務通信性能的主要因素有:網絡I/O模型、線程(進程)調度模型和數據序列化方式。
在網絡I/O模型方面,Netty采用基于非阻塞I/O的實現,底層依賴的是JDKNIO框架的Selector。
在線程調度模型方面,Netty采用Reactor線程模型。常用的Reactor線程模型有三種,分別是:
a、Reactor單線程模型:Reactor單線程模型,指的是所有的I/O操作都在同一個NIO線程上面完成。對于一些小容量應用場景,可以使用單線程模型。
b、Reactor多線程模型:Rector多線程模型與單線程模型最大的區別就是有一組NIO線程處理I/O操作。主要用于高并發、大業務量場景。
c、主從Reactor多線程模型:主從Reactor線程模型的特點是服務端用于接收客戶端連接的不再是一個單獨的NIO線程,而是一個獨立的NIO線程池。利用主從NIO線程模型,可以解決一個服務端監聽線程無法有效處理所有客戶端連接的性能不足問題。Netty線程模型并非固定不變的,它可以支持三種Reactor線程模型。
在數據序列化方面,影響序列化性能的主要因素有:
a、序列化后的碼流大?。ňW絡帶寬占用)。
b、序列化和反序列化操作的性能(CPU資源占用)。
c、并發調用時的性能表現:穩定性、線性增長等。
Netty默認提供了對GoogleProtobuf二進制序列化框架的支持,但通過擴展Netty的編解碼接口,可以實現其它的高性能序列化框架,例如Avro、Thrift的壓縮二進制編解碼框架。
通過對Netty網絡框架的分析研究以及對比測試(見后面的可行性分析測試報告)可判斷,基于Netty的數據采集方案能解決高數據吞吐量和數據實時收集的難點。
(2)客戶端數據加解密和壓縮方案
對一些明感的采集數據,需要在數據傳輸過程中進行加密處理。目前存在的問題是,客戶端采集代碼比較容易被匿名用戶獲取并反編譯(例如Android、JavaScript),導致數據加密的算法和密鑰被用戶竊取,較難保證數據的安全性。根據加密結果是否可以被解密,算法可以分為可逆加密和不可逆加密(單向加密)。具體的分類結構如下:
圖5(加密算法分類)
密鑰:對于可逆加密,密鑰是加密解算法中的一個參數,對稱加密對應的加解密密鑰是相同的;非對稱加密對應的密鑰分為公鑰和私鑰,公鑰用于加密,私鑰用于解密。私鑰是不公開不傳送的,僅僅由通信雙方持有保留;而公鑰是可以公開傳送的。非對稱密鑰還提供一種功能,即數字簽名。通過私鑰進行簽名,公鑰進行認證,達到身份認證的目的。
根據數據采集客戶端的特點,對于采集數據使用對稱加密算法是很明智的選擇,關鍵是要保證對稱密鑰的安全性。目前考慮的方案主要有:
a、將加解密密鑰放入APP中某些編譯好的so文件中,如果是JavaScript采集的話,構造一個用C編寫的算法用于生成密鑰,然后借助Emscripten把C代碼轉化為JavaScript代碼,這種方案有較好的混淆作用,讓竊聽者不太容易獲取到對稱密鑰。
b、將密鑰保存到服務器端,每次發送數據前,通過HTTPS的方式獲取加密密鑰,然后對采集數據進行加密和發送。
c、客戶端和服務器端保存一份公鑰,客戶端生成一個對稱密鑰K(具有隨機性和時效性),使用公鑰加密客戶端通信認證內容(UID+K),并發送到服務器端,服務端收到通信認證請求,使用私鑰進行解密,獲取到UID和對稱密鑰K,后面每次采集的數據都用客戶端內存中的K進行加密,服務器端根據UID找到對應的對稱密鑰K,進行數據解密。
這三種客戶端數據加密方式基本能解決客戶端采集數據傳輸的安全性難題。
采集數據壓縮。為了節省流量和帶寬,高效發送客戶端采集的數據,需要使用快速且高壓縮比的壓縮算法,目前考慮使用標準的GZIP和定制的LZ77算法。
(3)基于攜程分布式消息中間件Hermes的數據存儲方案
Hermes是基于開源的消息中間件Kafka且由攜程自主設計研發。整體架構如圖:
圖6(Hermes消息隊列整體架構)
Hermes消息隊列存儲有三種類型:
a、MySQL適用于消息量中等及以下,對消息治理有較高要求的場景。
b、Kafka適用于消息量大的場景。
c、Broker分布式文件存儲(擴展Kafka、定制存儲功能)。
由于數據采集服務的消息量非常大,所以采集數據需要存儲到Kafka中。Kafka是一種分布式的,基于發布/訂閱的消息系統。它能滿足采集服務高吞吐量、高并發和實時數據分析的要求。它有如下優秀的特性:
a、以時間復雜度為O(1)的方式提供消息持久化能力,即使對TB級以上數據也能保證常數時間復雜度的訪問性能。
b、高吞吐率。即使在非常廉價的商用機器上也能做到單機支持每秒100K條以上消息的傳輸。
c、支持Kafka Server間的消息分區,及分布式消費,同時保證每個Partition內的消息順序傳輸。
d、同時支持離線數據處理和實時數據處理。
e、Scale out,即支持在線水平擴展。
一個典型的Kafka集群中包含若干Producer(可以是Web前端產生的采集數據,或者是服務器日志,系統CPU、Memory等),若干broker(Kafka支持水平擴展,一般broker數量越多,集群吞吐率越高),若干ConsumerGroup,以及一Zookeeper集群。Kafka通過Zookeeper管理集群配置,選舉leader,以及在Consumer Group發生變化時進行rebalance。Producer使用push模式將消息發布到broker,Consumer使用pull模式從broker訂閱并消費消息。Kafka拓撲結構圖如下:
圖7(Kafka拓撲結構)
我們知道,客戶端用戶數據的有序性采集和存儲對后面的數據消費和分析非常的重要,但是在一個分布式環境下,要保證消息的有序性是非常困難的,而Kafka消息隊列雖然不能保證消息的全局有序性,但能保證每一個Partition內的消息是有序的。在用戶數據采集和分析的系統中,我們主要關注的是同一個用戶的數據是否能保證有序,如果我們在數據采集服務端能將同一個用戶的數據存儲到Kafka的同一個Partition中,那么就能保證同一個用戶的數據是有序的,因此基本上能解決采集數據的有序性。
(4)基于Avro格式的數據災備存儲方案
當出現網絡嚴重中斷或者Hermes(Kafka)消息隊列故障情況下,用戶數據需要進行災備存儲,目前考慮的方案是基于Avro格式的本地文件存儲。其中Avro是一個數據序列化反序列化框架,它可以將數據結構或對象轉化成便于存儲或傳輸的格式,Avro設計之初就用來支持數據密集型應用,適合于遠程或本地大規模數據的存儲和交換。
Avro定義了一個簡單的對象容器文件格式。一個文件對應一個模式,所有存儲在文件中的對象都是根據模式寫入的。對象按照塊進行存儲,在塊之間采用了同步記號,塊可以采用壓縮的方式存儲。一個文件由兩部分組成:文件頭和一個或者多個文件數據塊。其存儲結構如下圖所示:
圖8(Avro對象容器文件格式)
災備存儲處理過程是:當網絡異?;蛘逪ermes(Kafka)消息隊列出現故障時,將采集的用戶數據解析并轉化成Avro格式后,直接序列化存儲到本地磁盤文件中,數據按Kafka-Topic分成多個文件存儲,且每小時自動生成一個新的文件。當網絡或者Hermes(Kafka)故障恢復后,后端線程自動讀取磁盤Avro文件,將數據寫入Hermes(Kafka)消息隊列的對應Topic和分區中。每個文件寫入成功后,自動刪除災備存儲文件。這樣能增加用戶數據采集服務的健壯性和增強服務容錯性。
2、架構設計方案可行性分析
在相同配置的測試服務器上(包括數據采集服務器、Hermes(Kafka)集群)做如下對比實驗測試:(使用ApacheBenchmark進行Web性能壓力測試工具)
(1)Netty VS Nginx處理網絡請求對比
在不對采集數據進行業務處理的情況下(即只接請求并做響應,不做業務處理,也不存儲采集數據),在5000并發,Keepalive模式下均能達到每秒處理4萬多請求,其中Nginx的CPU、內存消耗會小一些。測試對比數據如下:(ab參數: -k –n 10000000 –c 5000)
(2)Netty對采集數據進行業務處理
Netty服務加上采集數據解析相關業務處理,以及處理后的數據寫入Hermes(Kafka)消息隊列??梢赃M行簡單的間接估算。如果采集服務要求達到:每秒處理3萬左右請求,99%的請求完成時間小于800ms的目標,則采集數據解析和存儲流程的處理時間必須在600ms以內。而這兩步又分為數據解析和數據存儲,可以分別進行壓力測試加以驗證。根據我們的壓力測試,采集數據解析和存儲也能完全滿足性能要求。
經以上對比實驗測試表明,使用Netty服務組件收集、解析數據并直接寫入Hermes(Kafka)分布式消息隊列的方案初步具備可行性。
基于實時采集到的用戶數據和系統監控數據,我們開發了一套相關的數據分析產品。產品的內容主要分以下幾部分:(1)、API和頁面性能報表;(2)、頁面訪問和流量;(3)、用戶行為分析;(4)、系統異常崩潰分析;(5)、數據實時查詢工具;(6)、采集數據排障工具;(7)、其它。其中詳細分類如下圖所示:
圖9(數據分析產品分類)
現選取其中幾個比較常見的產品做下簡單介紹:
1、單用戶瀏覽跟蹤
作用:實時跟蹤用戶瀏覽記錄,幫助產品優化頁面訪問流程、幫助用戶排障定位問題。
使用案例:根據用戶在客戶端上的唯一標識ID,如:手機號、Email、注冊用戶名、ClientId、VisitorId等查詢此用戶在某一時間段順序瀏覽過的頁面和每個頁面的訪問時間及頁面停留時長等信息。如果用戶在瀏覽頁面過程中發生了異常崩潰退出情況,可以結合應用崩潰信息關聯查詢到相關信息。
2、頁面轉化率
作用:實時查看各個頁面的訪問量和轉化情況,幫助分析頁面用戶體驗以及頁面布局問題。
使用案例:用戶首先配置頁面瀏覽路徑,如p1023-> p1201 -> p1137 -> p1300,然后根據用戶配置頁面瀏覽路徑查詢某個時間段各個頁面的轉化率情況。如有1.4萬用戶進入p1023頁面,下一步有1400用戶進入下一頁面p1201。這樣可推算出頁面p1201的轉化率為10%左右。這是最簡單的一種頁面轉化率,還有間接的頁面轉化率,即只匹配第一個和最后一個頁面的訪問量。同時可以按各種維度進行條件篩選,比如:網絡、運營商、國家、地區、城市、設備、操作系統等等。
3、用戶訪問流
作用:了解每個頁面的相對用戶量、各個頁面間的相對流量和退出率、了解各維度下頁面的相對流量。
使用案例:用戶選擇查詢維度和時間段進行查詢,就能獲取到應用從第一個頁面到第N個頁面的訪問路徑中,每個頁面的訪問量和獨立用戶會話數、每個頁面的用戶流向、每個頁面的用戶流失量等信息。
4、點擊熱力圖
作用:發現用戶經常點擊的模塊或者區域,判斷用戶喜好、分析頁面中哪些區域或者模塊有較高的有效點擊數、應用于A/B測試,比較不同頁面的點擊分布情況、幫助改進頁面交互和用戶體驗。
使用案例:點擊熱力圖查看工具包括Web和APP端,統計的指標包括:原始點擊數(當前選中元素的原始點擊總數)、頁面瀏覽點擊數(當前選中元素的有效點擊數,同一次頁面瀏覽,多次點擊累計算1次點擊)、獨立訪客點擊數(當前選中元素的有效點擊數,同一用戶,多次點擊累計算1次點擊)。
5、采集數據驗證測試
作用:快速測試是否能正常采集數據、數據量是否正常、采集的數據是否滿足需求等。
使用案例:用戶使用攜程APP掃描工具頁面的二維碼,獲取用戶標識信息,之后正常使用攜程APP過程中,能實時地將采集到的數據分類展示在工具頁面中,對數據進行對比測試驗證。
6、系統性能報表
作用:監控系統各業務服務調用性能(如SOA服務、RPC調用等)、頁面加載性能、APP啟動時間、LBS定位服務、Native-Crash占比、JavaScript錯誤占比等。按小時統計各服務調用耗時、成功率、調用次數等報表信息。
基于前端多平臺(包括iOS、Android、Web、Hybrid、RN、小程序)數據采集SDK的豐富的自動化埋點數據,我們可以對數據、用戶、系統三方面進行多維度立體的分析。服務于系統產品和用戶體驗、用戶留存、轉換率及吸引新用戶。
本文轉載自:36大數據
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn