看介绍文档貌似挺好:
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