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

该文档包涵了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的两倍?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/249d63dcf6c0ffbf2b65e7f09da2cf1d.html