從0到1構建數據生態係列(二):拆解架構藍圖
一、結合業務需求拆解架構圖
先把上一章已經講過的架構圖再貼一次:
整體架構說明
從架構圖中可以看出,在我們整個數據架構中,需要做的事情很多。隨著數據的流向,從下到上,主要分三層:
-
第一層是數據收集層,負責基礎數據的收集工作;
-
第二層是數據存儲與處理層,負責數據存儲、對數據進行深度處理、轉換及價值的挖掘等;
-
最上層是應用層,基於下麵的數據處理,進行價值轉換;還有貫穿整個過程的監控以及任務調度相關的工作。
第一層中,主要有四個數據來源:用戶行為埋點上報數據、服務日誌的數據、後端的業務數據、互聯網的公開數據。
第二層中,我們主要的核心框架是Hadoop的核心生態,基於HDFS的存儲(本質上hive的存儲也是基於HDFS),以及基於Spark部分實時處理的需求場景,主要是平台級的架構。當然,至於說具體的處理以及數據的加工、挖掘詳細數據業務,後續其它章節再詳述。
第三層中,我們直接麵向的是業務方。一方麵是數據生態中最基礎最常見的的數據智能商業化分析,我們以excel封裝成郵件日報周報的形式提供。另一方麵是平台化的BI係統,以及高度自助性的數據自助查詢係統。
在深度挖掘方麵,推薦是一個大方向,基於數據的當代搜索也是數據生態的重要組成部分,同時還有業務畫像、用戶畫像(絕對核心價值所在)等。除了以上這些,還有一些基於數據的推送服務、榜單數據、精準營銷係統等,都是數據進一步有效應用,以及數據化價值的直接體現。
收回話題,在時間、人力有限,並且基礎是0的前提下,事情解決的順序就顯得尤為重要了。
想要使用數據,前提是有數據。所以,我們第一個需要解決的問題是數據源,核心的驅動價值因素是我們的業務需求。
我們第一個業務需求就是從數據上洞察產品的運營效果,電商的各種數據運營需求,指導內容數據化運營、電商數據化運營以及通過數據改進產品。
跟業務強相關的基礎數據是產品的業務數據庫,這個是現成的,隻要打通數據流通即可。與用戶行為強相關的則是最直接的用戶行為埋點上報數據,以及用戶使用服務,在應用服務中留下的訪問LOG。
基於服務日誌LOG解析數據,一方麵如果需要從服務LOG中清洗出有用數據,前提是服務中已經有意識的進行相關信息的LOG落地,這一點,很遺憾,當時並沒有這個前瞻性。其次,從服務LOG中清洗數據的代價略高,且信息量有限。所以,在這個階段中,我們並沒有打算直接從服務LOG中清洗數據,因為在服務LOG中埋入數據收集點位,也是一個巨大的改造工程,但效果並不一定好。
我們將最快限度地打通業務數據庫與數據中心的通道,然後以最快速度的對業務方提供可參考性的數據化日報。打通行為數據到數據應用的鏈路,結合用戶行為數據,進一步優化數據化運營體係,以及為產品優化迭代提供數據支撐。構造最基礎的數據中心平台,打通數據收集到數據分析應用的鏈路,為業務方、決策層提供數據化運營決策方案,為產品迭代提供最真實的數據反饋支撐。
這是我們數據部門第一個戰略目標,像深度挖掘、推薦係統這些在這時通通不要想太多,飯需要一口一口的吃!
之所以需要拆分階段目標,依然是投入與產出比的問題!
當有一個大目標時,我們需要把目標進行拆分,進一步拆分為階段可實施、成果可見的階段性目標,在這裏同樣適用。
並且,記住,你的老板是不懂技術的,他才不會管你的平台又建設到什麼程度,集群又搭建了多少台,他隻會問,這都一兩個月了,你們數據怎麼還沒有給公司帶來價值啊?!(哈哈,有點黑BOSS的感覺了)
不過這肯定是現實,不同位置上的人關注的核心重點不一樣。可能你需要關注整體的進度,而業務層隻關心你的產出給他帶來什麼幫助。是的,拆解大目標有利於我們快速入手啟動項目;成果階段化,更具有鼓勵性,成就感;最後就是階段性目標的實現情況更容易量化你的效率。
從人力的需求評估角度上說,也是有道理的,隻有隨著你的體係一步一步完善,你才知道哪個環節真正的缺人,缺什麼人,這點很關鍵。不過最本質的問題,還是投入與產出比。
我們在做任何一件事情的時候,都需要注意投入與產出的比例,在一定的時間段內、投入一定的精力、產出一定比例的成果。有這種價值觀,處理事務才更有效率!
二、如何做機器需求的評估
想要打通數據收集到數據分析業務的輸出鏈路,那麼你需要一個數據平台進行支撐,甚至後續你將持續開挖的數據核心價值,這些都是基於平台做的。
所以我們需要一個數據平台,而說到平台,則機器資源是繞不過去的一個問題。那麼,如何去評估你的集群需要多少台機器呢?每個機器又是以一個什麼樣的角色存在的呢?
在評估之前,你首先應清楚了解到平台上需要承載的業務,包括內部的處理業務以及對外暴露的數據業務。其次,你需要考慮後續的可擴展性,即後續數據量上漲的情況下,機器的橫向擴展當然是沒有問題的,但部分角色機器的資源需求是在縱向。
舉個簡單例子,Hadoop的datanode可以在橫向上進行擴展,但是Namenode的資源需求則無法做到。
至於說如何進行機器資源評估,在了解自身業務需求的前提下,這裏所說的業務需求,不單純是業務範圍,也意味著業務範圍承載的數據量是什麼情況。在了解自身數據量的情況下,多查找其他公司的案例,與其他同行多交流溝通,借鑒其它公司的數據量與集群規模,來評估自身所需要的機器資源。需要注意一點的是,對於電商行業,經常會出現節日性、活動性質的流量暴漲。
所以,你的機器資源一定是需要考慮這些實際場景負載的或對於這種場景,若你有其它的方案進行處理也OK。
三、使用Nginx做數據上報偽服務
上麵說到第二個重點,那就是用戶行為數據的上報。
了解數據上報以及埋點相關邏輯的朋友應該清楚,其實所謂的SDK,其本質也是一個接受數據上報的服務。直接往上報服務中丟數據,跟封裝成工具SDK,本質的意義是一樣的,我們需要提供一個對外的數據上報服務。上報什麼數據,數據以什麼格式上報,這個在下一章的“數據上報體係”部分詳細闡述,這裏隻是對上報服務這塊進行講解。
那這意味著,我們需要為客戶端或者H5的童鞋提供一個統一的上報服務接口,讓他們在用戶特定行為操作的時候。比如瀏覽了某個頁麵,操作了某個按鈕等之類的操作,進行這種信息的收集統一上報。說白了,封裝用戶的行為數據,在適當時候調我們的接口,把用戶的行為數據給我傳過來。
那這看似就是一個後台服務,用於處理上報過來的數據。但是請注意,不管你是一個服務也好,偽服務也好,一般情況下絕不會直接把獲取到的數據直接落地的,這是傳統的思維路子。
要知道上報的業務流量是很大的,特別是你的點位足夠豐滿的情況下,在流量高峰期,你要是敢直接進行數據落地,它就敢直接把你的服務給搞死。一所以一般情況下,我們都會把數據丟給緩存,以解耦上報與落地兩端的壓力。
既然如此,在人力資源有限、項目時間有限的前提下,為何要花這麼大的精力去維護一個服務呢?於是,有了偽服務設想。
我們直接使用Nginx對外偽裝成一個Web服務,提供Restful API,但我們不對上報的內容做任何處理,直接落地成Nginx的日誌,再通過Flume對日誌進行監控,丟到Kafka中。這樣我們就迅速地搭建起一個上報“服務”,提供給客戶端童鞋以及H5的童鞋,製定好數據上報的規範,然後就可以坐等數據過來了。
關於數據的合理性校驗、規範性校驗、有效性校驗、以及進一步的解析,我們都放到Spark Streaming這一層去做。其實當時也是調研過lua的,在Nginx這一層也是可以做到數據完整性以及有效性校驗的,但為了不至於給Nginx端帶來過大的負荷,我們把複雜的邏輯處理放到後端。
基於這種偽服務的設計,還有一個好處就是,即使後端鏈路出現故障,但我的原始數據是落到LOG中的,隻要我進行數據的回溯,再通過LOG清洗出異常的部分就行了。這也是我們後續實時數據容錯的核心依據所在,所以,重點推薦。
四、用Spark Streaming做實時數據清洗
緊接上麵的上報,我們在後端一層使用Spark Streaming做數據校驗、進一步清洗的。
如果業務對於實時性要求不高,我們完全是不必要做數據的實時鏈路,隻需要周期性地把Nginx中的上報日誌進行批量清洗入庫即可。但是,一方麵基於部分對實時性稍高(其實也不高,分鍾級別),例如電商活動期間對數據的實時監控;另一方麵來說,實時性的數據上報鏈路是最終的目標,為了業務的時效性,遲早是需要做的。
由於我們需要在後端的處理環節中,對數據的有效性、規範性做校驗,並且做進一步的屬性解析,例如通過IP解析地理位置之類的,因此承載的業務邏輯還是蠻複雜的。
所以,我們打算引入一個實時處理框架來做這件事。關於實時框架這塊,我想,熟悉的朋友都會想到兩個:Storm與Spark Streaming。在這裏跟大家分享我之前翻譯過的一篇文章《Storm與Spark Streaming的對比》。(英文原文:https://xinhstechblog.blogspot.com/2014/06/storm-vs-spark-streaming-side-by-side.html)

雖然這兩種框架都提供了係統的可擴展性和可容錯性,但是它們的數據處理模型從根本上說是不一樣的,處理模型則決定了它們的實時性。
Storm可以實現真正流式實時的處理數據,例如每次處理一條消息,這樣延遲就可以控製在秒級以下,實時性很高。而Spark Streaming的本質還是批量處理,隻是這個批量是微批量,在短的時間窗口內進行數據實時處理,通常延遲在秒級左右,實時性相對較弱。
在數據容錯能力方麵,SparkStreaming做的比Storm好一些,它的容錯是通過狀態記錄去實現的。(譯者注:熟悉spark的童鞋都知道,spark會將所有的處理過程狀態都以log的形式記錄下來,即血統,出現錯誤的時候,可以根據血統進行數據的恢複)
而Storm則不一樣,Storm對每一條數據進行處理標記,從而進行跟蹤數據的處理情況,它隻能保證每條數據被處理一次,但實際情況是,在發生錯誤時,這條數據是被處理多次的。
這意味著,更新多次時可能會導致數據不正確。
而Spark的批處理特點,能夠保證每個批處理的所有數據隻處理一次,保證數據不會在恢複的時候錯亂(批處理重新執行)。
Storm提供的Trident庫雖然能夠保證在數據容錯時隻被處理一次,但它很大程度上依賴於事務的狀態更新,並且這個過程相對較慢,更甚者,這個過程是需要用戶自己去實現。(譯者注:Spark的數據安全性是毋庸置疑的,雖然當年Storm能夠從多個開源實時處理框架中脫穎而出,ack/faild機製的功勞巨大,但是跟Spark比,數據容錯能力還是差了一籌)

所以,如果你的業務場景對實時性要求比較高,同樣對數據容錯也有所要求,那麼Storm將是一個很好的選擇。當然,如果你希望對每次實時處理的過程進行掌控,那麼Spark Streaming提供的狀態記錄會清楚地描述出數據處理的過程,並且數據的容錯能力也很不錯。
框架實現以及編程API
假如你想深入源碼中研究,你需要清楚的是:Storm是由Clojure編寫的,而Spark Streaming則是Scala。
Storm是由BackType和Twitter開發的,而Spark Streaming則是由UC Berkeley開發的。
在語言支持上,Storm提供了Java API,同時也支持多語言。(譯者注:在多語言的支持上,雖然支持,但是通常除了Clojure、Java、Python等幾種語言,其它語言進行開發還是很困難的,最常用應該是Java)Spark Streaming支持Scala、Java、Python等幾種語言。
批處理框架集成
(譯者注:這點是針對於Spark Streaming來說的)
Spark Streaming一個很大的優勢就是,它是基於Spark框架上做的,這樣的話,熟悉Spark操作的人就能很輕鬆的像進行其它批處理操作一樣,進行操作Spark Streaming。這意味著你不用進行額外的編寫處理代碼,更為便捷。

實際生產應用
Storm開源得比較早,自2011年起,推特就在使用Storm了,其後更多的公司使用它。而Spark Streaming是一個比較新的項目,在2013年的時候,僅僅被Sharethrough使用(據作者了解)。
Storm是Hortonworks Hadoop數據平台中的數據流式處理的解決方案,而Spark Streaming出現在MapR的分布式平台和Cloudera的企業數據平台中。
此外,Databricks公司還專門為Spark提供技術支持,當然,其中也包括了Spark Streaming。
最後在依賴框架來說,Storm可以在Mesos上運行, 而Spark Streaming可以在YARN和Mesos上運行。

Storm比Spark Streaming更有實際應用的優勢,但Spark有專門的公司維護它並且提供技術支持,包括它與Yarn的結合等。
總結
其實Storm在處理領域上還是有一定的差異的,Storm比較擅長實時性較高的數據處理,而Spark Streaming則偏向於內存處理(注意嚴格來說內存處理跟流式處理並不是完全一樣的)。
在數據安全性方麵,不作過多的評論,數據安全Storm雖然沒有Spark streaming強大,但從目前來看已經夠用了,要知道很多業務數據在這種場合下是允許丟失部分數據的。
關鍵點在於資源的管理,雖然最近發布的Storm 0.10.0-beta號稱在資源管理上已經做了不小的優化,但在個人看來還遠遠不夠。Spark Streaming依賴於Spark的環境,而Spark在Hadoop2.0時代以後,資源管理方麵得到了巨大的提升,這側麵的衍生了大量類似Yarn的組件。
雖然Storm也可以運行在Yarn上,但目前並沒有一個很穩定可用於生產環境的開源版本。所以,在資源管理方麵storm還有很長的一段路要走。
在兩者的選擇上,從當前實際應用看,Storm已經越來越多的生產實例了,而Spark Streaming更多還處於預研或者試用階段。
相對來說,在流式處理上,Storm有著不可比擬的優勢,而在大批量內存處理的方麵,則是Spark Streaming占著不小的優勢。
所以具體使用方麵,一般情況下Storm足夠了,而Spark Streaming的話,慎用,畢竟任何開源的穩定性以及其價值,都是需要時間來檢驗的。
總之,Storm與Spark Streaming最本質的區分在於,Storm是真正實時處理,而Spark Streaming的處理本質則是微批處理。所以Storm能夠將實時業務達到毫秒級,而Spark Streaming雖然也能達到亞秒級,但對於效率的影響會比較大,所以一般會用於秒級的數據處理。
目前就我們自身的業務需求來說,對於實時性並沒有高到毫秒級的要求。
並且,為了維護係統平台的統一性(統一的平台架構,統一的YARN資源管理,同一個垂直生態),我們選擇使用Spark Streaming作為我們數據清洗的入口。
使用Spark Streaming需要解決的一個問題就是,輸出結果的高度碎片化。
正如上麵所說,Spark Streaming其核心依然是Spark的路子,在微小的時間窗內,對微小批量的數據進行處理,達到類似實時的效果。
而其每一個批量處理之後都是以批量結果得以輸出,於是,就會產生大量的碎片文件。
其實,解決這個問題也簡單,那就是合並!進行周期性的文件合並,這點就不多說了。
既然說到了Spark Streaming,也就順帶著說一說Spark這個生態。
在很早以前,Hadoop、MapReduce經常會被人提到,但是隨著Spark的興起,已經越來越少人願意使用MapReduce去批量處理數據了。
是的,Spark目前在Hadoop大生態中,已經形成一個比較完整的子生態:
-
包括與數據查詢分析關聯的Spark SQL;
-
實時處理領域的Spark Streaming;
-
正常內存處理可以替代MapReduce的離線批量;
-
還有集成大量機器學習包的MLlib;
-
以及還有什麼圖形處理的什麼鬼(好吧,那個不是我擅長的)。
在效率至上的數據時代,MapReduce說拋棄就被拋棄了(哈哈,其實也沒有這麼嚴重,隻是越來越多人棄用MapReduce,這肯定是事實)。
在體係支撐上,Spark依然成氣候,數據的常規SQL分析,數據的內存處理、實時處理,以及數據的深度挖掘等,全部一起打包,好用的不得了,所以越來越得人心,也是木有辦法的事。
關於IP地理位置解析,這裏也可以分享一下。
IPIP.NET提供的IP庫實在是值得推薦的,沒錢的可以使用它提供的免費版,有錢的主可以考慮使用使用付費版。
免費版沒有想象中那麼不堪,隻是它提供的服務沒有這麼多,更新的頻次少點而已,大部分能解析到市一級,至於省份這一級,那是妥妥的沒問題。
五、結語
本章主要闡述如何從局部入手,拆解架構圖,進行階段性的任務執行。其中,詳細講解了部分核心重點,包括架構圖的拆解、機器資源的評估、Nginx的上報偽服務、以及基於Spark Streaming的數據清洗等。
但是個人認為,方法論遠比現成的方案有用,授人以魚不如授人以漁!更重要的是中間闡述一些問題的思考方式、價值觀,諸如拆解整體規劃的思考、擴展預留的思考、方案選擇的對比衡量等。希望本文能對你有所啟發。
作者介紹 黃崇遠
-
畢業於哈工大,近6年大數據行業經驗 ,目前於深圳一創業公司任職大數據主管,數據蟲巢公眾號及官網(www.mite8.com)創建者。
-
原文發布時間為:2017-05-10
本文來自雲棲社區合作夥伴DBAplus
最後更新:2017-05-17 14:02:13