看介紹文檔貌似挺好:
https://github.com/alibaba/jstormhtml
阿里擁有本身的實時計算引擎java
相似於hadoop 中的MRpython
開源storm響應太慢git
開源社區的速度徹底跟不上Ali的需求github
下降將來運維成本web
提供更多技術支持,加快內部業務響應速度數據庫
現有Storm沒法知足一些需求apache
現有storm調度太簡單粗暴,沒法定製化編程
Storm 任務分配不平衡數組
RPC OOM一直沒有解決
監控太簡單
對ZK 訪問頻繁
JStorm相比Storm更穩定
Nimbus 實現HA:當一臺nimbus掛了,自動熱切到備份nimbus
原生Storm RPC:Zeromq 使用堆外內存,致使OS 內存不夠,Netty 致使OOM;JStorm底層RPC 採用netty + disruptor保證發送速度和接受速度是匹配的
新上線的任務不會衝擊老的任務:新調度從cpu,memory,disk,net 四個角度對任務進行分配,已經分配好的新任務,無需去搶佔老任務的cpu,memory,disk和net
Supervisor主線
Spout/Bolt 的open/prepar
全部IO, 序列化,反序列化
減小對ZK的訪問量:去掉大量無用的watch;task的心跳時間延長一倍;Task心跳檢測無需全ZK掃描。
JStorm相比Storm調度更強大
完全解決了storm 任務分配不均衡問題
從4個維度進行任務分配:CPU、Memory、Disk、Net
默認一個task,一個cpu slot。當task消耗更多的cpu時,能夠申請更多cpu slot
默認一個task,一個memory slot。當task須要更多內存時,能夠申請更多內存slot
默認task,不申請disk slot。當task 磁盤IO較重時,能夠申請disk slot
能夠強制某個component的task 運行在不一樣的節點上
能夠強制topology運行在單獨一個節點上
能夠自定義任務分配,提早預定任務分配到哪臺機器上,哪一個端口,多少個cpu slot,多少內存,是否申請磁盤
能夠預定上一次成功運行時的任務分配,上次task分配了什麼資源,此次仍是使用這些資源
JStorm相比Storm性能更好
JStorm 0.9.0 性能很是的好,使用netty時單worker 發送最大速度爲11萬QPS,使用zeromq時,最大速度爲12萬QPS。
JStorm 0.9.0 在使用Netty的狀況下,比Storm 0.9.0 使用netty狀況下,快10%, 而且JStorm netty是穩定的而Storm 的Netty是不穩定的
在使用ZeroMQ的狀況下, JStorm 0.9.0 比Storm 0.9.0 快30%
性能提高的緣由:
Zeromq 減小一次內存拷貝
增長反序列化線程
重寫採樣代碼,大幅減小採樣影響
優化ack代碼
優化緩衝map性能
Java 比clojure更底層
JStorm的其餘優化點
資源隔離。不一樣部門,使用不一樣的組名,每一個組有本身的Quato;不一樣組的資源隔離;採用cgroups 硬隔離
Classloader。解決應用的類和Jstorm的類發生衝突,應用的類在本身的類空間中
Task 內部異步化。Worker 內部全流水線模式,Spout nextTuple和ack/fail運行在不一樣線程
具體如何實現,請參考本ID的的博文系列 【jstorm-源碼解析】
JStorm 是一個相似Hadoop MapReduce的系統, 用戶按照指定的接口實現一個任務,而後將這個任務遞交給JStorm系統,Jstorm將這個任務跑起來,而且按7 * 24小時運行起來,一旦中間一個worker 發生意外故障, 調度器當即分配一個新的worker替換這個失效的worker。
所以,從應用的角度,JStorm 應用是一種遵照某種編程規範的分佈式應用。從系統角度, JStorm一套相似MapReduce的調度系統。 從數據的角度, 是一套基於流水線的消息處理機制。
實時計算如今是大數據領域中最火爆的一個方向,由於人們對數據的要求愈來愈高,實時性要求也愈來愈快,傳統的Hadoop Map Reduce,逐漸知足不了需求,所以在這個領域需求不斷。
在Storm和JStorm出現之前,市面上出現不少實時計算引擎,但自storm和JStorm出現後,基本上能夠說一統江湖: 究其優勢:
JStorm處理數據的方式是基於消息的流水線處理, 所以特別適合無狀態計算,也就是計算單元的依賴的數據所有在接受的消息中能夠找到, 而且最好一個數據流不依賴另一個數據流。
所以,經常用於
本處不細描敘Zookeeper安裝步驟
-s $HOME/.pythonbrew/etc/bashrc && source $HOME/.pythonbrew/etc/bashrc
pythonbrew install 2.6.7
pythonbrew switch 2.6.7
注意,若是當前系統是64位系統,則須要下載java 64位,若是是32爲系統,則下載32位java
wget http://download.zeromq.org/zeromq-2.1.7.tar.gz
tar zxf zeromq-2.1.7.tar.gz
cd zeromq-2.1.7
./configure
make
sudo make install
sudo ldconfig
若是沒有root權限,或當前用戶無sudo權限時,執行 「 ./configure --prefix=/home/xxxxx」 替換 「./configure」, 其中/home/xxxx 爲安裝目標目錄
git clone git://github.com/nathanmarz/jzmq.git
cd jzmq
./autogen.sh
./configure
make
make install
若是沒有root權限,或當前用戶無sudo權限時,執行 「 ./configure --prefix=/home/xxxx --with-zeromq=/home/xxxx」 替換 「./configure」, 其中/home/xxxx 爲安裝目標目錄
假設以jstorm-0.9.3.zip爲例
unzip jstorm-0.9.3.zip
vi ~/.bashrc
export JSTORM_HOME=/XXXXX/XXXX
export PATH=$PATH:$JSTORM_HOME/bin
配置$JSTORM_HOME/conf/storm.yaml
配置項:
在提交jar的節點上執行:
必須使用tomcat 7.0 或以上版本, 注意不要忘記拷貝 ~/.jstorm/storm.yaml
web ui 能夠和nimbus不在同一個節點
mkdir ~/.jstorm
cp -f $JSTORM_HOME/conf/storm.yaml ~/.jstorm
下載tomcat 7.x (以apache-tomcat-7.0.37 爲例)
tar -xzf apache-tomcat-7.0.37.tar.gz
cd apache-tomcat-7.0.37
cd webapps
cp $JSTORM_HOME/jstorm-ui-0.9.3.war ./
mv ROOT ROOT.old
ln -s jstorm-ui-0.9.3 ROOT
cd ../bin
./startup.sh
在JStorm中有對於流stream的抽象,流是一個不間斷的無界的連續tuple,注意JStorm在建模事件流時,把流中的事件抽象爲tuple即元組,後面會解釋JStorm中如何使用tuple。
JStorm認爲每一個stream都有一個stream源,也就是原始元組的源頭,因此它將這個源頭抽象爲spout,spout多是鏈接消息中間件(如MetaQ, Kafka, TBNotify等),並不斷髮出消息,也多是從某個隊列中不斷讀取隊列元素並裝配爲tuple發射。
有了源頭即spout也就是有了stream,那麼該如何處理stream內的tuple呢,一樣的思想JStorm將tuple的中間處理過程抽象爲Bolt,bolt能夠消費任意數量的輸入流,只要將流方向導向該bolt,同時它也能夠發送新的流給其餘bolt使用,這樣一來,只要打開特定的spout(管口)再將spout中流出的tuple導向特定的bolt,又bolt對導入的流作處理後再導向其餘bolt或者目的地。
咱們能夠認爲spout就是一個一個的水龍頭,而且每一個水龍頭裏流出的水是不一樣的,咱們想拿到哪一種水就擰開哪一個水龍頭,而後使用管道將水龍頭的水導向到一個水處理器(bolt),水處理器處理後再使用管道導向另外一個處理器或者存入容器中。
對應上文的介紹,咱們能夠很容易的理解這幅圖,這是一張有向無環圖,JStorm將這個圖抽象爲Topology即拓撲(的確,拓撲結構是有向無環的),拓撲是Jstorm中最高層次的一個抽象概念,它能夠被提交到Jstorm集羣執行,一個拓撲就是一個數據流轉換圖,圖中每一個節點是一個spout或者bolt,圖中的邊表示bolt訂閱了哪些流,當spout或者bolt發送元組到流時,它就發送元組到每一個訂閱了該流的bolt(這就意味着不須要咱們手工拉管道,只要預先訂閱,spout就會將流發到適當bolt上)。 插個位置說下Jstorm的topology實現,爲了作實時計算,咱們須要設計一個拓撲圖,並實現其中的Bolt處理細節,JStorm中拓撲定義僅僅是一些Thrift結構體,這樣一來咱們就可使用其餘語言來建立和提交拓撲。
JStorm將流中數據抽象爲tuple,一個tuple就是一個值列表value list,list中的每一個value都有一個name,而且該value能夠是基本類型,字符類型,字節數組等,固然也能夠是其餘可序列化的類型。拓撲的每一個節點都要說明它所發射出的元組的字段的name,其餘節點只須要訂閱該name就能夠接收處理。
Worker和Task是JStorm中任務的執行單元, 一個worker表示一個進程,一個task表示一個線程, 一個worker能夠運行多個task。
在JStorm中,資源類型分爲4種, CPU, Memory,Disk, Port, 再也不侷限於Storm的port。 即一個supervisor能夠提供多少個CPU slot,多少個Memory slot, 多少個Disk slot, 多少個Port slot
IRichSpout 爲最簡單的Spout接口
其中注意:
其中注意:
在Maven中配置
若是找不到jstorm-client和jstorm-client-extension包,能夠本身下載jstorm源碼進行編譯,請參考 源碼編譯
打包時,須要將全部依賴打入到一個包中
jstorm jar xxxxxx.jar com.alibaba.xxxx.xx parameter
JStorm VS Storm 請參看 JStorm 0.9.0 介紹.pptx
JStorm 比Storm更穩定,更強大,更快, storm上跑的程序,一行代碼不變能夠運行在jstorm上。
Flume 是一個成熟的系統,主要focus在管道上,將數據從一個數據源傳輸到另一個數據源, 系統提供大量現成的插件作管道做用。固然也能夠作一些計算和分析,但插件的開發沒有Jstorm便捷和迅速。
S4 就是一個半成品,健壯性還能夠,但數據準確性較糟糕,沒法保證數據不丟失,這個特性讓S4 大受限制,也致使了S4開源不少年,但發展一直不是很迅速。
AKKA 是一個actor模型,也是一個不錯的系統,在這個actor模型基本上,你想作任何事情都沒有問題,但問題是你須要作更多的工做,topology怎麼生成,怎麼序列化。數據怎麼流(隨機,仍是group by)等等。
Spark 是一個輕量的內存MR, 更偏重批量數據處理
測試樣例爲https://github.com/longdafeng/storm-examples
5 臺 16核, 98G 物理機
cgroups是control groups的縮寫,是Linux內核提供的一種能夠限制, 記錄, 隔離進程組(process groups)所使用的物理資源(如:cpu,memory,IO 等等)的機制。
在Jstorm中,咱們使用cgroup進行cpu硬件資源的管理。使用前,須要作以下檢查和配置。
cgroup功能在當前系統的內核版本是否支持
檢查/etc/cgconfig.conf是否存在。若是不存在, 請「yum install libcgroup」,若是存在,設置cpu子系統的掛載目錄位置, 以及修改該配置文件中相應的uid/gid爲啓動jstorm用戶的uid/gid, 本例子中以500爲例, 注意是根據第一步來進行設置的。
Note: cgconfig.conf只能在root模式下修改。
這是一個cgconfig.conf配置文件例子。好比jstorm的啓動用戶爲admin,admin在當前 系統的uid/gid爲500(查看/etc/passwd 能夠查看到uid和gid),那麼相對應cpu子系統的jstorm目錄uid/gid也須要設置爲相同的值。 以便jstorm有相應權限能夠在這個目錄下爲jstorm的每一個須要進行資源隔離的進程建立對應 的目錄和進行相關設置。
supervisor.enable.cgroup: true
參考性能優化
當報告 」No supervisor resource is enough for component 「, 則意味着資源不夠 若是是僅僅是測試環境,能夠將supervisor的cpu 和memory slot設置大,
在jstorm中, 一個task默認會消耗一個cpu slot和一個memory slot, 而一臺機器上默認的cpu slot是(cpu 核數 -1), memory slot數(物理內存大小 * 75%/1g), 若是一個worker上運行task比較多時,須要將memory slot size設小(默認是1G), 好比512M, memory.slot.per.size: 535298048
全部spout,bolt,configuration, 發送的消息(Tuple)都必須實現Serializable, 不然就會出現序列化錯誤.
若是是spout或bolt的成員變量沒有實現Serializable時,但又必須使用時, 能夠對該變量申明時,增長transient 修飾符, 而後在open或prepare時,進行實例化
0.9.0 開始,JStorm依舊使用Log4J,但storm使用Logbak,所以應用程序若是有依賴log4j-over-slf4j.jar, 則須要exclude 全部log4j-over-slf4j.jar依賴,下個版本將自定義classloader,就不用擔憂這個問題。
若是應用程序使用和JStorm相同的jar 但版本不同時,建議打開classloader, 修改配置文件
topology.enable.classloader: true
或者
ConfigExtension.setEnableTopologyClassLoader(conf, true);
JStorm默認是關掉classloader,所以JStorm會強制使用JStorm依賴的jar
有3種狀況:
若是有用戶程序的日誌輸出,則代表是用戶的初始化太慢或者出錯,查看日誌便可。 另外對於MetaQ 1.x的應用程序,Spout會recover ~/.meta_recover/目錄下文件,能夠直接刪除這些消費失敗的問題,加速啓動。
打開supervisor 日誌,找出啓動worker命令,單獨執行,而後檢查是否有問題。相似下圖:
檢查配置項 」storm.local.dir「, 是否是storm和jstorm使用相同的本地目錄,若是相同,則將兩者分開
有2種狀況:
假設是6800 端口被佔, 能夠執行命令 「ps -ef|grep 6800」 檢查是否有多個進程, 若是有多個進程,則手動殺死他們
Linux對外鏈接端口數限制,TCP client對外發起鏈接數達到28000左右時,就開始大量拋異常,須要
# echo "10000 65535" > /proc/sys/net/ipv4/ip_local_port_range