何謂五橫,基本還是根據數據的流向自底向上劃分五層,跟傳統的數據倉庫其實很類似,數據類的系統,概念上還是相通的,分別為數據采集層、數據處理層、數據分析層、數據訪問層及應用層。同時,大數據平臺架構跟傳統數據倉庫有一個不同,就是同一層次,為了滿足不同的場景,會采用更多的技術組件,體現百花齊放的特點,這是一個難點。
具體見下圖示例,這張圖是比較經典的,也是妥協的結果,跟當前網上很多的大數據架構圖都可以作一定的映射。
數據采集層:既包括傳統的ETL離線采集、也有實時采集、互聯網爬蟲解析等等。
數據處理層:根據數據處理場景要求不同,可以劃分為HADOOP、MPP、流處理等等。
數據分析層:主要包含了分析引擎,比如數據挖掘、機器學習、 深度學習
數據訪問層:主要是實現讀寫分離,將偏向應用的查詢等能力與計算能力剝離,包括實時查詢、多維查詢、常規查詢等應用場景。
數據應用層:根據企業的特點不同劃分不同類別的應用,比如針對運營商,對內有精準營銷、客服投訴、基站分析等,對外有基于位置的客流、基于標簽的廣告應用等等。
數據管理層:這是一縱,主要是實現數據的管理和運維,它橫跨多層,實現統一管理。
邏輯上,一般都有數據采集層、數據存儲與分析層、數據共享層、數據應用層,可能叫法有所不同,本質上的角色都大同小異。
--------------------------------------------------
數據采集層:
實時采集現在也成了大數據平臺的標配,估計主流就是FLUME+KAFKA,然后結合流處理+內存數據庫吧,這個技術肯定靠譜,但這類開源的東西好是好,但一旦出現問題往往解決周期往往比較長。除了用FLUME,針對ORACLE數據庫的表為了實現實時采集,也可以采用OGG/DSG等技術實現實時的日志采集,可以解決傳統數據倉庫抽全量表的負荷問題。
企業級的爬蟲中心的建設難度蠻大,因為不僅僅是需要爬蟲,還需要建立網址和應用知識庫,需要基于網頁文本進行中文分詞,倒排序及文本挖掘等,這一套下來,挑戰很大,當前已經有不少開源組件了,比如solr、lucent、Nutch、ES等等,但要用好它,路漫漫其修遠兮。
數據源的種類比較多:
作為互聯網行業,網站日志占的份額最大,網站日志存儲在多臺網站日志服務器上,一般是在每臺網站日志服務器上部署flume agent,實時的收集網站日志并存儲到HDFS上;
業務數據庫的種類也是多種多樣,有Mysql、Oracle、SqlServer等,這時候,我們迫切的需要一種能從各種數據庫中將數據同步到HDFS上的工具,Sqoop是一種,但是Sqoop太過繁重,而且不管數據量大小,都需要啟動MapReduce來執行,而且需要Hadoop集群的每臺機器都能訪問業務數據庫;應對此場景,淘寶開源的DataX,是一個很好的解決方案,有資源的話,可以基于DataX之上做二次開發,就能非常好的解決。當然,Flume通過配置與開發,也可以實時的從數據庫中同步數據到HDFS。
有可能一些合作伙伴提供的數據,需要通過Ftp/Http等定時獲取,DataX也可以滿足該需求;
------------------------------
總得來講,建設大數據采集平臺非常不易,從客戶的角度講,至少要達到以下三個要求:
多樣化數據采集能力:支持對表、文件、消息等多種數據的實時增量數據采集(使用flume、消息隊列、OGG等技術)和批量數據分布式采集等能力(SQOOP、FTP VOER HDFS),比基于傳統ETL性能有量級上的提升,這是根本。
可視化快速配置能力:提供圖形化的開發和維護界面,支持圖形化拖拽式開發,免代碼編寫,降低采集難度,每配置一個數據接口耗時很短,以降低人工成本。
統一調度管控能力:實現采集任務的統一調度,可支持Hadoop的多種技術組件(如 MapReduce、Spark 、HIVE)、關系型數據庫存儲過程、 shell腳本等,支持多種調度策略(時間/接口通知/手工)。
-------------------------------
數據處理層
MPP應該來說,是采用分布式架構對于傳統數據倉庫最好的替代,畢竟其實際上是變了種的關系型數據庫,對于SQL提供完整支持,在HIVE做了轉化分析后,數據倉庫的融合建模用它來做性能綽綽有余,其性價比較傳統DB2更好一點,比如經過實用,Gbase30-40臺集群就能超過2臺頂配的IBM 780。
MPP現在產品很多,很難做優劣判斷,但一些實踐結果可以說下,GBASE不錯,公司很多系統已經在上面跑了,主要還是國產的,技術服務保障相對靠譜,ASTER還有待觀望,自帶一些算法庫是有其一些優勢,GreenPlum、Vertica沒用過,不好說。
-----------------------------------
只嘗試過STORM和IBM STREAM,推薦IBM STREAM,雖然是商業版本,但其處理能力超過STORM不是一點半點,據說STORM也基本不更新了,但其實數據量不大,用啥都可以,從應用的角度講,諸如IBM這種商業版本,是不錯的選擇,支撐各類實時應用場景綽綽有余。
流處理集群以流處理技術結合內存數據庫,用以實時及準實時數據處理,基于IBM Streams流處理集群承載公司的實時業務:
---------------------------------
數據開放層
HBASE很好用,基于列存儲,查詢速度毫秒級,對于一般的百億級的記錄查詢那也是能力杠杠的,具有一定的高可用性,我們生產上的詳單查詢、指標庫查詢都是很好的應用場景。但讀取數據方面只支持通過key或者key范圍讀取,因此要設計好rowkey。
---如何設計好HBASE RowKey?
Redis是K-V數據庫,讀寫速度比HBASE更快,大多時候,HBASE能做的,Redis也能做,但Redis是基于內存的,主要用在key-value 的內存緩存,有丟失數據的可能,當前標簽實時查詢會用到它,合作過的互聯網或廣告公司大多采用該技術,但如果數據越來越大,那么,HBASE估計就是唯一的選擇了?
另外已經基于IMPALA提供互聯網日志的實時在線查詢應用,也在嘗試在營銷平臺采用SQLFire和GemFire實現分布式的基于內存的SQL關聯分析,雖然速度可以,但也是BUG多多,引入和改造的代價較大。
Kylin當前算是基于hadoop/SPARK的多維分析的殺手級工具,應用的場景非常多,希望有機會使用。
-------------------
數據應用層
每個企業應根據自己的實際規劃自己的應用,其實搞應用藍圖很難,大數據架構越上層越不穩定,因為變化太快,以下是運營商對外變現當前階段還算通用的一張應用規劃圖,供參考:
什么是Druid,Flink,phoenix,redis?
▲滴滴大數據體系架構圖
▲知乎大數據平臺架構圖
▲騰訊云大數據平臺架構圖(EMR)
-----------------------------
什么是canal? Presto? Kylin?
數據開發的平臺,這張圖比較細,這是詳細的整體數據流架構圖。包括最左邊是數據接入,上面是流式計算,然后是Hadoop離線計算。
將上圖左上角擴大來看,首先是數據接入與流式計算,電商系統產生數據分兩個場景,一個是追加型的日志型數據,另外是關系型數據的維度數據。對于前一種是使用Flume比較標準化的大家都在用的日志收集系統,最近使用了阿里開源的Canal,之后有三個下游,所有的流式數據都是走Kafka這套流走的。
數據收集特性:
對于數據收集平臺,日志數據是多接口的,可以打到文件里觀察文件,也可以更新數據庫表。關系型數據庫是基于Binlog獲取增量的,如果做數據倉庫的話有大量的關系型數據庫,有一些變更沒法發現等情況,可以通過Binlog手段可以解決。通過一個Kafka消息隊列集中化分發支持下游,目前支持了850以上的日志類型,峰值每秒有百萬介入。
流式計算平臺特性:
構建流式計算平臺的時候充分考慮了開發的復雜度,基于Storm。有一個在線的開發平臺,測試開發過程都在在線平臺上做,提供一個相當于對Storm應用場景的封裝,有一個拓撲開發框架,因為是流式計算,我們也做了延遲統計和報警,現在支持1100以上的實時拓撲,秒級實時數據流延遲。
這幅圖是離線數據平臺的部署架構圖,最下面是三個基礎服務,包括Yarn、HDFS、HiveMeta。不同的計算場景提供不同的計算引擎支持。如果是新建的公司,其實這里是有一些架構選型的。Cloud Table是自己做的HBase分裝封口。我們使用Hive構建數據倉庫,用Spark在數據挖掘和機器學習,Presto支持Adhoc上查詢,也可能寫一些復雜的SQL。對應關系這里Presto沒有部署到Yarn,跟Yarn是同步的,Spark是on Yarn跑。
建設敏捷數據倉庫,除了對架構技術上的要求之外,還有一個很重要的方面,就是數據建模,如果一上來就想著建立一套能兼容所有數據和業務的數據模型,那就又回到傳統數據倉庫的建設上了,很難滿足對業務變化的快速響應。應對這種情況,一般是先將核心的持久化的業務進行深度建模(比如:基于網站日志建立的網站統計分析模型和用戶瀏覽軌跡模型;基于公司核心用戶數據建立的用戶模型),其它的業務一般都采用維度+寬表的方式來建立數據模型,這塊是后話。
這里的數據共享,其實指的是前面數據分析與計算后的結果存放的地方,其實就是關系型數據庫和NOSQL數據庫;
前面使用Hive、MR、Spark、SparkSQL分析和計算的結果,還是在HDFS上,但大多業務和應用不可能直接從HDFS上獲取數據,那么就需要一個數據共享的地方,使得各業務和產品能方便的獲取數據;和數據采集層到HDFS剛好相反,這里需要一個從HDFS將數據同步至其他目標數據源的工具,同樣,DataX也可以滿足。另外,一些實時計算的結果數據可能由實時計算模塊直接寫入數據共享。
即席查詢一般是通過SQL完成,最大的難度在于響應速度上,使用Hive有點慢,可以用SparkSQL,它的響應速度較Hive快很多,而且能很好的與Hive兼容。
實時計算:Storm在這塊是比較成熟了,但我選擇Spark Streaming,原因很簡單,不想多引入一個框架到平臺中,另外,Spark Streaming比Storm延時性高那么一點點,那對于我們的需要可以忽略。
我們目前使用Spark Streaming實現了實時的網站流量統計、實時的廣告效果統計兩塊功能。
做法也很簡單,由Flume在前端日志服務器上收集網站日志和廣告日志,實時的發送給Spark Streaming,由Spark Streaming完成統計,將數據存儲至Redis,業務通過訪問Redis實時獲取。
當前,頭條每日處理數據量為 7.8 PB、訓練樣本量 200 億條、服務器總量 40000 臺、Hadoop 節點 3000 臺。
數據生命周期分為生成、傳輸、入庫和統計/分析/挖掘,每個環節的難度都會隨著數據規模的變大而上升。平臺建設面臨的挑戰是由龐大的數據量和業務復雜度給數據生成、采集、傳輸、存儲和計算等帶來的一系列問題。
(1)數據生成與采集——SDK、用戶埋點
一般情況下,數據生成與采集是很簡單的事,但對于頭條這個功能眾多的 APP 來講,難點就在于每個功能背后都是一個團隊獨立運營。如果每個團隊都用自研的數據采集方法,那會給后續的進程帶來巨大的困擾。
怎么辦呢?因為頭條屬于 C 端業務公司,主要以日志形式為主,數據的主要來源是用戶行為,那么就采用事件模型來描述日志,以 SDK 形式接入,支持客戶端、服務端埋點。
這里需要注意的是:數據質量很重要,埋點規范趁早確立,臟數據是不可避免的,可以引入必要的約束、清洗等。
埋點的管理,也由通過文檔、Wiki 等方式演進成埋點管理系統,覆蓋整個埋點生命周期。這樣一來,也得到了埋點元信息的描述,后續可應用在數據清洗、分析平臺等場景,同時埋點的上線流程實現標準化,客戶端也可進行自動化測試。
SDK。數據平臺實現了通用的客戶端埋點 SDK 和服務端埋點 SDK,放棄之前按約定生成數據的方式,可以保證生成的日志符合埋點規范,并統一 App 啟動、設備標識等的基本口徑,也減少了新 App 適配成本。
對數據的描述由使用 JSON 改為 Protobuf,這樣就可通過 IDL 實現強制約束,包括數據類型、字段命名等。
除了日志數據,關系數據庫中的數據也是數據分析的重要來源。頭條在數據的采集方式上,用 Spark 實現類 Sqoop 的分布式抓取替代了早期定期用單機全量抓取 MySQL 數據表的方式,有效的提升了抓取速度,突破了單機瓶頸。
再之后為了減少 MySQL 壓力,選用 Canal 來接收 MySQL binlog,離線 merge 出全量表,這樣就不再直接讀 MySQL 了,而且對千萬/億級大表的處理速度也會更快。
(2)數據傳輸——Kafka 做消息總線連接在線和離線系統
數據在客戶端向服務端回傳或者直接在服務端產生時,可以認為是在線狀態。當數據落地到統計分析相關的基礎設施時,就變成離線的狀態了。在線系統和離線系統采用消息隊列來連接。
頭條的數據傳輸以 Kafka 作為數據總線,所有實時和離線數據的接入都要通過 Kafka,包括日志、binlog 等。這里值得注意的是:盡早引入消息隊列,與業務系統解耦。
頭條的數據基礎設施以社區開源版本作為基礎,并做了大量的改進,也回饋給了社區,同時還有很多自研的組件。
因為以目前的數據和集群規模,直接使用社區版本乃至企業版的產品,都會遇到大量困難。像數據接入,就使用自研 Databus,作為單機 Agent,封裝 Kafka 寫入,提供異步寫入、buffer、統一配置等 feature。
Kafka 數據通過 Dump 落地到 HDFS,供后續離線處理使用。隨著數據規模的增加,Dump 的實現也經歷了幾個階段。最初實現用的是類似 Flume 模式的單機上傳,很快遇到了瓶頸,實現改成了通過 Storm 來實現多機分布式的上傳,支持的數據吞吐量大幅增加。
現在開發了一個叫 DumpService 的服務,作為托管服務方便整合到平臺工具上,底層實現切換到了 SparkStreaming,并實現了 exactly-once 語義,保證 Dump 數據不丟不重。
(3)數據入庫——數據倉庫、ETL(抽取轉換加載)
頭條的數據源很復雜,直接拿來做分析并不方便。但是到數據倉庫這一層級,會通過數據處理的過程,也就是 ETL,把它建設成一個層次完備的適合分析的一個個有價值的數倉。在數倉之上,就可以讓數據分析師和數據 RD 通過 SQL 和多維分析等更高效的手段使用數據。
數據倉庫中數據表的元信息都放在 Hivemetastore 里,數據表在 HDFS 上的存儲格式以 Parquet 為主,這是一種列式存儲格式,對于嵌套數據結構的支持也很好。
頭條有多種 ETL 的實現模式在并存,對于底層數據構建,一種選擇是使用 Python 通過 HadoopStreaming 來實現 Map Reduce 的任務,但現在更傾向于使用 Spark 直接生成 Parquet 數據,Spark 相比 MapReduce 有更豐富的處理原語,代碼實現可以更簡潔,也減少了中間數據的落地量。對于高層次的數據表,會直接使用 HiveSQL 來描述 ETL 過程。
(4)數據計算——計算引擎的演進
數據倉庫中的數據表如何能被高效的查詢很關鍵,因為這會直接關系到數據分析的效率。常見的查詢引擎可以歸到三個模式中,Batch 類、MPP 類、Cube 類,頭條在 3 種模式上都有所應用。
頭條最早使用的查詢引擎是 InfoBright,Infopight 可以認為是支持了列式存儲的 MySQL,對分析類查詢更友好,但 Infopight 只支持單機。隨著數據量的增加,很快換成了 Hive,Hive 是一個很穩定的選擇,但速度一般。
為了更好的支持 Adhoc 交互式查詢,頭條開始調研 MPP 類查詢引擎,先后使用過 Impala 和 Presto,但在頭條的數據量級下都遇到了穩定性的問題。
頭條現在的方案是混合使用 Spark SQL 和 Hive,并自研 QAP 查詢分析系統,自動分析并分發查詢 SQL 到適合的查詢引擎。在 Cube 類查詢引擎上,頭條采用了 Kylin,現在也是Kylin 在國內最大的用戶之一。
(5)數據門戶——為業務的數據分析提供整體解決方案
對于大部分需求相對簡單的公司來說,數據最終可以產出報表就夠用了,如做一個面向管理層的報表,可以讓老板直觀的了解一些關鍵性指標,這是最基礎的數據應用模式。
再深入一點,就需要匯總各種來源的業務數據,提供多種維度和指標來進行更深入的探索型分析,得到的結論用來指導產品的迭代和運營。頭條絕大部分業務都是數據驅動的,都需要產出和分析大量的數據,這就或多或少需要用到平臺提供的系列工具。
頭條開發了一套叫數據門戶的平臺系統,提供給業務部門使用,對數據生命周期各個環節都提供了相應支持。數據門戶提供的工具都是聲明式的,也就是讓使用者只需要說明要實現什么目的,具體實現的復雜細節都隱藏起來,對使用者更友好。
通過這些工具,可以讓業務部門的 RD 、分析師、PM 等將精力放在業務分析本身,而不是去學習大量數據基礎設施的使用方法。