初創公司大數據平臺的選型和進化心得


作者簡介:張申竣,魔窗聯合創始人兼首席技術官,互聯網技術聯盟ITA1024講師團成員。畢業於上海同濟大學計算機系,超過10年的軟件和互聯網行業研發經驗。曾在HP、SuccessFactors、EMC等500強企業從事企業級SaaS平臺的研發和性能調優,擁有深厚的企業級SaaS服務和移動互聯網的背景。

DSC_1697.JPG

魔窗簡介:作爲全國獨創品類的App用戶增長引擎,魔窗(MagicWindow)整體解決方案不僅能提供最好的增長工具,同時配套增長聯盟(最優秀的創始人聯盟)及生態連接器服務,幫助App創業者一站式地解決運營效率及增長問題。魔窗增長工具包含多個典型功能模塊,如硅谷最熱門的企業級深度鏈接(Deeplink)解決方案-mLink技術,App動態運營位管理,內容分發和服務分發平臺,App活動引擎以及跨App Store渠道分析等,幫助創業者以接近免費的低成本規模化獲取新用戶,提升2-3倍用戶活躍度。App只需半小時接入SDK,即可享受魔窗全方位的增長產品及服務。目前,魔窗團隊爲攜程、格瓦拉、美人相機、簡拼、我廚網、G信、羅輯思維(得到)、網易、黑馬會(學吧)、正和島(對路)、心意點點、悠哉旅遊、酒仙網、錦江集團、漫畫島、追書神器、好物、顏值、收趣、火辣健身等移動端優秀企業提供全程專業服務。

正文如下:

一、充分了解業務需求和產品所處階段

架構師的職責永遠是根據現有的資源不斷做trade off,挑選出最適合公司當前狀況的技術方案。所以在我們談大數據平臺選型之前,先看一下創業面臨的一些挑戰和優勢:

1.    資源不足

2.    時間壓力大

3.    沒有技術上的歷史包袱,選型相對自由

    

前兩點是搭建大數據平臺的挑戰,最後一點是優勢。對於大部分創業公司而言,這三點挑戰和優勢始終存在,但是業務特點隨着公司的發展會有相應的變化,一般而言我們可以把創業公司的發展分成下面幾個不同的階段:

  • 產品驗證階段:

  • 產品成熟階段:

  • 業務增長階段:

下面就結合魔窗的發展經歷談一下圍繞這三個不同階段,魔窗的大數據平臺的發展歷程。

首先說明一下我們大數據平臺的業務需求:

計算由我們的移動端SDK採集過來的包括,日活,應用打開次數,流失用戶,迴流用戶等移動端監測的常用指標。

因爲我們是提供基於Deep Link的一系列應用喚醒服務,所以我們還需要監測,從投放在各個渠道的基於DeepLink生成的短鏈的曝光,安裝轉化率。

我們還提供各種營銷活動的製作和投放,所以還需要監測營銷活動的曝光率。


二、產品驗證階段

先看一下這一階段的業務特點:

1.      數據量很小,用戶最多隻有幾十個種子用戶,整個監測採集到的數據規模根本不能稱作大數據。

2.      我們所計算的統計指標也無法確定對用戶是否有真正的幫助,很可能整個功能會根據市場反饋最後被砍掉。

    

這種情況下,我們首先考慮的是要儘量縮小產品驗證的成本,所以技術選型的原則很簡單,端到端跑通功能,設計和實現上越簡單粗暴越好,不需要存在技術積累,被砍了也不可惜。所以這個時候架構的總的原則是保證能夠最快速迭代,推倒重來也沒關係。

我們的整個計算平臺的架構是這樣的:

1.png

     

事實上這個都根本不能稱作是大數據計算平臺,只是一個包含了數據採集,數據計算腳本和數據展示的Java應用,拿目前流行的micro service化來說,這個就是一個micro service 的反例,一個monolithic的應用。

但是非常合適驗證產品,利用一些一站式開發框架,修改業務非常簡單,MySQL的結構化特點使得計算腳本非常容易。這個架構大約支撐了我們3個月的時間。


三、產品成熟階段

大約3個月後,我們的產品逐漸成熟穩定了,種子用戶也越來越多,此時我們的業務特點發生了變化:

1.      計算指標相對穩定,及時加指標也是基於原有的採集點的計算。

2.      有一些流量大一點的種子用戶進來了,數量也越來越多。

3.      計算上分爲了實時計算和離線計算這兩種需求。

撇開MySQL計算性能的問題不談,這個時候光是採集數據就會經常造成MySQL連接失效,於是我們在不斷優化MySQL服務器端和客戶端連接參數的同時,開始了真正的大數據平臺的架構。

這個時候的架構有一個總的原則就是可持續迭代,因爲產品一旦穩定成熟,技術上就承受不了推到重來的代價了,在這個前提之下我們的架構基於以下原則:

