接近淘寶 80%的大數(shù)據(jù)實時計算平臺,從0搭建的經(jīng)驗和坑

上周一,來自武漢的直播平臺斗魚TV宣布C輪融資,騰訊領投的 15 億人民幣,距其獲得 B 輪1億美元不到半年,也是大寫的牛逼。

但小尋更關心他們的大數(shù)據(jù)架構,作為一個在 2 年多時間里崛起的公司,其流量經(jīng)歷了從 0 到 PB 級別的飛躍。

剛好今年 3月,斗魚的大數(shù)據(jù)團隊負責人參加過簡尋主辦的首屆武漢開發(fā)者峰會,分享了一些經(jīng)驗和坑,結合一些資料,小尋整理了這個帖子,供有志于大數(shù)據(jù)的同學參考和借鑒。

438218194319244192.jpg

關于吳瑞誠:2014年加入斗魚,成為斗魚大數(shù)據(jù)團隊第一人,經(jīng)歷了斗魚的用戶從 十萬級別大千萬級別的飛躍,并從0 搭建了斗魚的大數(shù)據(jù)實時計算平臺。入職斗魚前,我吳瑞誠在淘寶干過三年,主要做HBase。

QQ截圖20160820143353.png

這是斗魚非常典型的直播間,55開,游戲打得好,牛吹得好,在斗魚比較好,大家看到密密麻麻的字,就是彈幕,視頻直播最火的場景,彈幕。很火的時候,上面會有禮物,用戶給主播贈送火箭,鯊魚騎著火箭的禮物飄過,這個火箭價值還挺高。

右下角這些圖標是禮物,用戶贈送給主播的禮物,魚翅可以充值購買,魚丸贈送,右邊是土豪的貢獻排行榜,貢獻越多排名越高,右邊是彈幕區(qū)。內(nèi)容和形態(tài)就是這樣,但是現(xiàn)在很火,有時候我們沒辦法預料現(xiàn)象級現(xiàn)象。

主要分享內(nèi)容

第一,日志檢索,日志全局檢索。后面會展開,這個地方主要是以NginxPHP日志做事例。

第二,實時CEP系統(tǒng),類KV的處理系統(tǒng)。

第三,實時流計算,流計算。 strong text

一、日志檢索

QQ截圖20160820183004.png

這是一個現(xiàn)在的大數(shù)據(jù)的架構圖,這個圖最近才整理出來,越整就覺得體會越深,這個圖里面看一下紅紅綠綠有一些方塊,看PPT看得多的同學,可能司空見慣了,大數(shù)據(jù)架構圖到最后可能都是這個樣子,但是圖上的每一個塊都是踩過無數(shù)個坑,付出了血的教訓才成為現(xiàn)在這樣。

我加入斗魚,當時是一個人負責整個這一大塊的東西,后來就是因為網(wǎng)站量上來了,個人吞吐量到了上限,招了第一批人。我第一批是組內(nèi)培養(yǎng)的,會有一些java開發(fā),生拉硬拽湊到大數(shù)據(jù)團隊,從最開始的小系統(tǒng)越做越大,做到現(xiàn)在這個架構。

最下面一層是數(shù)據(jù)源一層,Nginx、PHP日志,公司技術棧比較多,處理起來會越來越蛋疼,現(xiàn)在統(tǒng)一接入層是是Kafka,現(xiàn)在還沒有完全接入。

上面一層就是數(shù)據(jù)清洗和格式轉換包括初步的結算。

再上面一層就包括依賴MySQL實現(xiàn)的歸檔數(shù)據(jù),最大一塊是離線計算基于Hadoop,YARN。去年上線Spark,現(xiàn)在應用的范圍還比較小,主要還是在風控和個性推薦這一塊。

另外實時計算是Hbase,是之前經(jīng)驗比較熟悉,Hbase大家覺得有很多替代的產(chǎn)品,我覺得Hbase在第一層兜住海量熱數(shù)據(jù),我覺得Hbase的優(yōu)勢還是非常明顯的。所以我這一塊一直會保持Hbase在這個地方使用,在快速查詢,可以相對于自助查詢走的presto。

