深度分析推ter Heron
原始鏈接:http://www.longda.us/?p=529
2015年6月1號, 推ter 對外宣講了他們的Heron系統, 從ppt和論文中,看起來完爆storm。昨天,抽空把論文,仔細讀了一遍, 把個人筆記和心得分享一下:
最后總結:
Heron更適合超大規模的機器, 超過1000臺機器以上的集群。 在穩定性上有更優異的表現, 在性能上,表現一般甚至稍弱一些,在資源使用上,可以和其他編程框架共享集群資源,但topology級別會更浪費一些資源。
而從應用的角度,應用更偏向于大應用,小應用的話,會多一點點資源浪費, 對于大應用,debug-ability的重要性逐漸提升。 另外對于task的設計, task會走向更重更復雜, 而JStorm的task是向更小更輕量去走。
未來JStorm可以把自動降級策略引入, 通過實現阿里媽媽的ASM, debug-ability應該遠超過storm, 不會遜色于Heron, 甚至更強。
現狀:
所有的老的生產環境的topology已經運行在Heron上, 每天大概處理幾十T的數據, billions of消息
為什么要重新設計Heron:
【題外話】這里完全引用作者吐槽的問題, 不少問題,其實JStorm已經解決
(1)debug-ability 很差, 出現問題,很難發現
1.1 多個task運行在一個系統進程中, 很難定位問題。需要一個清晰的邏輯計算單元到物理計算單元的關系
(2)需要一種更高級的資源池管理系統
2.1 可以和其他編程框架共享資源, 說白了,就是類似yarn/mesos, 而在推ter就是Aurora
2.2 更簡單的彈性擴容和縮容 集群
2.3 因為不同task,對資源需求是不一樣的, 而storm會公平對待每個worker, 因此會存在worker浪費內存問題。當worker內存特別大時, 進行jstack或heap dump時,特別容易引起gc,導致被supervisor干掉
2.4 經常為了避免性能故障,常常進行超量資源分配, 原本100個core,分配了200個
(3)認為Storm設計不合理的地方
3.1 一個executor 存在2個線程, 一個執行線程, 一個發送線程, 并且一個executor運行多個task, task的調度完全依賴來源的tuple, 很不方便確認哪個task出了問題。
3.2 因為多種task運行在一個worker中, 無法明確出每種task使用的資源, 也很難定位出問題的task,當出現性能問題或其他行為時, 常用就是重啟topology, 重啟后就好了,因為task進行了重新調度
3.3 日志打到同一個文件中,也很難查找問題,尤其是當某個task瘋狂的打印日志時
3.4 當一個task掛掉了,直接會干掉worker,并強迫其他運行好的task被kill掉
3.5 最大的問題是,當topology某個部分出現問題時, 會影響到topology其他的環節
3.6 gc引起了大量的問題
3.7 一條消息至少經過4個線程, 4個隊列, 這會觸發線程切換和隊列競爭問題
3.8 nimbus功能太多, 調度/監控/分發jar/metric report, 經常會成為系統的bottleneck
3.9 storm的worker沒有做到資源保留和資源隔離, 因此存在一個worker會影響到另外的worker。 而現有的isolation調度會帶來資源浪費問題。 Storm on Yarn也沒有完全解決這個問題。
3.10 zookeeper成為系統的瓶頸, 當集群規模增大時。 有些系統為了降低zk心態,新增了tracker,但tracker增加了系統運維難度。
3.11 nimbus是系統單點
3.12 缺乏反壓機制
3.12.1 當receiver忙不過來時, sender就直接扔棄掉tuple,
3.12.2 如果關掉acker機制, 那無法量化drop掉的tuple
3.12.3 因為上游worker執行的計算就被扔棄掉。
3.12.4. 系統會變的難以預測(less predictable.)
3.13 常常出現性能問題, 導致tuple fail, tuple replay, 執行變慢
3.13.1 不良的replay, 任意一個tuple失敗了,都會導致整個tuple tree fail, 不良的設計時(比如不重要的tuple失敗),會導致tuple輕易被重發
3.13.2 當內存很大時,長時間的gc,導致處理延時,甚至被誤殺
3.13.3 隊列競爭
Heron設計原則:
(1)兼容老的storm api
(2)實現2種策略, At most once/At least once
架構:
調度器
Aurora是一個基于mesos的通用service scheduler, Hero基于Aurora 實現了一套Topology Scheduler, 并且這個調度器已經提供了一定的抽象,可以移植到yarn/mesos/ec2(我的理解應該稍加修改就可以運行在其他通用型調度器上)
2/ 第一個container 運行 Topology Manager(TM), 其他的container 內部會運行一個Stream manager/Metrics Manager 和多個Heron Instance。 這里一個container類似一個docker感念,表示一個資源集合,是Aurora的調度單元, 多個container可以運行在一臺機器上, 分配多少container由Aurora根據現有資源情況進行分配, 另外一個container設置了cgroup
Topology Manager
1. tm伴隨整個topology生命周期, 提供topology狀態的唯一contact (類似yarn的app master)
2. 可以一主多備, 大家搶占zk 節點, 誰勝出,誰為master, 其他為standby
Stream manager(SM)
最大的改變就是源自Stream manager, Stream manager就相當于一個container的tuple的總線(hub)。 所有的Hero Instance(HI)都連接SM進行send/receive
如果container內部一個HI 發送數據到另外一個HI,走的是本地快速通道。
Backpressure 反壓機制
當下游處理速度變慢后,通過反壓機制,可以通知上游進行減速, 避免數據因buffer被塞滿而丟失,并因此帶來資源浪費。
TCP 反壓:
當一個HI 處理慢了后,則該HI的接收buffer會被填滿, 緊接著本地SM的sending buffer被填滿, ? 然后會傳播到其他的SM和上游HI。
這個機制很容易實現,但在實際使用中,存在很多問題。因為多個HI 共用SM, 不僅將上游的HI 降速了,也把下游的HI 降速。從而整個topology速度全部下架,并且長時間的降級。
Spout 反壓。
這個機制是結合TCP 反壓機制, 一旦SM 發現一個或多個HI 速度變慢,立刻對本地spout進行降級, 停止從這些spout讀取數據。并且受影響的SM 會發送一個特殊的start backpressure message 給其他的sm,要求他們對spout進行本地降級。一旦出問題的HI 恢復速度后,本地的SM 會發送 stop backpressure message 解除降級。
Stage-by-Stage 反壓
這個類似spout反壓,但是一級一級向上反壓。
Heron最后采用的是spout反壓, 因為實現比較簡單,而且降級響應非常迅速。 并且可以很快定位到那個HI 處理速度慢了。 每個socket channel都綁定了一個buffer, 當buffer 的 queue size超過警戒水位時,觸發反壓,減少時,接觸反壓。
這種機制,不會丟棄tuple,除了機器宕機。
topology可以設置打開或關閉。
Heron Instance
(1) 一個task 一個進程,
(2) 所有的進程之間通信都是使用protocol buffer
(3) 一個gateway線程, 一個執行線程。 gateway線程負責和外圍通信, sm/mm。 執行線程和現有storm的執行線程非常類似。執行線程會收集所有的metrics,然后發送給gateway線程。
(4)這個data-in/data-out隊列會限定大小, 當data-in 隊列滿了的時候, gateway線程停止從local SM 讀取數據。同理如果data-out隊列滿,gateway會認為local SM不想接受更多的數據。 執行線程就不再emit或執行更多的tuple。
(5)data-in/data-out隊列大小不是固定, 如果是固定時, 當網絡顛簸時,會導致內存中大量數據堆積無法發送出去,并觸發GC, 并導致進一步的降級。因此是動態調整, 定期調整隊列大小。 如果隊列的capacity超過閥值時, 對其進行減半。這個操作持續進行指導隊列的capacity維持在一個穩定的水位或0。這種方式有利避免GC的影響。 當隊列的capcity小于某個閥值時, 會緩慢增長到配置大小或最大capacity值。
Metrics manager(mm)
收集所有的metrics,包括系統的和用戶的metrics, 也包含SM的。 mm會發送metrics 給monitor系統(類似ganglia系統),同樣也會給TM.
流程:
(1)提交任務, Aurora分配必要的資源和在一些機器上調度container
(2)TM 在一個container上運行起來,并注冊到ZK
(3)每個container的SM 查詢ZK 找到TM, 向TM 發送心跳。
(4)當所有的SM 連上TM后, TM 執行分配算法, 不同的compoent到不同的container。 這個階段叫物理執行計劃(類似SQL解析和執行過程)。并將執行計劃放到ZK。
(5)SM 下載執行計劃,并開始相互之間進行連接, 與此同時, 啟動HI, hi開始發現container,下載他們的執行計劃,并開始執行
(6)整個topology完成初始化,開始正式的發送和接收數據。
三種failure case
1. 進程掛了
1.1 如果TM 掛了, container會重啟TM, TM 會從ZK 上重新下載執行計劃。如果有一主多備,則備機會被promotion。 所有SM 會切到新的TM
1.2 如果SM 掛了, container依舊會重啟TM, 并從ZK 下載執行計劃, 并檢查是否有變化。其他的SM 會連到新的SM
1.3 如果HI 掛了, 重啟并下載執行計劃,并重新執行。
外圍系統
外圍系統就介紹一下Heron Tracker
Heron Tracker
負責收集topology的信息, 類似一個gateway的角色。 通過watch zk,發現新的TM, 并獲取topology的一些原數據。是一種Aurora service, 提供load balance在多個instance之間。
可以提供REST API。可以獲取
(1) 邏輯和物理執行計劃
(2) 各種metrics, 系統的和用戶的
(3)日志link
Heron UI/VIZ
UI 提供傳統的UI 方式。
VIZ 提供全新的UI, 可以看到更多的metrics, 曲線和健康檢查。比UI 炫酷很多。
性能報告和測試過程:
了解整個系統架構和工作流程后, 后面的性能測試報告, 沒有看了, 也差不多有個概念了。
個人思考和總結:
(1) 相對于JStorm, Heron把角色剝離的更清晰明了。
(1.1)調度器
scheduler 負責container的調度,這個調度非常的純粹,可以直接復用yarn/mesos/, 現有的TM 其實就是nimbus,唯一一點變化就是這個TM 只負責自己topology的信息, 不是負責所有topology。這個TM 就相當于yarn下的app master, 非常適合目前主流的調度系統。 當集群規模非常大的時候, 并且每個應用都比較大的時候, 這個架構會非避免nimbus成為瓶頸。 不過storm-on-yarn模式下, 可能通過一個nimbus管理一個小的邏輯集群,也可以解決這個問題, 并且當topology 比較小的時候, 可以通過大家公用一個nimbus,節省一些資源。
(1.2) container
這里特別要把container拿出來仔細說一下, 這個container是Auron的一個資源單元。如果將Auron類似JStorm的worker, 你就會發現角色和架構是多么的類似。
(1.2.1) container和jstorm的worker都可以設置cgroup,達到一定的資源隔離
(1.2.2)container內部的SM/MM 其實就類似jstorm worker內部drainer/dispatcher/metricsreport線程。
但container 相對jstorm 的worker 還有一些其他的優缺點:
優點:
(1.2.3)這個粒度可以控制的更自由, 這個container 可以控制cpu 到更多的核,更多的內存上限。 但jstorm的worker 基本上最多10個核, 而且當內存太大,在core dump和gc的時候壓力會比較大。
(1.2.4)container還帶一定的supervisor的功能,當container內部任何進程掛了, container都會負責把它重啟, 因此整個系統的心態邏輯會非常的簡單。 ?Auron <–> container, ? ?Container <– > tm/sm/mm/hi. ?整個系統的心跳壓力模型會更簡單, 心跳壓力(對ZK)也更小
性能:
ppt和文檔里面說性能有15倍以上的提升, 這個在某些設置下是可以達到這種效果, 但通常情況性能應該比JStorm還要差一點點。
如何達到這種效果呢,
(1)前提條件是, grouping方式不是選擇localOrShuffle或者localFirst
?就是把container設置的盡可能的大, 最好是獨占一臺機器。這樣SM和SM 之間的通信就會大幅減少, 而一個container內部的HI 通信走內部通道。因此會有更多的HI走內部通道。而jstorm/storm, worker比較多的時候, worker和worker之間會創建netty connection, 更多的netty connection會帶來更多的內存消耗和線程切換。 尤其是worker數超過200個以上時。
但為什么說通常情況下,性能應該還要比JStorm差一點點呢。
因為在生產環境, container 是不可能占有這么多資源, 否則Auron的調度太粗粒度,一臺機器只跑一個大container, 會導致更嚴重的資源浪費。正常情況下, 一個container綁定2 ~ 4個核, 這個時候,和一個普通的jstorm worker沒有什么區別, 但jstorm worker內部task之間數據傳輸的效率會遠遠高于Heron, 因為Heron的HI 之間即使是走進程間通信方式, 也逃脫不了序列化和反序化的動作, 這個動作肯定會耗時, 更不用說IPC 之間的通信效率和進程內的通信效率。
資源利用率:
Heron 可以非常精準的控制資源使用情況, 能夠保證, 申請多少資源,就會用多少資源。 在大集群這個級別會節省資源,在topology級別浪費資源。
如果JStorm-on-yarn這種系統下, 因為每個邏輯集群會超量申請一些資源, 因此資源可能會多有少量浪費。無法做到像Heron一樣精準。 如果改造nimbus成為topology level 類似TM(騰訊在jstorm基礎上實現了這個功能), 這個問題就可以很好的解決。在普通standalone的JStorm模式下, jstorm不會浪費資源, 但因為Standalone,導致這些機器不能被其他編程框架使用, 因此也可以說浪費一定的資源。 但這種情況就是 資源隔離性– 資源利用率的一種平衡, 現在這種根據線上運行情況,浪費程度可以接受。
在topology這個粒度進行比較時, Heron應該會消耗掉更多的資源。 最大的問題在于, Heron中一個task就是一個process, 論文中沒有描敘這個process的公共線程, 可以肯定的是, 這個process比如還有大量的公共線程, 比如ZK-client/network-thread/container-heartbeat-thread, 一個task一個process,這種設計,相對于一個worker跑更多的task而言,肯定浪費了更多的CPU 和內存。
至于吐槽在Storm和JStorm,超量申請資源問題, 比如一個topology只要100 個cpu core能完成, 申請了600個core, 這個問題,在jstorm中是絕對不存在的, jstorm的cgroup設置是share + limit方式, 也就是上限是600 core,但topology如果用不到600個core, 別的topology可以搶占到cpu core。 在內存方面, jstorm的worker 內存申請量,是按照worker最大內存申請, 但現代操作系統早就做到了, 給你一個上限, 當你用不了這么多的時候, 其他進程可以搶占。
在穩定性和debug-ability這點上:
Heron 優勢非常大, 主要就是通過2點:
(1) 自動降級策略, 也就是論文說的backpressure, 這個對于大型應用是非常有效的, 也很顯著提高穩定性。
(2) 一個task一個process, 這個結合降級策略,可以非常快速定位到出錯的task, 另外因為一個task 一個process, task之間的影響會非常快, 另外也避免了一個進程使用過大的內存,從而觸發嚴重的GC 問題。
最后總結:
Heron更適合超大規模的機器, 超過1000臺機器以上的集群。 在穩定性上有更優異的表現, 在性能上,表現一般甚至稍弱一些,在資源使用上,可以和其他編程框架共享資源,但topology級別會更浪費一些資源。
另外應用更偏向于大應用,小應用的話,會多一點點資源浪費, 對于大應用,debug-ability的重要性逐漸提升。 另外對于task的設計, task會走向更重更復雜, 而JStorm的task是向更小更輕量去走。
未來JStorm可以把自動降級策略引入, 通過實現阿里媽媽的ASM, debug-ability應該遠超過storm, 不會遜色于Heron, 甚至更強。
其他流式編程框架
1.S4 Distributed Stream Computing Platform.?http://incubator.apache.org/s4/
2. Spark Streaming. https://spark.apache.org/streaming/ ?
3. Apache Samza. http://samza.incubator.apache.org
4. Tyler Akidau, Alex Balikov, Kaya Bekiroglu, Slava Chernyak, Josh?Haberman, Reuven Lax, Sam McVeety, Daniel Mills, Paul?Nordstrom, Sam Whittle: MillWheel: Fault-Tolerant Stream?Processing at Internet Scale.? PVLDB 6(11): 1033-1044 (2013)
5.?Mohamed H. Ali, Badrish Chandramouli, Jonathan Goldstein,Roman Schindlauer: The Extensibility Framework in Microsoft?StreamInsight.? ICDE?2011: 1242-1253
6. Rajagopal Ananthanarayanan, Venkatesh Basker, Sumit Das, Ashish?Gupta, Haifeng Jiang, Tianhao Qiu, Alexey Reznichenko, Deomid?Ryabkov, Manpreet Singh, Shivakumar Venkataraman: Photon:?Fault-tolerant and Scalable Joining of Continuous Data Streams.? SIGMOD?2013: 577-588
7. DataTorrent.?https://www.datatorrent.com
8. Simon Loesing, Martin Hentschel, Tim Kraska, Donald Kossmann:?Stormy: An Elastic and Highly Available Streaming Service in the?Cloud. EDBT/ICDT Workshops 2012: 55-60
本文由用戶 rbyt 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!