1.      採集端保證大吞吐量。

2.      在存儲和計算節點出問題的情況下,保證在一段時間內採集到的數據不會丟失。

3.      性能可以通過Scale Out解決,並且易於做Scale Out。

4.      DevOps簡單,能夠方便的監測和預警。

下面是基於以上原則我們最後的架構:

2.png

 

數據採集

採用Nginx沒有什麼太大的爭議,異步非阻塞,保證大吞吐量


數據暫存區

這裏和一些傳統的監測架構有所區別,我們並買有采用把Nginx的日誌當數據暫存區的辦法,而是直接用了Kafka,好處在於:

1.      比起磁盤IO, Kafka的吞吐量更大,並且提供了異步寫入的方法,保證Nginx採集到的數據能夠最及時的進入數據暫存區。

2.      消息隊列本身就具有分佈式的一些特性,比如支持Failover保證高可用,數據可以存放多份,Partition機制使數據的寫入和加載更高效。

3.      消息隊列天生能解決不同種類監測數據區分的業務問題(比如Topic)。

4.      比起日誌,利用Kafka的API能夠方便的處理一些數據續傳的問題,比如如果存儲節點崩潰了,僅僅利用日誌是很難知道下次應該從那條記錄開始續傳的,Kafka就可以利用客戶端保存的Offset(實際上我們每個Kafka客戶端的Offset是保存在Zookeeper中的)做到。

 

數據傳輸

當時在兩種方案裏搖擺,一個是Flume 還有一個是Spring XD,最終選擇Flume的原因在於:

1.      輕量級,使用簡單,有大量的source和sink可以用。

2.      能被CDH託管(Spring XD不能被CDH託管,但是可以用yarn做資源調度)。

但是這個選擇最終造成了後期的一些困擾,之後會提到。

 

數據存儲計算

離線計算

Spark+ HDFS的模式相信已經被大家所熟悉,下面之談一下我們對於Spark的優化心得

1.      瞭解應用中的RDD的partition,執行中的stage情況,避免過多小任務。

2.      儘可能程序中複用RDD,如果多次使用,考慮做cache,根據實際情況選擇合適的持久化策略。

3.      必要時候使用broadcast 和 accumulator。

4.      根據自己的作業具體情況結合系統資源監控調整主要資源類參數,例如  num-executors,executor-memory,executor-cores和spark.default.parallelism等。

5.      如果允許,建議嘗試官方推薦的Kryo。

6.      對於jvm,, 通過打印GC信息瞭解內存使用情況,調整相應參數。

 

實時計算

我們又把實時計算拆分成了流式計算和針對特定時間範圍內的全體數據集合的實時計算。因爲對於像用戶留存這樣的指標,根據回溯歷史數據去做計算是相當困難的,採用流式計算的話會簡單很多,我們根據我們的業務特點也並沒有引入Storm或者Spark Stream這樣的流失框架,而僅僅是在Flume傳輸數據的過程中,簡單地利用HBase做了流式計算。

下面我們將解釋一下我們是如何利用HBase來做用戶留存率這一指標的計算的。

    