右側實時計算主要基于Storm,今年大目標把spark作為重點引入。對于新框架的考量,小公司二次的開發(fā)能力或者定制能力弱一些,我們現(xiàn)在主要應用短平快的一些方式,比如,主流的有一些大公司BAT、京東、美團把坑踩完了我們再上,這樣我們成本會小很多,我們會跟進spark,spark社區(qū)活躍得讓人沒辦法忽視它,它現(xiàn)在活躍程度比Hadoop強一個量級。

最右邊是Elastic,最開始引入的時候只是做一個搜索引擎,后來越用越覺得爽,真的是一個神器,后面會具體展開。

再就是上面的服務數(shù)據(jù)層,前端網(wǎng)站和服務層使用,再就是Dashboard,監(jiān)控、個性推薦、用戶行為分析、風控系統(tǒng)、搜索引擎、其它數(shù)據(jù)應用。

平臺監(jiān)控非常重要。

a2mQZzj_副本.jpg

這是Lambda架構,這三層架構,P處理層,再是上面的加速層到服務層,這三層架構,應該可以覆蓋絕大多數(shù)的大數(shù)據(jù)團隊架構的場景。

實時日志檢索

從前:grep + awk

演進:rsync + Hive UDF

現(xiàn)在:ELK

我們最開始,只有幾個PHP實例,出了問題,我就上去grep、awk,然后規(guī)模上來了,機器和應用實例突增,就用rsync和HiveUDF的方式,把日志收集起來,按照時間粒度切碎了拖過來,然后用Hive進行一些匹配,形成這么一個非常初級的系統(tǒng)。

到了現(xiàn)在,ELK,用的很爽的系統(tǒng),能支持的量很大,可擴展,全文檢索,很多時候包括技術團隊定位問題非常方便,有這幾個特性能滿足基本使用。如果再能夠幫他們做一些告警,包括量的告警,文本的告警,有更好,這也是我們現(xiàn)在在做的。

3.png

這是實時日志檢索的架構圖,大家可以看到應用場景,當時flume用得最多,應用場景變得比較快,我們的業(yè)務調(diào)整也非常迅猛,新場景中發(fā)現(xiàn)flume有兩個場景沒辦法滿足,一個場景是C++場景,它的量太大,他們的日志按實例文件夾寫本地;一個是,Java太耗資源,包括CPU、包括內(nèi)存,后來我們覺得這一塊要做一些改變。

最開始的方案,因為我們有C++的團隊做服務化,他們覺得我們可以自己造輪子,這個輪子比較簡單,后來我做了一圈對比,發(fā)現(xiàn)Logstash新版本中,有一個Beats組件,是golang實現(xiàn)的。

架構圖中間以Elastic技術棧為主,包括中間匯聚層在不久將來會被替換掉,但是現(xiàn)有的一些場景,如果一直穩(wěn)定的話先保持現(xiàn)狀。因為我們在這個階段它比較穩(wěn)定。

Flume 的Memory channel在量大的時候會OOM,這個時候把溢出的量落地到disk上面,這樣可以在保證效率的同時能增大Flume能承受的吞吐量,這樣讓flume很穩(wěn)定,一直沿用到現(xiàn)在。

現(xiàn)在還是用Flume做了匯聚層,我們后續(xù)會使用Kafka做匯聚層,有很多場景,有些日志可能回頭還要再消費或者說要做Pub-sub,現(xiàn)在模式很難實現(xiàn),必須要用到Kafka。

日志數(shù)據(jù)在圖的下方走了Elastic,用Kibana做的UI,Kibana 2.0以后使用上會有很多不順暢,我這一塊其實建議大家二次開發(fā),二次開發(fā)的成本不大,比較容易上手,所有的接口都可以走API,定制起來方便,圖上方是走的Hdfs出報表。

FLUME

選項

Channel

Flume 監(jiān)控

再說一下踩過的一些坑。

