未加星标

Storm实战常见问题及解决方案

字体大小 | |
[系统(linux) 所属分类 系统(linux) | 发布者 店小二03 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

文档说明

该文档包涵了storm实战中经常遇到一些问题,及对应解决方案。这个文档是群里一个朋友在学习storm,并实战storm中遇到的一些问题,及和群里其他朋友一起交流给出的对应解决方案,并由他整理好,委托我发布出来(也算是交流者之一),供大家参考,希望能对大家有所帮助。

问题锦集

1关于Storm集群

1.1关于storm集群的环境变量配置问题

安装好JDK后,需要配置环境变量,通常情况下出于经验,我们往往会修改/etc/profile的值进行环境变量配置,但这在安装JDK以及后面安装的storm集群、zookeeper集群以及metaq集群时会出问题,这时候我们需要在/etc/.bashrc文件中加入环境变量,不然安装的Java和ZK集群等就无法使用,尤其这个问题在我用shell写调度脚本去启动storm集群的时候就遇到过,如果没有将java的环境变量配置在/etc/.bashrc文件中,就会报一个错,这个问题在后面我会提到。

1.2关于zookeeper集群安装问题

记得刚刚接触storm,在安装zookeeper集群的时候有这样的考虑:为什么不可以把zookeeper只安装在nimbus上,然后让其他的supervisor来它这里读取任务?如果在每台机器上都安装zookeeper,那nimbus分配任务的时候,是每台机器上的zookeeper都收到同一份的任务,还是只是将分配给每个supervisor节点的那部分写到同一节点上的zookeeper中?

有朋友解答说:ZK也是以集群的方式工作的,ZK集群内部有他自己的一套相互通信机制,而storm正是要借助其通讯机制,例如任务下发等,往往在执行一个任务的时候,storm会把任务及相关执行的代码经过序列化之后发送到各个ZK节点供supervisor去下载,然后才会各自执行自己部分的代码或者任务。说的直接一点就是每个ZK节点收到的任务是一样的,而supervisor只需要下载属于自己的任务即可。

1.3关于Storm中tuple 的可靠处理问题

Storm 为了保证tuple 的可靠处理,需要保存tuple 信息,这样会不会导致内存泄漏?

关于这个问题,其实网上是有资料进行了详细的解释的。这里只是大概将一下,如果还不明白,可以上网搜搜“storm可靠处理”。Storm为了保证tuple 的可靠处理,acker 会保存该节点创建的tuple id的xor (异或)值,这个值称为ackvalue,那么每ack 一次,就将tuple id 和ack value做异或(xor)。当所有产生的tuple 都被ack的时候,ack value 必定为0。这是个很简单的策略,对于每一个tuple 也只要占用约20个字节的内存。对于100万tuple,也才20M 左右,所以一般情况下是不用考虑内存泄漏问题的。

1.4关于storm计算结果的存放问题

很多人在刚刚学习Storm 的时候都会有这个问题:storm处理后的结果保存在哪里? 内存中?还是其他地方?

官方解释说: Storm是不负责保存计算结果的,这是应用程序里需要负责的事情,如果数据不大,你可以简单地保存在内存里,也可以每次都更新数据库,也可以采用NoSQL存储。storm并没有像s4 那样提供一个PersistAPI,根据时间或者容量来做存储输出。这部分事情完全交给用户。数据存储之后的展现,也是你需要自己处理的,storm UI只提供对topology 的监控和统计。

1.5关于Storm如何处理重复的tuple问题

有人问到Storm 是怎么处理重复的tuple?

因为Storm 要保证tuple 的可靠处理,当tuple 处理失败或者超时的时候,spout 会fail并重新发送该tuple,那么就会有tuple 重复计算的问题。这个问题是很难解决的,storm也没有提供机制帮助你解决。不过也有一些可行的策略:

(1)不处理,这也算是种策略。因为实时计算通常并不要求很高的精确度,后

续的批处理计算会更正实时计算的误差。

(2)使用第三方集中存储来过滤,比如利用mysql、MemCached 或者Redis 根据逻辑主键来去重。

(3)使用bloom filter 做过滤,简单高效。

1.6关于task与executor的关系问题

在storm的学习过程中,有许多人问到task与executor的关系问题。

在我们安装配置storm的时候,不知大家是否主要到了一个问题,就是我们在配置的时候会加几个worker的端口(supervisor.slots.ports:),比如众多文档中提到的6700/6701等等类似的东西。没错,这就是我们定义了该supervisor最多的worker数,worker中执行一个bolt或者spout线程,我们就称之为task,而executor是物理上的线程概念,我们可以将其称为执行线程;而task更多是逻辑概念上的,有时候bolt与spout的task会共用一个executor,特别是在系统负荷比较高的时候。

1.7关于Storm UI显示内容的问题

Storm UI 里spout 统计的complete latency 的具体含义是什么?为什么emit 的数目会是acked的两倍?

简单地说,complete latency 表示了tuple 从emit 到被acked 经过的时间,可以认为是tuple以及该tuple 的后续子孙(形成一棵树)整个处理时间。其次spout 的emit 和transfered 还统计了spout和acker 之间内部的通信信息,比如对于可靠处理的spout 来说,会在emit 的时候同时发送一个_ack_init给acker,记录tuple id 到task id 的映射,以便ack 的时候能找到正确的acker task。

1.8关于Storm的ack和fail问题

在学习storm的过程中,有不少人对storm的Spout组件中的ack及fail相关的问题存在困惑,这里做一个简要的概述。

Storm保证每一个数据都得到有效处理,这是如何保证的呢?正是ack及fail机制确保数据都得到处理的保证,但是storm只是提供给我们一个接口,而具体的方法得由我们自己来实现。例如在spout下一个拓扑节点的bolt上,我们定义某种情况下为数据处理失败,则调用fail,则我们可以在fail方法中进行数据重发,这样就保证了数据都得到了处理。其实,通过读storm的源码,里面有讲到,有些类(BaseBasicBolt?)是会自动调用ack和fail的,不需要我们程序员去ack和fail,但是其他Bolt就没有这种功能了。

1.9关于IRichBolt与IBasicBolt接口的区别

首先从类的组成上进行分析可以看到,IBasicBolt接口只有execute方法和declareOutputFields方法,而IRichBolt接口上除了以上几个方法还有prepare方法和cleanup及map方法。而且其中execute方法是有些不一样的,其参数列表不同。

总体来说Rich方法比较完善,我们可以使用prepare方法进行该Bolt类的初始化工作,例如我们链接数据库时,需要进行一次数据库连接操作,我们就可以把该操作放入prepare中,只需要执行一次就可以了。而cleanup方法能在该类调用结束时进行收尾工作,往往在处理数据的时候用到,例如在写hdfs(Hadoop的文件系统)数据的时候,在结束时需要进行数据clear,则需要进行数据收尾。当然,根据官网及实际的测验,该方法往往是执行失败的。

2关于Topology发布

2.1发布topologies 到远程集群时,出现Nimbus host is not set 异常

原因是Nimbus 没有被正确启动起来,可能是storm.yaml 文件没有配置,或者配置有问题。

解决方法:打开storm.yaml 文件正确配置:nimbus.host: "xxx.xxx.xxx.xxx",重启nimbus后台程序即可。

2.2发布topology到远程集群时,出现AlreadyAliveException(msg: xxx is alreadyactive)异常

原因是提供的topology 与已经在运行的topology 重名。

解决方法:发布时换一个拓扑名称即可。

2.3启动Supervisor 时,出现java.lang.UnsatisfiedLinkError

具体信息:启动Supervisor 时,出现java.lang.UnsatisfiedLinkError:

/usr/local/lib/libjzmq.so.0.0.0: libzmq.so.1: cannot open sharedobject

file: No such file or directory 异常。

原因是未找到zmq 动态链接库。

解决方法1:配置环境变量 export LD_LIBRARY_PATH=/usr/local/lib

解决方法2:编辑/etc/ld.so.conf 文件,增加一行:/usr/local/lib。再执行

sudo ldconfig 命令,重启Supervisor。

2.4发布topologies 时,出现不能序列化log4j.Logger 的异常

原因是日志系统无法正确支付序列化。

解决方法:使用slf4j 代替log4j。

2.5bolt 在处理消息时,worker 的日志中出现Failing message

原因:可能是因为Topology 的消息处理超时所致。

解决方法:提交Topology 时设置适当的消息超时时间,比默认消息超时时间(30

秒)更长。比如:

conf.setMessageTimeoutSecs(60);

2.6在打包toplogy工程的时候, 如果采用assembly方式,对于相关的依赖的配置一般要这样:

Xml代码

1. <dependencySets>

2. <dependencySet>

3. <outputDirectory>/</outputDirectory>

4. <unpack>true</unpack>

5. <excludes>

6. <exclude>storm:storm</exclude>

7. </excludes>

8. </dependencySet>

9. </dependencySets>

wiki上说可以用<scope>compile</scope>。然后将storm依赖设置为runtime,貌似不行。 另外就是所有的依赖包将全部解压,然后将所有依赖的配置和class文件生成一个文件。这个是通过<unpack>true</unpack>参数来控制的。

2.7在提交topology的时候有时可能出现如下异常:

Exception in thread "main"java.lang.IllegalArgumentException: Nimbus host is notset

atbacktype.storm.utils.NimbusClient.<init>(NimbusClient.java:30)

atbacktype.storm.utils.NimbusClient.getConfiguredClient(NimbusClient.java:17)

atbacktype.storm.StormSubmitter.submitJar(StormSubmitter.java:78)

atbacktype.storm.StormSubmitter.submitJar(StormSubmitter.java:71)

atbacktype.storm.StormSubmitter.submitTopology(StormSubmitter.java:50)

atcom.taobao.kaleidoscope.storm.IcdbTopology.main(IcdbTopology.java:59)

但是启动nimbus是没有问题的, 这个主要因为conf_dir路径设置不正确,在bin/storm脚本中需要加上这样一句:

python代码

1. CONF_DIR = STORM_DIR + "/conf"

3关于DRPC

3.1发布drpc 类型的topologies 到远程集群时,出现空指针异常,连接drpc服务器失败

原因是未正确配置drpc 服务器地址。

解决方法:在conf/storm.yaml 文件中增加drpc 服务器配置,启动配置文件中

指定的所有drpc 服务。内容如下:

drpc.servers:

- "drpc 服务器ip"

3.2客户端调用drpc 服务时,worker 的日志中出现Failing message,而bolt都未收到数据

错误日志如下所示:

2011-12-02 09:59:16 task [INFO] Failing message

[email protected]: source:1:27,

stream: 1, id: {-5919451531315711689=-5919451531315711689},

[foo.com/blog/1, {"port":3772,"id":"5","host":"10.0.0.24"}]

原因是主机名,域名,hosts 文件配置不正确会引起这类错误。

解决方法:检查并修改storm 相关机器的主机名,域名,hosts 文件。重启网络服务:service networkrestart。重启storm,再次调用drpc 服务,成功。Hosts 文件中必须包含如下

内容:

[nimbus 主机ip] [nimbus 主机名] [nimbus 主机别名] [supervisor 主机ip] [supervisor 主机名] [supervisor 主机别名] [zookeeper 主机ip] [zookeeper 主机名] [zookeeper 主机别名]

4关于jzmq安装

4.1storm 启动时报no jzmq in java.library.path 错误

原因是找不到jzmq,默认情况下在执行install_zmq.sh 时,那些.so 文件

安装路径在/usr/local/lib,但是实际安装时可能装在其他的路径下了。

解决方法:在storm.yaml 中添加:

java.library.path:

"/opt/storm/jzmq/lib:/opt/storm/zeromq/lib:/usr/local/lib:/opt/local/

lib:/usr/lib"

4.2安装jzmq 时遇到No rule to make target ‘classdist_noinst.stamp’的make错误

具体的make 错误信息:

make[1]: *** No rule to make target`classdist_noinst.stamp',needed by `org/zeromq/ZMQ.class'.Stop.

解决方法:手动创建classdist_noinst.stamp 空文件。

touch src/classdist_noinst.stamp

4.3安装jzmq 时遇到cannot access org.zeromq.ZMQ 的make 错误

具体的make 错误信息:

error: cannot access org.zeromq.ZMQ class file fororg.zeromq.ZMQ not found

javadoc: error - Class org.zeromq.ZMQ not found.

解决方法:手动编译,然后重新make 即可通过。

cd src

javac -d . org/zeromq/*.java

cd ..

4.4 在部署storm节点的时候需要安装jzmq和zeromq, 在安装这两个依赖包之后,需要执行sudo -u root ldconfig. 否则会出现异常:

2012-02-24 16:30:30 worker [ERROR] Error oninitialization of server mk-worker java.l

本文系统(linux)相关术语:linux系统 鸟哥的linux私房菜 linux命令大全 linux操作系统

分页:12
转载请注明
本文标题:Storm实战常见问题及解决方案
本站链接:http://www.codesec.net/view/483649.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(linux) | 评论(0) | 阅读(23)