留存(https://en.wikipedia.org/wiki/Churn_rate)計算,如果使用傳統基於歷史數據集的查詢非常複雜,我們轉換思路,採用了流式的複雜寫,簡單讀的方式。

基本思路如下:

記錄設備的首次和上次訪問時間 

3.pic.jpg

爲各租戶定義需要計算的留存區間,例如5日留存,7日留存,2周留存,1月留存等,例如某租戶tenant1 ,選擇配置爲計算首日,5日,7日和3月留存。

那麼該租戶所屬的某個app(source App)發送的一條類似如以下的event,tenant1|deviceId1|timeStamp1|action1 ,應用會做以下操作:

1.      如果是新deviceId,則上表中新增訪問記錄。

2.      如果不是,例如本例中的deviceId1, 計算距離上次訪問時間間隔(以天計),(timeStamp1-pt1)=2day,更新上表中的previous access time。

3.    通過CAS incr. 更新以下留存記錄, 如果跨天了,表示這個設備的用戶就是留存用戶。如果跨1天,表示1天留存,跨3天,表示3天留存,依次類推。這是天的留存,周的留存根據Previous access time判斷是否跨周,道理相同。

其他如流失和迴流用戶基本計算方法比較接近,細節處理各異。

4.pic.jpg

對於特定時間範圍內的全體數據集的實時計算,我們選用了Elasticsearch作爲實時計算的集羣,原因如下:

1.      數據結構基於Json,因此是半結構化的數據,易於計算。

2.      基於我們的測試,查詢的response time基本能夠隨着節點的增長線性降低。

3.      非常容易做Scale Out,非常容易通過參數設置調整數據備份和Partition的策略。

4.      支持查詢的模板化,使查詢和客戶端代碼解耦。

5.      包括查詢,管理在內的所有功能API化,易於運維。

6.      插件豐富支持從其他數據源雙向導入數據。

爲什麼選擇CDH

我們曾經接觸過的幾個Hadoop 發行版 CDH,IDH(Intel),HAWQ(Pivotal),Hortonworks。

之前已經談到,在選型裏面我們比較關心的是DevOps,因爲到目前爲止我們還沒有專職的運維,所以需要最大限度的利用已有工具提升運維的效率,在這一方面CDH是最強的,它的管理工具提供了安裝,維護,監測,預警等一系列幫助運維的功能,節省了我們維護的很多時間。

IDH的特點是在HBase提供了LOB的類型,對二進制存儲有幫助,使用特殊的存儲類型避免發生頻繁的Compacting。同時還優化了Hive計算的性能使相關數據儘量在同一region裏。這幾點和我們的需求毫無關係,而且Intel已經戰略投資Cloudera,之後會把IDH的功能逐步移入CDH。

HAWQ,最爲PivotalHD的基礎,HAWQ最大的特點是在於它實際上是一個MPP架構的數據庫,提供了基於HDFS之上的SQL支持。3個Data Node的情況下,上億級別的包含group by聚合以及SQL子查詢的複雜查詢響應在10秒左右。所以HAWQ非常適合異步的近實時查詢,但是我們也沒有這個場景。不過用HAWQ可以把開發計算任務的成本幾乎降到0是非常具有吸引力的。

Hortonworks,各方面和CDH很像,但是管理工具不如CDH強大。

 

四、業務增長階段

隨着BD的鋪開,接入的客戶越來越多,隨着數據量的增長,我們發現了在產品成熟階段設計上的許多問題,但是因爲之前的架構原則是可持續迭代,所以問題都發生在局部的某些點上。

1.      沒有用到任何序列化技術,數據存儲是簡單粗暴的文本格式,這樣會導致兩個問題:

a)      當數據種類增加時,計算任務會產生大量join,既增加計算的複雜度,又影響性能。

b)     計算腳本和數據格式嚴重耦合,腳本任務取字段依賴於該字段在文本文件中的位置,增減字段需要評估所有job的影響。

5.pic.jpg

3.      Flume再往HDFS寫入時,無法保證一個partition一個文件,往往會被打散成許多小文件,Spark的計算性能和Namenode的性能對小文件的數量嚴重敏感。

4.      採用Spark Standalone,一個節點只能起一個executor,job 只能順序一個個執行。

5.      被CDH 託管的Flume 一臺機器只能使用一個Flume 節點。

針對這些個問題,我們又逐步進行了一些優化:

1.      錄入HDFS的文件採用Arvo的格式,保證採集到的一條完整數據可以存儲在同一個文件中,不用拆分,摒棄了join。另外基於Schema的數據,使得計算Job的語義更容易理解,可維護性更好。

2.      在離線計算任務之前,我們先回跑一個腳本將同一個partition下產生Flume產生的文件給合併,大大提升計算性能。

3.      從Spark standalone 切換到Spark Yarn。這樣做的好處在於:

a)      統一了我們的資源調度平臺;

b)     Yarn會自動優化數據的存儲和計算髮生在同一地域的問題(同一臺服務器,同一臺機櫃);

c)      我們而言比起spark standalone 最大的好處在與每個節點起的executor的數目可配,不同的job可以並行執行。

4.      Yarn本身作爲一個資源調度平臺的特性先不談,對我們而言比起sparkstandalone 最大的好處在與每個節點起的executor的數目可配,不同的job可以並行執行。

 

五、大數據平臺的DevOps

團隊的特點:只有一個兼職的運維。生產環境的運維由這個兼職的運維,我們的架構師和我本人負責。所以不可能花太多人力在運維上,因此我們必須保證監控,調試,重新發布的自動化程度,這也是我們選擇CDH的一個很重要的原因。

另外我們還單獨開發一個監測和重啓Spark任務的管理工具,而這個工具又是基於我們自主開發的離線任務框架來進行監測的。

這個工具包括一個web console, webconsole會通過JMX去控制job的基本操作,同時提供對已執行過的job的信息訪問,這些數據存儲在mysql中,通過Job Repository服務訪問。

5.png

六、總結和心得

從我們的平臺發展經歷來看,在初創公司做大數據平臺的選型,最重要的有兩點:

1.      產品目標導向,不同的階段利用有限的資源採集不同的架構策略。

2.      無論何種架構策略, DevOps始終是架構選型的一個重要考量,因爲它直接影響到你如何評估和調整架構。

(本篇文章整理自張申竣5月26日在『ITA1024大數據技術精英羣』裏的分享實錄:初創公司大數據平臺的選型和進化心得 。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章