首先Flume的選型。我最開始看中還是因為他是Apache的產(chǎn)品,覺得它穩(wěn)定,在很多公司PPT里面,我稍微估計一下,flume出現(xiàn)的概率比其它產(chǎn)品出現(xiàn)頻率高很多,所以做一些壓測做了對比,差不太多,就選了flume,現(xiàn)在要新用或者要換型需要更詳細的壓測。

channel這一塊,最開始內(nèi)存到disk到現(xiàn)在兩個方案混搭在一起,但是占資源特別耗資源。

flume的監(jiān)控,一定要先考慮監(jiān)控再上新的技術棧。

ERK

  • ES vs Solr

  • ES 插件:KOPF集群監(jiān)控:hesd 索引操作;

  • ES 讀寫分離

  • 獨立小集群解決慢查詢;

  • 避免索引過大

  • 最熱的查詢中避免使用 Range 查詢;

  • JVM heapsize 設置;

  • CMS vs G1

在Elastic上,我們跟Solr做對比,大家可以看一下純開源的組建跟有商業(yè)團隊支撐的開源產(chǎn)品,社區(qū)活躍度和產(chǎn)品迭代不是在一個量級上,Elastic現(xiàn)在已經(jīng)開始注重使用體驗了,這一點是Solr還沒有納入考量的點。

因為Elastic除了我們最開始最傳統(tǒng)的搜索引擎、文本搜索,現(xiàn)在更大的一塊可以當作我們的多維自助查詢,水平擴展能力非常強,因為數(shù)據(jù)結構的天熱優(yōu)勢,就有一些場景,包括多維的及時查詢這一塊有非常強悍的性能。

ES插件上,我們使用了Kopf做監(jiān)控,head來操作索引。

ES讀寫分離。ES集群拓撲越來越大,如果按照默認的拓撲來使用的話,可能量上沒法滿足很多場景,比如,如果讀寫不做分離,查詢極有可能把線上寫的節(jié)點直接壓垮,這樣就建議有一個專門的節(jié)點來負責讀。

對于資源隔離,我們使用了幾個小的Elastic的集群來滿足各個功能。因為,Elastic是P2P的,無主。無主有一個問題,有時候沒有辦法很強的控制某些節(jié)點行為,這時候要做一些隔離,最見效的方式就是按照小集群直接做隔離。

避免索引過大。這一點大家如果能注意把不必要的字段建到索引能解決大部分。

最熱的查詢中避免用range查詢。

JVM heapsize設置,我們現(xiàn)在一直使用32G,Hbase集群也是這樣,盡管集群配置很高,Hbase的配置還是32G。

GC方面,我們使用的是CMS,在線上使用、壓測表現(xiàn)看的話,G1穩(wěn)定性和用戶體驗看來都會差一些。

二、實時CEP系統(tǒng)

  • 從前: Redis

  • 演進:HBase

  • 現(xiàn)在:TSDB

最開始我們做一個指標統(tǒng)計,大家把數(shù)據(jù)推到我們這邊來做一些統(tǒng)計,然后借助redis做統(tǒng)計并最后把結果數(shù)據(jù)保存在Redis,簡單的統(tǒng)計場景OK了,后來業(yè)務場景復雜了,產(chǎn)品線多了,redis單個實例肯定不夠,可擴展性和數(shù)據(jù)規(guī)模是redis暫時無法越過的門檻,所以我們又很自然用到了Hbase。

Hbase使用有兩大點需要注意:

第一,rowkey的設計,Hbase中除了rowkey沒有索引可供使用。

第二,數(shù)據(jù)壓縮,歷史數(shù)據(jù)的壓縮很關鍵。一個指標兩個指標做抽樣做一些歸檔很好做,但是怎么做到統(tǒng)一,而且還很簡單,我們能直接拿來用,這個時候碰到open TSDB,一個時間序列存儲方案。

最開始也用了InfluxDB,感覺有時候只要壓力上來了之后,它可以沒有征兆掛機,后來干脆就考慮到open TSDB。數(shù)據(jù)揣拽產(chǎn)生圖形,基于OpenTSDB,能滿足很大的量。

