Strom及DRPC效能測試與改進

晚來風急發表於2017-07-03
參考1:storm效能測試報告
  參考2:Storm DRPC 使用
  參考3:Storm DRPC 使用及訪問C++ Bolt問題的解決方法
  參考4:Storm 多語言支援之ShellBolt原理及改進
  參考5:Base64編碼及編碼效能測試
  參考6:Base64編碼及編碼效能測試 [改進]
  參考7:zlib使用與效能測試
  參考8:十分簡單的redis使用說明及效能測試
  [參考1]的結論與侷限
  參考種對Storm效能進行測試,得出了以下結論:
  storm單條流水線的處理能力大約為20000 tupe/s, (每個tuple大小為1000位元組)
  storm系統本省的處理延遲為毫秒級
  在叢集中橫向擴充套件可以增加系統的處理能力,實測結果為1.6倍
  Storm中大量的使用了執行緒,即使單條處理流水線的系統,也有十幾個執行緒在同時執行,所以幾乎所有的16個CPU都在執行狀態,load average 約為 3.5
  Jvm GC一般情況下對系統效能影響有限,但是記憶體緊張時,GC會成為系統效能的瓶頸
  使用外部處理程式效能下降明顯,所以在高效能要求下,儘量使用storm內建的處理模式
  作者對strom的處理能力和可擴充套件性進行了測試,給出了很有說服力的資料。但還不能滿足我們的需要:
  1)由於作者使用的tuple為1000位元組,也就是1K,資料量相對較小,而在實際使用過程中,storm作為實時流處理系統,處理的資料可能比較大。比如我們用來進行影像處理,一個圖片可能有1M左右。這時候storm的效能如何呢?
  2)為了簡化storm的整合,我們使用DRPC來訪問storm,具體用法可參見[參考2]和[參考3],在DRPC訪問時,資料需要從DRPCClient傳送至DRPCServer,再由DRPCServer傳送給topology中的spout,spoout傳送給Bolt……..;當資料處理完畢後,還要由Bolt返回給DPRCServer,由DRPCServer返回給DRPCClient。
  增加了這些步驟以後,Strom DRPC的效能究竟如何呢?
  3)作者在[參考1]中提到,使用外部處理程式時Storm的效能明顯下降,大概只有1/10的效能。但是我們在實際使用中,可能經常是在已有的基礎上,將功能整合到Storm中執行。通俗點說:實際情況是我們經常使用外部處理程式,這種情況下,怎麼能提高Storm的效能呢?關於這點可以檢視[參考4]。我們使用JNI來解決。
  測試與結論
  1)測試環境
  測試環境如圖所示
  有客戶端和兩臺伺服器組成。
  客戶端為虛擬機器,單核3.2GHz  1G 記憶體,100M頻寬。
  伺服器也是虛擬機器,8核2.2GHz,8G記憶體,1G頻寬。
  DRPC Topology由一個DRPCSpout,CPPBolt和一個ReturnResult組成。功能是接收一個字串並返回。
  Topology執行在一個work中,Spout,Bolt分別由不同的執行緒執行。
 2)測試方法
  在Client啟動0-100多個執行緒,不停的訪問Topology,向其傳送一個字串(1K-1M)。Topology會原封不動的返回該字串。
  測試過程就不詳細展開了。直接說測試結果。
  3)測試結論
  該測試中,處理速度主要受限於客戶端頻寬。也就是說由於資料量大,客戶端發的速度慢,低於Storm中topology的處理速度。
  因此該測試只能得出DRPC方式中單個請求在不同資料大小時,storm的延遲時間。
  簡而言之,StormDRPC方式中,最小延遲為50ms(資料小於1K),當資料量大時,256K資料,延遲為125ms,512K時延遲為208ms。
  所以Storm資料量較大的時,處理的延遲還是比較大的。
  當然以上僅是在特定環境中的測試,僅供參考。
  改進方法
  根據個人經驗,針對以上Storm延遲可以由以下改進方法:
  1)資料可以先壓縮後再交給storm處理,在具體的bolt中對其進行解壓縮。根據個人測試zlib壓縮1M的資料,壓縮率為80%,既可以將資料研所為原來的20%。從而可以減小資料量,提高效率。而zlib對1M資料進行壓縮、解壓縮所用時間在10ms以內。可以使情況選用。見[參考7]
  2)storm本身採用字元型傳輸,對於二進位制資料必須進行編碼。可採用base64編碼。參見[參考5],base64對1M資料的編碼,解碼時間也分別小於10ms。
  3)在DRPC測試中,資料從Clinet到DRPCServer,到DRPC SPOUT,到BOLT,到RETURN Result,在到DRPCSERVER,最後返回Client傳輸多次,可以考慮使用記憶體資料庫如redis,Client直接將資料放入redis,將其在redis中的路徑進行傳輸,在需要時,由bolt從redis中獲取。參見[參考8]。將1M資料在redis中存取,耗時也分別在10-20ms。
  4)對於外部處理程式,如C++,可以採用JNI的方式,對ShellBolt進行改進,而不是啟動新的程式在通過Json編碼,Pipe傳輸與之通訊,從而也可以提交效率。參見[參考4]。
最新內容請見作者的GitHub頁:http://qaseven.github.io/


相關文章