天天看點

揭開 Heron 性能面紗

整體heron 的架構設計就是storm-on-mesos 的架構。

這篇博文分為2部分

測試結果和測試過程

heron 性能分析

<a></a>

今年5月25号, heron開源了他們的源碼, 整個業界對heron 的性能都非常感興趣,我們花了3周的時間,完成heron的整個測試。

fastwordcount 測試用例 分為3個stage spout-&gt; split &gt; count, 使用流計算中最常用的shuffler和fieldgrouping 方式。

揭開 Heron 性能面紗
揭開 Heron 性能面紗

10 台a8, 32 核/128g

os: redhat rhel 7.2

jdk: jdk8

hdfs: 2.6.3

mesos: 0.25.0

aurora: 0.12.0

jstorm: 2.2.0

heron: 0.14.0 并打上heron最新性能優化patch

flink: 1.0.3

storm: 1.0.2

worker/container 記憶體設定4g

第一次跑,heron性能極差, 10個container隻有2w qps, 咨詢twitter, 告知,大量觸發反壓,可以打個patch 調整反壓政策

第二次跑(打上patch後),10個container可以到10多萬, 但其實和storm相比,也是差很多, 咨詢twitter 人員, 告知一個container内部task太多,容易發生反壓

第三次跑(修改container内部task數), 10個container 跑到20w qps, 但我們依舊不滿意,咨詢twitter, 他們告知 他們也就隻能跑20w qps, 并且告訴 一個很大問題, container内部的stream-manager的瓶頸是50w qps, 也就是一個container所有内部通信和外部通信的總和上限就是50w。

後面的分析,主要是分析heron 最大的噱頭 “10 倍storm性能” &amp; “減少3倍storm資源”, heron 有很多漂亮的設計, 這裡不贅述, 讀者可以自行閱讀我們之前的文章。

heron 一直号稱是storm 10倍性能, 但heron 對比的對象是storm 0.8.2, 這是3年前的storm,是上一代的storm, 而最新版storm 1.0.2 早已經是storm 0.8.2 的十倍性能。

heron在性能上存在2個緻命缺陷

失去了整個業界性能優化很大的一個方向, 流計算圖優化。其核心思想就是讓task盡量綁在一個程序中, 這樣task之間的資料,可以直接走程序内通信,無需反序列化和序列化。

為了提高穩定性, heron将每個task 獨立成為一個程序, 則會産生一個新的問題,就是task之間的通信都不會有程序内通信, 所有task通信都是走網絡, 都要經過序列化和反序列化, 引入了大量額外的計算.

如果想要圖優化, 則heron必須引入一層新的概念, 将多個task 連結到一個程序中, 但這個設計和heron的架構設計理念會沖突

每個container 的stream manager 會成為瓶頸, 一個container 内部的所有task 的資料(無論資料對外還是對内)通信都必須經過stream manager, 一個程序他的網絡tps是有上限的, 而stream-manager的上限就是50w qps, 則表示一個container的内部通道和外部通道總和就是50w qps. 大家都必須搶這個資源。

原來的一次網絡通信, 現在會變成3次網絡通信, task -》 目前container的streammanager -》 目标container的stream manager -》 目标task

heron 突出的 “省資源3倍”, 這個論點和3年前的storm相比,确實是可以這麼說,這個說法的背後技術:

反壓;過去storm 應用,為了應對每天的高峰, 必須要多申請資源, 否則當流量高峰來臨時, worker會爆掉。

大叢集部署,利用大叢集的削峰填谷能力和資源隔離能力。

對每個task的資源做限定, 限定cpu 用多少, 記憶體用多少,按需使用,無需超量申請。

但今天的storm已經今非昔比,而jstorm更是不一樣了。 jstorm反壓早就做到了第三版, 當下遊資料發生堆積時, 上遊spout早就做限流降級, 應用無需申請超量的資源。

今天jstorm-on-yarn/jstorm-on-docker, jstorm-on-yarn 已經上線,就是在大叢集上部署多個邏輯叢集, 讓大叢集削峰填谷和資源隔離都非常成熟。

jstorm 0.9.0/storm0.9.5 開始就有了task粒度資源排程器,就是task按自己需要,申請多少cpu和多少記憶體就配置設定多少記憶體。但jstorm從0.9.5 開始,排程的資源從task粒度恢複到worker粒度, 原因是:

叢集跑一段時間後,容易出現碎片, 即有的機器上有cpu slot但沒有記憶體 slot, 有的機器上有記憶體slot但沒有cpu slot

業務方很少遵守task 粒度去申請資源,反而偏愛worker粒度,簡單粗暴方式。

業務方有時超量申請資源, 隻需要10個cpu slot,但卻申請20個cpu

最終jstorm的方案是, 資源的粒度是到worker級别,但每台機器上配置動态監測, 實時根據負載情況調整自己的資源池政策, 很有效解決上述問題。

另外heron 資源上其實會引入1個小問題, 單個heron container會比單個jstorm/storm worker更消耗資源。

假設3個task運作在一個worker或container中,每個task 需要2g記憶體, 如果是jstorm或storm, 可能5g 記憶體就夠了, 每個task之間可以臨時share一下, 而heron container 則需要7g 甚至8g, 每個task 都需要2g,而且不能互相share, 另外一個container中還有streammanager/metricsmanager, 他們都需要記憶體。

原本worker級别的公共線程,在heron中現在需要在每個task程序中都配置上, 比如netty程序池,心跳線程, metrics 線程等等, 這些都在消耗cpu。