阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

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

189次阅读
没有评论

共计 13581 个字符,预计需要花费 34 分钟才能阅读完成。

文档说明

该文档包涵了 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

backtype.storm.drpc.DRPCSpout$DRPCMessageId@3770bdf7: 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.lang.UnsatisfiedLinkError: /usr/local/lib/libjzmq.so.0.0.0:libzmq.so.1: cannot open shared object file: No such fileor
directory
      at java.lang.ClassLoader$NativeLibrary.load(NativeMethod)
      atjava.lang.ClassLoader.loadLibrary0(ClassLoader.java:1803)
      atjava.lang.ClassLoader.loadLibrary(ClassLoader.java:1728)
      atjava.lang.Runtime.loadLibrary0(Runtime.java:823)
      atjava.lang.System.loadLibrary(System.java:1028)
      atorg.zeromq.ZMQ.<clinit>(ZMQ.java:34)

5 关于 Storm 的配置问题

1.      yaml 跟我们一般用的属性配置文件有所不同, 它的要求更严格一些, 因此在往 conf/storm.yaml 中添加配置的时候必须注意,比如必须注意开始位置和冒号后面的空格, 否则配置不会生效。

2.      如何检查配置是否生效?

可以使用命令: storm localconfvalue 配置关键字

 但是这个命令只能在 nimbus 上生效, 在 supervisor 看到的还是默认值. 不知道为什么。

6 关闭 storm 相关进程

6.1 关闭 nimbus 相关进程:

kill `ps aux | egrep ‘(daemon\.nimbus)|(storm\.ui\.core)’ |fgrep -v egrep | awk ‘{print $2}’`

备注:这是在网上看到的,没有经过实际测试,有兴趣的朋友可以自己测试一下。

6.2 干掉 supervisor 上的所有 storm 进程:

kill `ps aux | fgrep storm | fgrep -v ‘fgrep’ | awk ‘{print$2}’`

备注:这是在网上看到的,没有经过实际测试,有兴趣的朋友可以自己测试一下。

7 关于 Topology 发布之后的 log

1)      用 storm jar… 将项目提交给 storm 集群后,想查看本项目的 log 信息,要到 supervisor 机器的:storm 安装路径 /logs/worker-number.log(其中的 number 视实际情况而定)中查看。

2)      如果是用 daemontools 启动的 storm,daemontools 监控的目录是 /service/storm,那么到 /service/storm/logs 中查看 worker-number.log 日志。

3)      若要更改 log 的级别,是 debug 还是 info 等,在 storm 安装路径 /log4j 下有个配置文件,按需要修改即可。

4)      Storm 的 debug 模式下,它本身的 log 非常庞大,所以我觉得自己的代码中有些重要的信息,用 info 比较好,这样将 storm 的 log 级别调整为 info 比较方便查看。

8 关于 maven 打包问题

8.1 首先 maven 的 pom 文件中的 storm 依赖,要么加 excludestorm 的相关语句(github 有说明),要么加 <scope>,如下:

                  <dependency>

                          <groupId>storm</groupId>

                          <artifactId>storm</artifactId>

                          <scope>test</scope>

                  </dependency>

加 scope 可以使打 jar 包时,不包含 storm。如果包含了 storm,那么提交到 storm 集群,会运行出错。官方要求打 jar 包时,要去除 storm 的依赖。

8.2 使用 maven 插件,在打 jar 包时,包含依赖。

在 pom 中加入:

<plugin>

      <artifactId>maven-assembly-plugin</artifactId>

      <configuration>

            <descriptorRefs>

                    <descriptorRef>jar-with-dependencies</descriptorRef>

            </descriptorRefs>

            <archive>

                    <manifest>

                          <mainClass>com.path.to.main.Class</mainClass>

                    </manifest>

            </archive>

      </configuration>

</plugin>

打 jar 包时使用命令:mvn assembly:assembly

8.3 依赖的 jar 冲突问题

如果本地依赖的 jar 与 storm 的 lib 下的 jar 有冲突,即都用了一个 jar,但是版本不同,那么貌似目前只能改为跟 storm 保持统一。官方的讨论组是这样说的。

9 关于 nimbus 的启动问题

9.1 Stormnimbus 启动失败

在使用了 storm 一段时间后,需要重新部署 storm 的集群,主要是想将 storm 部署在其它机器上。做了以下错误操作:

        1) 没有 kill 正在运行的 topology,kill nimbus 和 supervisor 的 storm 进程

        2) 删除了配置中 ”storm.local.dir” 的文件夹内的内容

        3) 启动 storm nimbus

