轉自: http://www.csdn.net/article/2015-10-20/2825962算法
【CSDN現場報道】10月14日-16日,「 2015移動開發者大會 · 中國」 (Mobile Developer Conference China 2015,簡稱MDCC 2015)在北京新雲南皇冠假日酒店隆重舉行。本次大會由全球最大中文IT社區CSDN和中國最具關注度的全方位創業平臺創新工場聯合主辦,以「萬物互 聯,移動爲先」爲主題,邀請國內外業界領袖與技術專家共論移動開發的熱點,在實踐中剖析技術方案與趨勢。數據庫
友盟數據平臺負責人 吳磊緩存
移 動互聯網的無處不在催熟了大數據平臺,而中國互聯網正在面臨從IT時代到DT時代的變革,移動互聯網與大數據幾乎是一種相生相伴的關係。迴歸到App研 發,到後期尤爲須要數據與運營。友盟從2010年開始就專一於移動大數據,5年來不只積累了大量的數據,並且擁有着豐富的技術與經驗,那麼,友盟大數據平 臺有着怎樣的架構與實踐?今天在這裏與你們分享一下。服務器
友盟架構主要參考了Twitter提出的Lambda架構思想。如上圖所示,最下面是快速處理層,新增數據在快速處理層計算,這部分數據比較小,能夠快速完成,生成實時視圖。同時,新增數據會併入全量數據集,進行批處理,生成批處理視圖。這樣,系統同時具備了低延遲實時處理能力,也具備離線大數據處理能力。以後經過數據服務層,把兩個視圖合併起來,對外提供服務。網絡
根 據友盟的業務特色,數據平臺由下向上分紅這幾個部分:最基礎的是日誌收集,接下來進入離線計算和實時分析,計算後的結果,會進行數據挖掘,有價值的數據進 入數據倉庫。接下來會提供一個基於REST Service的數據服務,在此服務之上作各類數據應用,例如:報表、數據分析報告、數據下載等。兩邊的部分提供輔助的功能,包括任務調度和監控管理。架構
結 合友盟的業務架構和Lambda架構思想,最終的系統以下圖所示:最左邊是數據採集層,友盟提供手機、平板、盒子的SDK給App集成,App經過SDK 發送日誌到友盟平臺;首先進入到Nginx,負載均衡以後傳給基於finagle框架的日誌接收器,接着來到數據接入層。併發
數 據接入層讓Kalfka集羣承擔,後面由Storm消費,存儲在MongoDB裏面,經過Kafka自帶的Mirror功能同步,兩個Kafka集羣,可 以分離負載;計算有離線和實時兩部分,實時是Storm,離線是Hadoop,數據挖掘用Hive,分析任務,正在從Pig遷移到Spark平臺,大量的 數據經過計算以後,存儲在HFDS上,最後存儲在HBase裏面,經過ES來提供多級索引,以彌補HBase二級索引的缺失。負載均衡
通 過以上的介紹,你們可能對整個大數據平臺的結構和概念有了初步的瞭解。正如Linux之父Linus Torvalds的名言——「Talk is cheap, show me the code!」同樣,其實知道是相對容易的,難的是如何去實現。因此接下來,我給你們分享一些友盟在實踐中獲得的一些經驗。框架
首先是從數據採集來講起,數據採集部分面臨了很大的挑戰,首當其衝即是大流量、高併發和擴展性。友盟的數據平臺經歷了一個發展的過程。在2010年剛開始的時候,由於快速上線的要求,咱們是基於RoR開發的,在後臺經過Resque進行一些離線的處理。這個架構,隨着互聯網的爆發,面臨巨大的數據壓力,很快就不能適用了。運維
接 下來,咱們就切換到基於Finagle Server的日誌服務器。這個Finagle Server是Twitter開源出來的一個異步服務器框架,很適合移動互聯網的訪問特色:高併發、小數據量。切換到Finagle Server以後,單臺服務器的處理能力獲得了極大的提高。同時日誌收集服務的無狀態特性能夠支持橫向擴展,因此當面臨很是高壓力的時候能夠簡單地經過增 加臨時服務器來解決。
大數據的特色之一是數據多樣化,若是不進行清洗會對後面的計算產生困擾。在數據清洗方面,咱們花了不少精力,並踩了不少的坑。
作數據分析,第一件事情就是要拿到「惟一標識」。Android系統裏做爲惟一標識的,經常使用的是IMEI、MAC、Android ID。首先,由於Android碎片化問題,經過API在採集這些數據的時候,經常會有采集不到的狀況。
還 有其餘一些異常的狀況,好比有不少山寨機沒有合法的IMEI,因此會不少機器共用一個IMEI,致使IMEI重複;有些ROM刷機後會更改MAC地址,導 致MAC重複;大部分電視盒子自己就沒有IMEI。這種狀況下咱們單純用IMEI或者MAC,或者Android ID ,來進行標識的話,就會出現問題。
對此,咱們採用的辦法是由單獨的服務來統一計算。後臺會有離線任務來進行計算,發現重複率很高的標識符,加入到黑名單裏。在計算的時候,直接跳過黑名單裏的標識,換用另外一種算法進行計算。
咱們在「數據標準化」方面也遭遇過不少坑,好比:「設備型號」,並非直接採集model個字段就能夠解決的。拿小米3舉例,這個手機會有不少版本,不一樣的批次model字段不同。對於這種狀況,若是不進行統一標準化,算出來的結果確定有問題。
此外,還會出現多機一型的狀況,例如m1,在2011發佈的三年後活躍設備數量發生突增。調查發現,原來是其對手廠家在2014年末生產了一款暢銷的產品,model字段也叫m1。所以,咱們就須要把設備型號,經過專門手段來和產品名稱對應上,統一標準化。
在數據標準化過程當中,還會遇到「地域識別」的問題。地域識別是用IP地址來識別的。由於中國IP地址管理並非很是規範,因此常常會出現,上一秒鐘你們還在北京,下一秒就到深圳的狀況。對於解決這樣的問題,咱們是選用設備一天中最常出現的IP地址做爲當天的地域標識。
還 有「時間識別」,也是很大的問題。最開始咱們採用的都是客戶端時間。可是客戶時間有很大的隨意性,用戶的一個錯誤設置,就會致使時間不一致;另一些山寨 機會有Bug,機器重啓以後,時間直接就變成1970年1月1號了;還有一種可能,產生數據的時候沒有網絡鏈接,在從新聯網時日誌纔會彙報到平臺,這樣的 話數據就會產生延遲。
爲了解決這些時間不一致的問題,咱們統一使用服務器端時間。可是這樣又帶來了新的問題:統計時間和真實時間的差別,可是這個差別值是從小時間窗口(例如一個小時,或一天)觀察出來的,從大的時間窗口來看是正確的。
友盟SDK通過不少版的進化,上報上來的日誌會有多種格式。早期時採用JSON格式,後期則使用Thrift的格式。在數據平臺處理的時候,兩種格式切換很麻煩,所以在處理以前,咱們把它統一成 Protobuf ,來進行後期計算。
在數據計算的時候,根據不一樣業務對於時延的容忍程度的高低,分爲實時計算,離線計算和準實時計算。
實 時計算,面臨的挑戰之一是時效性。由於實時計算是對延時很是敏感的,毫秒級的水平。若是說你把不合適的計算,好比一些很耗CPU的計算放進來,會直接致使 實時計算的延遲。因此在架構時,須要考量把哪些放到實時部分合適,哪些不適合。另外,實時計算每每會在寫數據庫時產生IO延遲,須要對實時數據庫進行專門 優化。對此,咱們在實時計算部分選用了MongoDB存儲數據,同時不斷優化MongoDB的寫請求來解決這個問題。
另一個挑戰是突發流量。用戶使用App的頻率並不均勻,早中晚會有很高的使用率,尤爲是晚上10:00-12:00這個時間段會對咱們系統帶來很是大的壓力,得益於以前的架構設計,在達到必定的閾值以後,會觸發報警,運維的同窗會進行臨時擴容來應對這些突發流量。
因 爲實時計算一般是增量計算,會產生偏差積累的問題。Lambda架構決定了實時和離線是兩套獨立的計算系統,因此必然會出現偏差。若是長時間使用實時計算 的結果,這個偏差會愈來愈大。如今解決的辦法是在實時處理時,不要給太大的時間窗口,好比說最多不要超過一天,超過一天以後,就要開始清理,離線部分的計 算天天計算一次,保證在這個時候離線部分的數據計算完成,這樣就能夠用離線的數據來覆蓋實時數據,從而消除這個數據偏差。
離線計算,也會面臨一些問題。最常遇到的麻煩是數據傾斜問題。數據傾斜這個事情,幾乎是自然存在的,好比說一些大App的數據量,和小App的數據量存在着巨大的差距,經常會在離線計算的時候產生長尾現象,並行的MR做業中老是有一兩個任務拖後腿,甚至超出單機計算能力。
產 生數據傾斜的緣由有不少種,針對不一樣的緣由,有不一樣的解決辦法。最多見的緣由是由於粒度劃分太粗致使的,好比說咱們計算的時候,若是以App ID來進行分區,很容易致使數據傾斜。針對這種狀況,友盟的解決辦法的是進行更細一步的劃分,好比經過App ID加設備ID進行分區,而後再將結果聚合起來,這樣就能夠減小數據傾斜的發生。
第二個問題是數據壓縮的問題。離線計算的時候,每每輸入輸出都會很大,所以咱們要注意時時刻刻進行壓縮,用消耗CPU時間來換取存儲空間的節省。這樣作可以節省數據傳輸中的IO延遲,反而可以下降整個任務的完成時間。
接下來會面臨資源調度的困難,由於各類任務優先級是不同的,好比一些關鍵的指標,要在特定時間算出來,有些任務則是早幾個小時均可以。Hadoop自帶的調度器不管是公平調度仍是能力調度器都不能實現咱們的需求,咱們是經過修改Hadoop的度器代碼來實現的。
另 外還有一類任務對時延比較敏感,可是又不適合放到實時計算中的。這類任務咱們稱之爲準實時任務。例如報表的下載服務,由於是IO密集型任務,放入實時不太 合適,可是它又對時間比較敏感,可能用戶等三五分鐘仍是能夠接受的,可是等一兩個小時就很難接受了。對於這些準實時任務咱們以前採用的是經過預留必定資源 來運行MR來實現的。如今用Spark Streaming專門來作這些事情。
在進行準實時計算時,裏面也有一個資源佔用的問題,在預留的過程當中,會致使你的資源佔用率太低,如何平衡是個問題;第二點不少實時計算的任務,每每也採用了增量計算模式,須要解決增量計算的偏差累計問題,咱們經過必定時間的全量計算來彌補這個缺陷。
數 據存儲,根據咱們以前的計算模式,也分爲在線存儲和離線存儲兩部分。在實時部分的計算結果主要存在MongoDB裏面,必須對寫IO進行優化。離線數據計 算結果通常存儲在HBase裏。可是HBase缺乏二級索引。咱們引入了Elastic Search,來幫助HBase進行索引相關的工做。
在 作數據服務的時候經過數據緩存可以解決數據冷熱的問題。友盟數據緩存用的是Redis,同時使用了TwemProxy來做負載均衡。友盟在數據緩存這方面 的經驗就是須要預加數據,好比:天天凌晨計算完數據以後,在用戶真正訪問以前,須要把部分計算結果預先加載上去,這樣等到用戶訪問的時候,就已經在內存裏 了。
整個大數據的系統,價值最大的部分,就在於數據增值,友盟目前數據增值主要分兩個大的方向。首先是內部數據打通,基於用戶事件,結合用戶畫像、以及和阿里百川合做提供更多的維度信息,來爲開發者提供更精準的推送。好比,對一個汽車電商類App,能夠圈定一部分有車的用戶來推送汽車配件相關信息,而後圈定一部分無車用戶來推送售車相關信息。
此外,在數據挖掘方面也作了不少工做。針對現有的設備,進行用戶畫像相關計算,經過用戶畫像可以瞭解用戶的屬性和興趣,方便後續的數據橫向打通。同時,還針對一些做弊行爲設計提供了設備評級產品。
經過數據平臺的統計算法和機器學習算法,把現有的全部設備進行評級,哪些是垃圾設備,哪些是真實設備,可以很好的識別出來。這樣一來,若是開發者有相關需求,咱們能夠提供設備評級相關指標,來幫助開發者測評這些推廣渠道,到底哪些可信,哪些不可信。
更多精彩內容,請關注新浪微博:@CSDN移動,圖文直播專題:2015移動開發者大會。