這個系統(tǒng)中真正性能考驗的其實還是Hbase,Hbase OK,opentTSDB也就沒有問題,我們會一直把這個方案做下去,基于open TSDB,我們可以很靈活做定制,它本身就是基于Hbase做了定制的特性,包括我剛剛說到對rowkey的設計。

對數(shù)據(jù)壓縮,每一個指標每一個小時會有一個row,open TSDB幫我們做了。后面有定制需求我們從頭開始做,這一塊是比較簡單的,底層Hbase性能是沒有問題,越往后看,Hbase有很多地方它會做得越來越通用。因為它的性能這一塊顯性能沒有問題,后面卡頓的問題會有明顯的提升。

4.png

回到剛剛上面的圖這是CEP系統(tǒng),這個圖上面,大家可以看一下。

從數(shù)據(jù)收集,第一個parser會走到Kafka,從spark走到Hbase,走到這一步就走到了業(yè)務系統(tǒng),包括我們的監(jiān)控系統(tǒng),這是有一個業(yè)務流程,現(xiàn)在可以簡單理解成某些指標大于閾值就覺得它的是一個嫌疑事件,需要告警的,簡單理解就是這樣,這一塊馬上引入規(guī)則引擎,這一塊業(yè)務變化頻率太快了,發(fā)布速度拖了后腿,在已經(jīng)測試上了。

到后面有一些結果的存儲,再有告警的推送,這個地方也是直接走到Hbase。后面有一些統(tǒng)計好的指標可以拿來用的,這個地方我們走到了open TSDB,這個圖就沒有重新再畫,直接從Cloudera Blog上面借用,這個架構圖和我們的系統(tǒng)是一模一樣的。

  • 關于 Open TSDB:

  • 周期 IO 波動問題:①禁用 OpenTSDB 的Compation機制;②數(shù)據(jù)壓縮過速度

Open TSDB,業(yè)務指標非常靈活,我們現(xiàn)在有一些CPU指標,打出來我們收集起來,各個指標匯集在一起,而且是秒級的力度,這個力度因為指標量大,時間粒度比較細,我們服務機器的服務數(shù)越來越大,現(xiàn)在還碰不到瓶頸。

  • 關于HBase:

  • Rowkey 設計是關鍵;

  • 不適宜多維度索引、需要事務、穩(wěn)定性要求極高;

  • 關注寫熱點;

  • writebuffer,WAL,Autoflush;

  • 關閉compact/split、手動觸發(fā)GC

關于Hbase使用。現(xiàn)在用Hbase的公司越來越多,2011年淘寶這一塊就已經(jīng)開始在線上大規(guī)模使用,Hbase這一塊很穩(wěn)定,從0.96之后就已經(jīng)可以說到非常穩(wěn)定,1.0有一些變化,1.0之后的Hbase是值得大家使用的。

rowkey設計可以寫一本書,這里只做簡單介紹。Hbase沒有索引,所以rowkey非常關鍵,我們通過rowkey定位到數(shù)據(jù),如果通過rowkey能約精確定位到數(shù)據(jù),查詢效率越高,用這個思路看看業(yè)務場景和看看使用,可以做一些相應的優(yōu)化,做一些提升。

HBase不適宜的場景,包括多維度索引、需要事務、穩(wěn)定性要求極高。

關注寫熱點,一般,按照默認的Region Split方案,上線后如果寫壓力比較大,都會有寫熱點的問題,這時需要考慮預建region。再就是寫壓內(nèi)考慮writebuffer、WAL、autoflush,我寫的要求很高,數(shù)據(jù)一致性要求很高那這事就不好辦,只有做權衡,寫性能上和數(shù)據(jù)一致上做權衡,下面三個參數(shù)只要你調(diào)了或者關了,可用性就會丟,有這個風險擇,這是預先告訴大家。

對日志類的表化考慮關閉compact,手動觸發(fā)GC。

y2i263I_副本.jpg

