從無到有、從小到大,今日頭條大數(shù)據(jù)平臺實踐經(jīng)歷的那些坑
原創(chuàng)【51CTO.com原創(chuàng)稿件】隨著公司規(guī)模的發(fā)展,數(shù)據(jù)量呈遞增式爆棚,他也見證了基礎(chǔ)數(shù)據(jù)平臺從無到有、從小到大的歷程。頭條在這一發(fā)展過程中對于數(shù)據(jù)使用及難度都經(jīng)歷了數(shù)量級的變化。本文將與大家分享數(shù)據(jù)平臺經(jīng)歷的各種坑及一些重要的技術(shù)決策。
基礎(chǔ)數(shù)據(jù)平臺的建設(shè)歷程
為什么要建設(shè)基礎(chǔ)數(shù)據(jù)平臺?
對于初創(chuàng)公司來講,核心是服務(wù)好用戶,做好產(chǎn)品功能的迭代。當(dāng)公司發(fā)展到一定階段,業(yè)務(wù)開始多元化并開始精細(xì)化運營,數(shù)據(jù)需求變多,產(chǎn)生的數(shù)據(jù)量和數(shù)據(jù)處理復(fù)雜度也大幅增加,這時就該建設(shè)基礎(chǔ)數(shù)據(jù)平臺了。
2014 年,頭條每天只有幾百萬活躍用戶,支撐好產(chǎn)品是首要任務(wù),并沒有專門的人負(fù)責(zé)做數(shù)據(jù)。眾多復(fù)雜業(yè)務(wù)的上線,同步會招聘大量的 PM(產(chǎn)品經(jīng)理)和運營。基于刻到骨子里的數(shù)據(jù)驅(qū)動的思想,各種各樣的數(shù)據(jù)需求源源不斷的被提上來,這時不再是幾個數(shù)據(jù)工程師單打獨斗就能解決問題了,而讓PM 和運營直接分析數(shù)據(jù)的門檻也很高。
面對這些情況,頭條的做法是成立數(shù)據(jù)平臺團隊,把數(shù)據(jù)基礎(chǔ)設(shè)施像 Hadoop、Hive、Spark、Kylin 等封裝成工具,把這些工具結(jié)合通用的分析模式整合成完整的解決方案,再把這些解決方案通過平臺的形式,提供給業(yè)務(wù)部門使用。
這里需要注意數(shù)據(jù)平臺的發(fā)展是一個演進的過程,并不需要追求一開始就大而全,不同階段采用的技術(shù)能匹配當(dāng)時需求就好。
基礎(chǔ)數(shù)據(jù)平臺的職責(zé)什么?
數(shù)據(jù)平臺的需求最初來自推薦業(yè)務(wù),從用戶的閱讀需求出發(fā),搭建面向全公司的通用數(shù)據(jù)平臺。其中,用戶數(shù)據(jù)(內(nèi)容偏愛、行為軌跡、閱讀時間等)是頭條最龐大的數(shù)據(jù)源,這些被記錄下來的數(shù)據(jù)反映了用戶的興趣,會以各種形式傳輸和存儲,并提供給全公司各個業(yè)務(wù)系統(tǒng)來調(diào)用。
還要維護面向 RD(分析師)數(shù)據(jù)工具集(日志收集、入庫、調(diào)度、依賴管理、查詢、元數(shù)據(jù)、報表),面向 PM、運營的通用用戶行為分析平臺,底層查詢引擎(Hive,Presto,Kylin 等 OLAP 查詢引擎,支撐上層數(shù)據(jù)平臺和數(shù)據(jù)倉庫),平臺基礎(chǔ)數(shù)據(jù)倉庫及協(xié)助維護業(yè)務(wù)部門數(shù)據(jù)倉庫。
面臨哪些挑戰(zhàn)?
當(dāng)前,頭條每日處理數(shù)據(jù)量為 7.8 PB、訓(xùn)練樣本量 200 億條、服務(wù)器總量 40000 臺、Hadoop 節(jié)點 3000 臺。
數(shù)據(jù)生命周期分為生成、傳輸、入庫和統(tǒng)計/分析/挖掘,每個環(huán)節(jié)的難度都會隨著數(shù)據(jù)規(guī)模的變大而上升。平臺建設(shè)面臨的挑戰(zhàn)是由龐大的數(shù)據(jù)量和業(yè)務(wù)復(fù)雜度給數(shù)據(jù)生成、采集、傳輸、存儲和計算等帶來的一系列問題。
(1)數(shù)據(jù)生成與采集——SDK、用戶埋點
一般情況下,數(shù)據(jù)生成與采集是很簡單的事,但對于頭條這個功能眾多的 APP 來講,難點就在于每個功能背后都是一個團隊獨立運營。如果每個團隊都用自研的數(shù)據(jù)采集方法,那會給后續(xù)的進程帶來巨大的困擾。
怎么辦呢?因為頭條屬于 C 端業(yè)務(wù)公司,主要以日志形式為主,數(shù)據(jù)的主要來源是用戶行為,那么就采用事件模型來描述日志,以 SDK 形式接入,支持客戶端、服務(wù)端埋點。
這里需要注意的是:數(shù)據(jù)質(zhì)量很重要,埋點規(guī)范趁早確立,臟數(shù)據(jù)是不可避免的,可以引入必要的約束、清洗等。
- 埋點。埋點是用戶在使用某一個功能時,產(chǎn)生的一段數(shù)據(jù)。頭條初期,埋點由各業(yè)務(wù)場景自定義日志格式,之后埋點統(tǒng)一到事件模型,保證了信息的結(jié)構(gòu)化和自描述,降低了后續(xù)使用成本,并復(fù)用統(tǒng)一的解析和清洗流程、數(shù)據(jù)倉庫的入庫和行為分析平臺的導(dǎo)入。
埋點的管理,也由通過文檔、Wiki 等方式演進成埋點管理系統(tǒng),覆蓋整個埋點生命周期。這樣一來,也得到了埋點元信息的描述,后續(xù)可應(yīng)用在數(shù)據(jù)清洗、分析平臺等場景,同時埋點的上線流程實現(xiàn)標(biāo)準(zhǔn)化,客戶端也可進行自動化測試。
SDK。數(shù)據(jù)平臺實現(xiàn)了通用的客戶端埋點 SDK 和服務(wù)端埋點 SDK,放棄之前按約定生成數(shù)據(jù)的方式,可以保證生成的日志符合埋點規(guī)范,并統(tǒng)一 App 啟動、設(shè)備標(biāo)識等的基本口徑,也減少了新 App 適配成本。
對數(shù)據(jù)的描述由使用 JSON 改為 Protobuf,這樣就可通過 IDL 實現(xiàn)強制約束,包括數(shù)據(jù)類型、字段命名等。
除了日志數(shù)據(jù),關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)也是數(shù)據(jù)分析的重要來源。頭條在數(shù)據(jù)的采集方式上,用 Spark 實現(xiàn)類 Sqoop 的分布式抓取替代了早期定期用單機全量抓取 MySQL 數(shù)據(jù)表的方式,有效的提升了抓取速度,突破了單機瓶頸。
再之后為了減少 MySQL 壓力,選用 Canal 來接收 MySQL binlog,離線 merge 出全量表,這樣就不再直接讀 MySQL 了,而且對千萬/億級大表的處理速度也會更快。
(2)數(shù)據(jù)傳輸——Kafka 做消息總線連接在線和離線系統(tǒng)
數(shù)據(jù)在客戶端向服務(wù)端回傳或者直接在服務(wù)端產(chǎn)生時,可以認(rèn)為是在線狀態(tài)。當(dāng)數(shù)據(jù)落地到統(tǒng)計分析相關(guān)的基礎(chǔ)設(shè)施時,就變成離線的狀態(tài)了。在線系統(tǒng)和離線系統(tǒng)采用消息隊列來連接。
頭條的數(shù)據(jù)傳輸以 Kafka 作為數(shù)據(jù)總線,所有實時和離線數(shù)據(jù)的接入都要通過 Kafka,包括日志、binlog 等。這里值得注意的是:盡早引入消息隊列,與業(yè)務(wù)系統(tǒng)解耦。
頭條的數(shù)據(jù)基礎(chǔ)設(shè)施以社區(qū)開源版本作為基礎(chǔ),并做了大量的改進,也回饋給了社區(qū),同時還有很多自研的組件。
因為以目前的數(shù)據(jù)和集群規(guī)模,直接使用社區(qū)版本乃至企業(yè)版的產(chǎn)品,都會遇到大量困難。像數(shù)據(jù)接入,就使用自研 Databus,作為單機 Agent,封裝 Kafka 寫入,提供異步寫入、buffer、統(tǒng)一配置等 feature。
Kafka 數(shù)據(jù)通過 Dump 落地到 HDFS,供后續(xù)離線處理使用。隨著數(shù)據(jù)規(guī)模的增加,Dump 的實現(xiàn)也經(jīng)歷了幾個階段。最初實現(xiàn)用的是類似 Flume 模式的單機上傳,很快遇到了瓶頸,實現(xiàn)改成了通過 Storm 來實現(xiàn)多機分布式的上傳,支持的數(shù)據(jù)吞吐量大幅增加。
現(xiàn)在開發(fā)了一個叫 DumpService 的服務(wù),作為托管服務(wù)方便整合到平臺工具上,底層實現(xiàn)切換到了 SparkStreaming,并實現(xiàn)了 exactly-once 語義,保證 Dump 數(shù)據(jù)不丟不重。
(3)數(shù)據(jù)入庫——數(shù)據(jù)倉庫、ETL(抽取轉(zhuǎn)換加載)
頭條的數(shù)據(jù)源很復(fù)雜,直接拿來做分析并不方便。但是到數(shù)據(jù)倉庫這一層級,會通過數(shù)據(jù)處理的過程,也就是 ETL,把它建設(shè)成一個層次完備的適合分析的一個個有價值的數(shù)倉。在數(shù)倉之上,就可以讓數(shù)據(jù)分析師和數(shù)據(jù) RD 通過 SQL 和多維分析等更高效的手段使用數(shù)據(jù)。
數(shù)據(jù)倉庫中數(shù)據(jù)表的元信息都放在 Hivemetastore 里,數(shù)據(jù)表在 HDFS 上的存儲格式以 Parquet 為主,這是一種列式存儲格式,對于嵌套數(shù)據(jù)結(jié)構(gòu)的支持也很好。
頭條有多種 ETL 的實現(xiàn)模式在并存,對于底層數(shù)據(jù)構(gòu)建,一種選擇是使用 Python 通過 HadoopStreaming 來實現(xiàn) Map Reduce 的任務(wù),但現(xiàn)在更傾向于使用 Spark 直接生成 Parquet 數(shù)據(jù),Spark 相比 MapReduce 有更豐富的處理原語,代碼實現(xiàn)可以更簡潔,也減少了中間數(shù)據(jù)的落地量。對于高層次的數(shù)據(jù)表,會直接使用 HiveSQL 來描述 ETL 過程。
(4)數(shù)據(jù)計算——計算引擎的演進
數(shù)據(jù)倉庫中的數(shù)據(jù)表如何能被高效的查詢很關(guān)鍵,因為這會直接關(guān)系到數(shù)據(jù)分析的效率。常見的查詢引擎可以歸到三個模式中,Batch 類、MPP 類、Cube 類,頭條在 3 種模式上都有所應(yīng)用。
頭條最早使用的查詢引擎是 InfoBright,Infopight 可以認(rèn)為是支持了列式存儲的 MySQL,對分析類查詢更友好,但 Infopight 只支持單機。隨著數(shù)據(jù)量的增加,很快換成了 Hive,Hive 是一個很穩(wěn)定的選擇,但速度一般。
為了更好的支持 Adhoc 交互式查詢,頭條開始調(diào)研 MPP 類查詢引擎,先后使用過 Impala 和 Presto,但在頭條的數(shù)據(jù)量級下都遇到了穩(wěn)定性的問題。
頭條現(xiàn)在的方案是混合使用 Spark SQL 和 Hive,并自研 QAP 查詢分析系統(tǒng),自動分析并分發(fā)查詢 SQL 到適合的查詢引擎。在 Cube 類查詢引擎上,頭條采用了 Kylin,現(xiàn)在也是 Kylin 在國內(nèi)***的用戶之一。
(5)數(shù)據(jù)門戶——為業(yè)務(wù)的數(shù)據(jù)分析提供整體解決方案
對于大部分需求相對簡單的公司來說,數(shù)據(jù)最終可以產(chǎn)出報表就夠用了,如做一個面向管理層的報表,可以讓老板直觀的了解一些關(guān)鍵性指標(biāo),這是最基礎(chǔ)的數(shù)據(jù)應(yīng)用模式。
再深入一點,就需要匯總各種來源的業(yè)務(wù)數(shù)據(jù),提供多種維度和指標(biāo)來進行更深入的探索型分析,得到的結(jié)論用來指導(dǎo)產(chǎn)品的迭代和運營。頭條絕大部分業(yè)務(wù)都是數(shù)據(jù)驅(qū)動的,都需要產(chǎn)出和分析大量的數(shù)據(jù),這就或多或少需要用到平臺提供的系列工具。
頭條開發(fā)了一套叫數(shù)據(jù)門戶的平臺系統(tǒng),提供給業(yè)務(wù)部門使用,對數(shù)據(jù)生命周期各個環(huán)節(jié)都提供了相應(yīng)支持。數(shù)據(jù)門戶提供的工具都是聲明式的,也就是讓使用者只需要說明要實現(xiàn)什么目的,具體實現(xiàn)的復(fù)雜細(xì)節(jié)都隱藏起來,對使用者更友好。
通過這些工具,可以讓業(yè)務(wù)部門的 RD 、分析師、PM 等將精力放在業(yè)務(wù)分析本身,而不是去學(xué)習(xí)大量數(shù)據(jù)基礎(chǔ)設(shè)施的使用方法。
數(shù)據(jù)抽取平臺 QueryEditor
數(shù)據(jù)抽取平臺 QueryEdito 使用界面
數(shù)據(jù)抽取平臺 QueryEditor,用于數(shù)據(jù)生命周期管理,對 Kafka 數(shù)據(jù) Dump、數(shù)據(jù)倉庫入庫、SQL 查詢托管等做了統(tǒng)一支持。
結(jié)語
基礎(chǔ)數(shù)據(jù)平臺的建設(shè)理念是通過提供整體解決方案,降低數(shù)據(jù)使用門檻,方便各種業(yè)務(wù)接入?;ヂ?lián)網(wǎng)產(chǎn)品的數(shù)據(jù)分析模式也是相對固定的,比如事件多維分析、留存分析、漏斗分析等,把這些分析模式抽象出工具,也能覆蓋住大部分常用需求。
同時,期望參與業(yè)務(wù)的人比如 PM 等能更直接的掌握數(shù)據(jù),通過相關(guān)工具的支持自行實現(xiàn)數(shù)據(jù)需求,盡量解放業(yè)務(wù)部門工程師的生產(chǎn)力,不至于被各種臨時跑數(shù)需求困擾。而對于更專業(yè)的數(shù)據(jù)分析師的工作,也會提供更專業(yè)的工具支持。
王燁
今日頭條數(shù)據(jù)平臺架構(gòu)師
2014 年加入今日頭條,目前負(fù)責(zé)頭條基礎(chǔ)數(shù)據(jù)平臺的技術(shù)架構(gòu),解決海量數(shù)據(jù)規(guī)模下推薦系統(tǒng)和用戶產(chǎn)品的統(tǒng)計分析問題,并見證了頭條數(shù)據(jù)平臺從無到有、從小到大的歷程。加入頭條前,曾就職于豆瓣負(fù)責(zé) Antispam 系統(tǒng)的研發(fā)。
【51CTO原創(chuàng)稿件,合作站點轉(zhuǎn)載請注明原文作者和出處為51CTO.com】