最近讀到了一篇關(guān)于在facebook如何構(gòu)建流式分布式處理系統(tǒng)的paper蒿辙。感覺系統(tǒng)設(shè)計(jì)折中的思路總結(jié)非常好拇泛。在數(shù)據(jù)應(yīng)用領(lǐng)域滨巴,我覺得任何已經(jīng)確認(rèn)效果的方法都會(huì)嘗試提高時(shí)效性來獲得更好的收益
一. Facebook實(shí)際使用流處理的應(yīng)用場景
- 用戶使用產(chǎn)品行為的埋點(diǎn)數(shù)據(jù)
- mobile app運(yùn)行埋點(diǎn)數(shù)據(jù) for developer
- facebook頁面統(tǒng)計(jì)數(shù)據(jù)(eg. trend)
- 總的設(shè)計(jì)目標(biāo):秒級(jí)別的延遲,每秒處理百GB級(jí)別的吞吐量
二. 設(shè)計(jì)的思考
系統(tǒng)設(shè)計(jì)對(duì)比圖
1. 支持的語言
主要思考點(diǎn):編寫應(yīng)用的難易程度俺叭,應(yīng)用實(shí)際運(yùn)行的performance
選擇:
- Declarative: 比如:SQL恭取,這類比較容易實(shí)現(xiàn)功能,但是可控的部分比較少
- Functional: 這類也比較容易實(shí)現(xiàn)
- Procedural:比如:c++ java python 可控程度最高熄守,性能最好
Facebook的選擇:
線上有3套流式處理架構(gòu)(Puma蜈垮,Stylus, Swift),支持Declarative和Procedural方式裕照。puma實(shí)現(xiàn)簡單攒发,適合調(diào)研需求。stylus復(fù)雜晋南,開發(fā)測試周期相對(duì)更長惠猿,適合確定的復(fù)雜的任務(wù)
2. 數(shù)據(jù)流傳輸?shù)姆绞?/h4>
這個(gè)選擇確定了后面的容錯(cuò)性,性能和可擴(kuò)展性
- 直接傳輸:比如:RPC或者zeromq搬俊。這類的好處是ms級(jí)別的延遲紊扬,速度快
- 使用broker中轉(zhuǎn):這類好處是網(wǎng)絡(luò)都經(jīng)過broker可控性更好
- 使用持久化隊(duì)列:比如:scribe和kafka蜒茄。這類的優(yōu)點(diǎn)是:讀寫異步唉擂,失敗恢復(fù)快,流量的重發(fā)易于debug
Facebook的選擇:
使用基于scribe的持久化隊(duì)列的方案檀葛,滿足秒級(jí)別延遲的業(yè)務(wù)需求玩祟。同時(shí)收獲了 - 更好的容錯(cuò)性
某些node失敗重新啟動(dòng)即可 - 更好的debug
node不符合預(yù)期,重放流量調(diào)試即可 - 更好的監(jiān)控
監(jiān)控隊(duì)列的長度 - 支持不同的流式處理工具
可以某些node使用puma而某些node使用Stylus屿聋,node組件化可以快速復(fù)用
3. node處理的語義
這部分主要是思考是否需要在特定條件下犧牲部分性能來保證100%準(zhǔn)確性
node主要做的工作
- 處理input events:查詢外部系統(tǒng)空扎,更新內(nèi)存中數(shù)據(jù)結(jié)構(gòu)
- 產(chǎn)出output: 處理完input數(shù)據(jù)后,產(chǎn)出output 供下游node使用
- 存儲(chǔ)checkpoints:存儲(chǔ)內(nèi)存中數(shù)據(jù)結(jié)構(gòu)润讥,存儲(chǔ)input的offset转锈,存儲(chǔ)output值
選擇: - at-least-once: 至少處理一次,先處理楚殿,后update offset撮慨,需要下游兼容重復(fù)的情況
- at-most-once: 至多處理一次,先update offset脆粥,后處理
- exactly-once: 需要支持事務(wù)操作砌溺,有操作代價(jià)
Facebook的選擇:
根據(jù)業(yè)務(wù)場景一般使用at-least-once和at-most-once。3個(gè)流式架構(gòu)支持不同的級(jí)別的語義
4. 狀態(tài)存儲(chǔ)的機(jī)制
選擇:
- 多副本冗余:使用多1倍的機(jī)器冗余每個(gè)node, 代價(jià)高
- 本地?cái)?shù)據(jù)庫存儲(chǔ)
- 遠(yuǎn)程分布式數(shù)據(jù)庫存儲(chǔ)
- 上游消息隊(duì)列備份
- 全局分布式snapshot
Facebook的選擇: - 支持本地?cái)?shù)據(jù)存儲(chǔ)
優(yōu)點(diǎn):沒有網(wǎng)絡(luò)開銷变隔,更加快速规伐。支持hdfs備份數(shù)據(jù)。
本地?cái)?shù)據(jù)庫存儲(chǔ)
-
支持遠(yuǎn)程數(shù)據(jù)庫存儲(chǔ)
優(yōu)點(diǎn):支持append only 提高吞吐匣缘,降低延遲猖闪。merge的時(shí)機(jī)很重要鲜棠。
遠(yuǎn)程數(shù)據(jù)庫存儲(chǔ)
5. 數(shù)據(jù)回放的支持
在某些場景,數(shù)據(jù)回放十分有用
- 驗(yàn)證一個(gè)新的流處理application是否正確
- 增加了新的統(tǒng)計(jì)信息的維度萧朝,需要補(bǔ)充數(shù)據(jù)
- debug application
選擇: - 只通過流式: 通過緩存消息隊(duì)列實(shí)現(xiàn)岔留,很難支持很長時(shí)間
- 通過流式和批量處理: 支持2個(gè)存儲(chǔ)系統(tǒng),短時(shí)間的通過緩存的消息隊(duì)列检柬。長時(shí)間的通過分布式存儲(chǔ)献联,如:hive。
- 通過支持批量處理的流式處理:比如:spark streaming
Facebook的選擇: - 通過scribe支持短期數(shù)據(jù)的回放
- 通過mapreduce on hive 實(shí)現(xiàn)長期數(shù)據(jù)的處理
- 工具支持1套代碼2處都能運(yùn)行
三. 總體系統(tǒng)架構(gòu)
流式處理系統(tǒng)架構(gòu)圖
- Scribe
系統(tǒng)總體輸入的源頭何址,數(shù)據(jù)流先進(jìn)入scribe隊(duì)列里逆。黃色箭頭表示數(shù)據(jù)流。node從scribe讀取數(shù)據(jù)處理完成后寫入scribe - Puma
puma支持filter 和 aggregation用爪。使用DSL編寫原押。針對(duì)于長久運(yùn)行,固定需求的查詢優(yōu)化(比如:最熱門的話題top10)偎血。filter的使用:如只關(guān)注處理#超級(jí)碗相關(guān)話題的post - Stylus
更底層的支持DAGnode結(jié)構(gòu)的流處理框架 - Laser
基于RocksDB的kv系統(tǒng)诸衔。適用于寫少讀多的場景。用于共享流處理產(chǎn)出的數(shù)據(jù) - Scuba
提供類似數(shù)據(jù)庫查詢的實(shí)時(shí)查詢 - Hive
存儲(chǔ)全量數(shù)據(jù)颇玷,按天分表笨农。基于Presto支持sql查詢