Open TSDB表設計和原數(shù)據(jù)和數(shù)據(jù)表。這是官方圖,講得非常透,大家看一下怎么保證維的很多,數(shù)據(jù)量很大的時候,能夠基于open TSDB把這么一個系統(tǒng)做得高效,就是通過一套rowkey,還有右圖按照時間力度做row的壓縮,我覺得主要這兩個特性保證它的性能。

這是跟open TSDB密切相關的兩個點。

三、實時流計算

這一塊我們現(xiàn)在斗魚用得規(guī)模比較大,和大公司比可能就有一點小巫見大巫,但是我還是想分享一下,從0到1的過程,包括第三點,從1到1.1的過程。

  • 實時流計算

  • 以前:靠猜

  • 演進:Redis

  • 現(xiàn)在:Storm + Spark Streaming

流計算。比如,我們上了一個專題或者我剛開始提到,英雄聯(lián)盟有一個決賽,線上有量,量有多大,只能根據(jù)卡不卡,只能主觀上感覺卡不卡做一個評估。后臺服務器的一些數(shù)據(jù)指標比較延時,剛開始靠猜,靠感覺,感覺要上機器了,要調(diào)一些流或者壓力到另外一部分機上,靠感覺。

包括有一些上專題,比方說有一些活動,錘子或者魅族、樂視新品發(fā)布,他們的量,有時候沒有能想象的大,有時候會非常大,但是我們沒有辦法做一些預案,所以這個時候我們就慢慢有了這個,這是我們最開始的一個迫于壓力有了這樣一個方案,redis實時統(tǒng)計的量。

用戶多了,鳥就多了,各種羊毛黨就越多,這一塊有了一個風控,再一個個性推薦,用戶多了之后,用戶群體戶越來越多樣化,這一塊就考慮個性推薦,千人千面,這一塊是后來第二階段的需求。就有了現(xiàn)在storm加spark Streaming的方案在跑。

zE3qUrF_副本.jpg

這是數(shù)據(jù)流的架構,最開始只有最上面的架構,web、APP,在Nginx Lua,這是錘子2發(fā)布會捐贈的一個項目,他把世界上最快的兩個系統(tǒng),一個是Nginx和Lua,加在一起性能非常好強悍。基于Lua和redis,性能好,又好用又穩(wěn)定,又不吃資源。

到了Kafka這一層,就有了另外的一些數(shù)據(jù),比方用戶行為數(shù)據(jù)接入進來,關系表MySQL,我們沒有其它的關系存儲。到了Kafka出來之后就是storm,是線上規(guī)模用得最大,我剛才說的數(shù)據(jù)產(chǎn)品都是基于storm,后面簡單介紹一下storm踩過一些坑。

Spark吞吐量是非常好的,因為兩個數(shù)據(jù)模型就決定了他們兩個側重業(yè)務場景是不一樣的,后面離線計算,這個中間有一個是數(shù)據(jù)應用層,我們可以從實時計算到數(shù)據(jù)應用層,會寫到中間離線層,又有另外一批數(shù)據(jù)到前面的應用層,實時數(shù)據(jù)監(jiān)控和其它應用。

  • 關于數(shù)據(jù)收集

  • 以前:堆PHP

  • 現(xiàn)在:OpenResty

剛剛講了數(shù)據(jù)收集這一塊,尤其用戶行為數(shù)據(jù),包括另外有一些服務層的服務,開始堆PHP,太耗資源,我們就發(fā)現(xiàn)OpenResty。

再用Storm,我先把這個羅列在這個地方,Storm優(yōu)化主要就是基于這兩個邏輯對象圖。

6_副本.png

Storm的新版本中,已經(jīng)剝離了對ZK的依賴。我們所有的調(diào)優(yōu)調(diào)這幾個對象的參數(shù),比方提高并行度,我們要提高時間時效,就是基于這個圖。

這個圖中,數(shù)據(jù)流怎么從這個流程里面最快的流入,最快流出,這就是實時流計算的初衷或者說包括最終的解決方案,也就是一直在優(yōu)化。就比方說我們在第一級Kafka或者redis出來之后進到storm,越簡單越快把消息弄進來最好。弄進來之后越快把消息處理完統(tǒng)計完把數(shù)據(jù)推走,越快推走對壓力越小,處理時效吞吐量越大。