报错:
backtype.storm.daemon.nimbus
fn__2692fn__2692exec_fn__945__auto____2693this__2731@62135133  java.io.FileNotFoundException: File’/opt/apps-install/storm/  storm_local/nimbus/stormdist/appFailed-6-1325065153/stormconf.ser’  does not exist        at  org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:137)        at  org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:  1135)        atbacktype.storm.daemon.nimbusthis__2731@62135133  java.io.FileNotFoundException: File’/opt/apps-install/storm/  storm_local/nimbus/stormdist/appFailed-6-1325065153/stormconf.ser’  does not exist        at  org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:137)        at  org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:  1135)        atbacktype.storm.daemon.nimbusread_storm_conf.invoke(nimbus.clj:128)
      atbacktype.storm.daemon.nimbus
compute_new_task__GT_node_PLUS_port.invoke(nimbus.clj:244)        atbacktype.storm.daemon.nimbuscompute_new_task__GT_node_PLUS_port.invoke(nimbus.clj:244)        atbacktype.storm.daemon.nimbusmk_assignments.invoke(nimbus.clj:288)
      atbacktype.storm.daemon.nimbus
fn__2692fn__2692exec_fn__945__auto____2693this__2731.invoke(nimbus.clj:460)        atbacktype.storm.eventthis__2731.invoke(nimbus.clj:460)        atbacktype.storm.eventevent_manager
fn__2068fn__2068fn__2069.invoke(event.clj:25)
      atbacktype.storm.eventevent m anager eventmanagerfn__2068.invoke(event.clj:22)
      atclojure.lang.AFn.run(AFn.java:24)
      atjava.lang.Thread.run(Thread.java:662)
2011-12-29 16:15:02 util [INFO] Halting process: (“Errorwhen
processing an event”)
报错原因:因为没有先 killtopology,所以在启动 nimbus 时,zookeeper 中依然保留了上次运行着的 topology 的信息。

解决办法:用 zookeeper 的 zkCli.sh 清理一下,我直接重装了 zookeeper。但是据说在 storm0.6.1 中解决了该 bug。而我用的是 storm 0.6.0。

10Storm 使用 JVM 参数

在配置文件 storm.yaml 中,有:

# to nimbus
nimbus.childopts: “-Xmx1024m”

# to supervisor
supervisor.childopts: “-Xmx1024m”

# to worker
worker.childopts: “-Xmx768m”
如果 worker 在运行时,需要用指定的 JVM 参数,那么可以像这样配置:
worker.childopts: “-Dworker=worker -Xmx768m -Xdebug –Xnoagent-Djava.compiler=NONE-Xrunjdwp:transport=dt_socket,address=8111,suspend=y,server=y”

11 关于 spout/bolt 的生命周期

一般来说 spout/bolt 的生命周期如下:

1      在提交了一个 topology 之后 (在 nimbus 所在的机器), 创建 spout/bolt 实例(spout/bolt 在 storm 中统称为 component) 并进行序列化;

2      将序列化的 component 发送给所有的任务所在的机器;

3      在每一个任务上反序列化 component;

4      在开始执行任务之前, 先执行 component 的初始化方法(bolt 是 prepare, spout 是 open);

因此 component 的初始化操作应该在 prepare/open 方法中进行, 而不是在实例化 component 的时候进行。

12 关于 storm 与 spring 框架集成问题

 首先声明一下,这个问题是当时有考虑到是否可以将 storm 与 spring 集成时,在网上看到的一点介绍,只是为了日后做参考。

在进行 storm 与 spring 集成时,本来想着一次就能成功,抱着很大的希望可是运行时竟然报了个 java.io.NotSerializableException 的异常。该异常要求被依赖注入的 jar 包实现序列化接口,但那些 jar 包都是别人开发的你不能一个一个都改掉源码才能用到项目里。

再网上找一下还真有人遇到类似的问题,具体原因是对 storm 的 spout 和 bolt 的生命周期理解的不够深刻。

一般来说 spout/bolt 的生命周期如下:

1. 在提交了一个 topology 之后 (在 nimbus 所在的机器), 创建 spout/bolt 实例(spout/bolt 在 storm 中统称为 component) 并进行序列化.

2. 将序列化的 component 发送给所有的任务所在的机器

