本文导读:html
一、What——JStorm是什么? 1.1 概述 1.2优势 1.3应用场景 1.4JStorm架构 二、Why——为何启动JStorm项目?(与storm的区别) 2.1storm的现状、缺陷 2.2JStorm比Storm更稳定,功能更强大,更快!—— 表现 2.2.1稳定性好的表现 2.2.2调度强大的表现 2.2.3性能更好的表现 2.3性能提高的缘由所在 2.4JStorm的其它优势 2.5与flume、S四、AKKA、Spark的比较 三、JStorm的性能优化点 四、JStorm的常见问题 五、TODO List 六、参考连接
JStorm 是一个分布式实时计算引擎,相似Hadoop MapReduce的系统, 用户按照规定的编程规范实现一个任务,而后将这个任务递交给JStorm系统,Jstorm将这个任务跑起来,而且按7 * 24小时运行起来,一旦中间一个worker 发生意外故障, 调度器当即分配一个新的worker替换这个失效的worker。所以,从应用的角度,JStorm 应用是一种遵照某种编程规范的分布式应用。从系统角度,JStorm一套相似MapReduce的调度系统。从数据的角度,是一套基于流水线的消息处理机制。实时计算如今是大数据领域中最火爆的一个方向,由于人们对数据的要求愈来愈高,实时性要求也愈来愈快,传统的 Hadoop Map Reduce,逐渐知足不了需求,所以在这个领域需求不断。java
在Storm和JStorm出现之前,市面上出现不少实时计算引擎,但自storm和JStorm出现后,基本上能够说一统江湖,git
应用场景:
JStorm处理数据的方式是基于消息的流水线处理, 所以特别适合无状态计算,也就是计算单元的依赖的数据所有在接受的消息中能够找到, 而且最好一个数据流不依赖另一个数据流。github
JStorm 从设计的角度,就是一个典型的调度系统。web
在这个系统中,数据库
具体参考下图:apache
关于流处理框架,在先前的文章汇总已经介绍过Strom,今天学习的是来自阿里的的流处理框架JStorm。简单的概述JStorm就是:JStorm 比Storm更稳定,更强大,更快,Storm上跑的程序,一行代码不变能够运行在JStorm上。直白的讲JStorm是阿里巴巴的团队基于Storm的二次开发产物,至关于他们的Tengine是基于Nginx开发的同样。如下为阿里巴巴团队放弃直接使用Storm选择自行开发JStorm的缘由:编程
在整个阿里巴巴集团,1000+的物理机上运行着Storm,一淘(200+),CDO(200+),支付宝(150+),B2B(50+),阿里妈妈(50+),共享事业群(50+),其余等。安全
WHY之一句话概述:JStorm比Storm更稳定,功能更强大,更快!(Storm上跑的程序能够一行代码不变运行在JStorm上)性能优化
JStorm 0.9.0 性能很是的好,使用netty时单worker 发送最大速度为11万QPS,使用zeromq时,最大速度为12万QPS。
编程接口改变:当topology.max.spout.pending 设置不为1时(包括topology.max.spout.pending设置为null),spout内部将额外启动一个线程单独执行ack或fail操做, 从而nextTuple在单独一个线程中执行,所以容许在nextTuple中执行block动做,而原生的storm,nextTuple/ack/fail 都在一个线程中执行,当数据量不大时,nextTuple当即返回,而ack、fail一样也容易没有数据,进而致使CPU 大量空转,白白浪费CPU, 而在JStorm中, nextTuple能够以block方式获取数据,好比从disruptor中或BlockingQueue中获取数据,当没有数据时,直接block住,节省了大量CPU。
但所以带来一个问题, 处理ack/fail 和nextTuple时,必须当心线程安全性。
附属: 当topology.max.spout.pending为1时, 恢复为spout一个线程,即nextTuple/ack/fail 运行在一个线程中。
Flume 是一个成熟的系统,主要focus在管道上,将数据从一个数据源传输到另一个数据源, 系统提供大量现成的插件作管道做用。固然也能够作一些计算和分析,但插件的开发没有Jstorm便捷和迅速。
S4 就是一个半成品,健壮性还能够,但数据准确性较糟糕,没法保证数据不丢失,这个特性让S4 大受限制,也致使了S4开源不少年,但发展一直不是很迅速。
AKKA 是一个actor模型,也是一个不错的系统,在这个actor模型基本上,你想作任何事情都没有问题,但问题是你须要作更多的工做,topology怎么生成,怎么序列化。数据怎么流(随机,仍是group by)等等。
Spark 是一个轻量的内存MR, 更偏重批量数据处理。
按照性能来讲, trident < transaction < 使用ack机制普通接口 < 关掉ack机制的普通接口, 所以,首先要权衡一下应该选用什么方式来完成任务。
若是“使用ack机制普通接口”时, 能够尝试关掉ack机制,查看性能如何,若是性能有大幅提高,则预示着瓶颈不在spout, 有多是Acker的并发少了,或者业务处理逻辑慢了。
参考上面3中JStorm性能优化
当报告 ”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
1 #if it is null, then it will be detect by system 2 supervisor.cpu.slot.num: null 3 4 #if it is null, then it will be detect by system 5 supervisor.mem.slot.num: null 6 7 # support disk slot 8 # if it is null, it will use $(storm.local.dir)/worker_shared_data 9 supervisor.disk.slot: null
全部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,就不用担忧这个问题。
1 SLF4J: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. 2 SLF4J: See also 3 http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. 4 Exception in thread "main" java.lang.ExceptionInInitializerError 5 at org.apache.log4j.Logger.getLogger(Logger.java:39) 6 at org.apache.log4j.Logger.getLogger(Logger.java:43) 7 at com.alibaba.jstorm.daemon.worker.Worker.<clinit>(Worker.java:32) 8 Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also 9 http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. 10 at org.apache.log4j.Log4jLoggerFactory.<clinit>(Log4jLoggerFactory.java:49) 11 ... 3 more 12 Could not find the main class: com.alibaba.jstorm.daemon.worker.Worker. Program will exit.
若是应用程序使用和JStorm相同的jar 但版本不同时,建议打开classloader, 修改配置文件
1 topology.enable.classloader: true
或者
1 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左右时,就开始大量抛异常,须要
1 # echo "10000 65535" > /proc/sys/net/ipv4/ip_local_port_range
Github源码:https://github.com/alibaba/jstorm/
中文文档:https://github.com/alibaba/jstorm/wiki/JStorm-Chinese-Documentation