如果我們做優(yōu)化,會去分析在第一個bolt1或者bolt2,如果里面有堆積,是在哪一個邏輯里面堆積,會考慮增加并行度或簡化它的邏輯,讓數(shù)據(jù)流盡快從第一級到 第二級到第三級,流出數(shù)據(jù)流程,我們整個優(yōu)化的思路就是這樣。

bolt1、2到bolt3,想跟大家分享,我們很多時候優(yōu)化Storm忽略一個點,Storm依賴外部資源會成會我們的瓶頸,我們的數(shù)據(jù)沒辦法往外面推,沒辦法落地,后面一層堆積也會直接制約我們優(yōu)化的一個瓶頸。

我們最后往redis寫,性能強悍,你一個storm沒問題,當時用一個redis做一些hush,做分散,還是解決不了,后來把redis替換掉。

  • 關于 Storm 優(yōu)化

  • Spout數(shù)和Kafka中Topic 的 Partition 數(shù)相匹配

  • 根據(jù)excute latency,找出各個 componet 的 process cost

  • 讓 spout nextTuple 盡量簡單

  • 提升 Storm Topology的性能要注意外部資源

這是我們在storm優(yōu)化整體的思路,比較簡單,主要幾大塊。 spout數(shù)和Kafka中的話題的partition數(shù)相匹配。 監(jiān)控每一個執(zhí)行的時效,去做監(jiān)控,及時發(fā)現(xiàn)某一些componet要不要做優(yōu)化。

我們最開始上storm就有了spark流,流利用在時空監(jiān)控的場景,這是今年2016年的大方向。

  • 關于 Spark Streaming

  • 設置合理的批處理時間(batchDuration)

  • 緩存需要經(jīng)常使用的數(shù)據(jù)

  • 集群task并行度

  • 使用Kryo序列化

這是流的簡單使用有一些心得,踩過一些坑。批處理時間。換粗需要經(jīng)常的使用的數(shù)據(jù)。集群task并行度,使用Kryo序列化。

這是我們踩過的巨坑,最后和大家強調(diào)一下。

踩過的巨坑

  • 監(jiān)控

  • 安全

  • 余量

第一個踩過的巨坑就是監(jiān)控。

我們有很多量,現(xiàn)象級的,百萬級的用戶立馬在一秒到十秒用涌入一個直播間,這個直播間放在和其它直播間放在一個server上面,立馬卡頓不卡用,如果在監(jiān)控這一塊,可以解決很多的一些告警和預警。包括有一些業(yè)務的指標監(jiān)控,監(jiān)控這一塊非常重要。

今年做了比較大的一塊,就是在做統(tǒng)一監(jiān)控平臺,現(xiàn)在我們也是在花主要的開發(fā)資源做這一塊,因為我們前端有網(wǎng)站端后端有C++服務端,語言異構排查起來就存在,沒法定位,第一反應大家很本能甩鍋,就需要統(tǒng)一監(jiān)控平臺。

第二,安全。

最開始太粗放,我們最開始做網(wǎng)絡隔離,我們的集群是第一次做了網(wǎng)絡上的隔離,然后后來就包括人員越來越大,因為不可能是我一個人干,也不可能做這么多業(yè)務場景,用的人越來越多,包括其它團隊,業(yè)務分析師做數(shù)據(jù)分析用到線上環(huán)境,這個地方安全非常重要。

第三,一定的余量。

預估業(yè)務、提需求,上機器這么一套下來,就一兩個月,小公司不要扣這部分的成本,起碼預留20%的量。

To do

探索式數(shù)據(jù)集市、推薦系統(tǒng)、風控系統(tǒng),這是我們今年最大的三塊目標。

ps:作為優(yōu)秀又土豪的公司,斗魚現(xiàn)在非常缺人,非常非常缺,總之錢多速來有挑戰(zhàn)!對斗魚感興趣的同學可以聯(lián)系私信小尋哦~

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容