3. 在每一个任务上反序列化 component.

4. 在开始执行任务之前, 先执行 component 的初始化方法(bolt 是 prepare, spout 是 open).

因此 component 的初始化操作应该在 prepare/open 方法中进行, 而不是在实例化 component 的时候进行.

按照这种说法进行改造,结构该问题消失了。但接下来又有了新的问题:

Caused by: org.xml.sax.SAXParseException: Content is not allowedin prolog.

这个异常网上搜索之后发现原来是由于 *.xml 文件编码的问题。原因是在从其他项目里或者编辑工具编辑时,在文件编码中加入了 BOM 头的原因,于是用 notePad++ 打开 xml 文件选择去掉 BOM 头信息,重新进行保存即可。

13 关于 java.lang.NoClassDefFoundError: clojure.core.protocols$

原因:JDK 版本不匹配,安装虚拟机时系统自带一个 jdk.1.5.0。

解决办法:检查 jdk 版本,卸载系统自带的 JDK,使用自己安装的 JDK 版本。

        # rpm –qa | grep java

        #  rpm –e –nodeps java-*

配置环境变量,vi /etc/profile

重新执行一遍试试,貌似问题解决了。

14 关于 storm 连接 Mysql

连接远程 mysql 是报如下错误:

message from server:”Host FILTER” is not allowed to connect tothis MySQL server

解决方案:

很可能是你没有给其他 IP 访问你数据库的权限,你可以试试:

在 MySql 数据库的主机上,在 mysql 命令行中输入以下命令:

grant all on *.* to root@’%’ identified by “111111” ;

这样,给任何 IP 都赋予了访问的权限,

任何 IP 都能以,用户名:root,密码:111111

来进行局域网的访问!

(命令中 *.* 是通配任何 IP,你也可以指定 IP)

15 关于 metaq 启动的出现服务拒绝连接的问题

解决办法:在 metaq 安装目录下,删掉之前的日志文件,测试网络是否正常连接。将之前的服务的 metaq 进程 kill 掉,然后重启。

16 关于 topology 的 spout 与 bolt

之前有问到,一个 topology 中可不可以有多个 spout?这个问题貌似很幼稚啊,呵呵。关于这个问题,我是这样考虑的:实际应用中,如果我们每一条应用都创建一个 topology 的话,未免也太夸张了。如果是同一个应用,同一个数据来源,但是你想分几种方式对这个数据做处理的话,这时候就应该是建多个 spout 了,让这些 spout 并行去读数据,然后交给订阅这个 spout 的 bolt 去处理就行,没必要一种处理方式建一个 topology。

17 关于 shell 脚本编码格式问题

这是我在写启动 storm 集群的 shell 脚本时遇到的一个实际问题。shell 脚本运行时报错误:/bin/bash^M: badinterpreter

出现原因:windows 上写的脚本,直接拷贝到 Linux 系统上运行由于格式不兼容导致。

17.1 解决方案(一):

1. 比如文件名为 myshell.sh,vim myshell.sh

2. 执行 vim 中的命令 : set ff? 查看文件格式,如果显示 fileformat=dos,证明文件格式有问题。

3. 执行 vim 中的命令 :set fileformat=unix 将文件格式改过来就可以了,然后:wq 保存退出就可以了。

17.2 解决方案(二)

或者使用最笨的方法:将 windows 下编辑好的脚本通过 txt 文本格式转换,然后在拷贝到 linux 下。

如果是使用 Notepad 编辑器进行编辑的话,可以在菜单栏上选择“编辑”—“档案���式转换”—“转换为 UNIX 格式”。

最后说明一下,这些问题只是 storm 应用过程中遇到的一小部分问题,其实还有很多问题是涉及到实际项目的考虑的,比如集群硬件要求,参数配置,日志处理等等,具体问题具体分析吧,也希望哪些在实际项目中用到 storm 的大神们,能多多和大家分享你们的实际经验,毕竟实践出真知,任何新技术,只有经过实际应用和实际检验,分享出来的东西才有说服力。

Storm 的安装步骤 http://www.linuxidc.com/Linux/2016-08/134184.htm

Kafka-Storm 集成部署 http://www.linuxidc.com/Linux/2016-03/129063.htm

Storm 在 Ubuntu 环境下的单机部署 http://www.linuxidc.com/Linux/2016-03/129060.htm

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-10/136079.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计13581字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中