C++开发Storm demo实现

这段时间, 断断续续在搞storm及c++实现方案,遇到了不少坑 , 也参考了不少博客, 主要基于Sasa Petrovic 的c++ 封装, 基本上实现了storm multilang协议。现在把过程捋一捋:

storm 中遇到的问题

这里不谈storm和zookeeper的环境安装与配置, 只说下遇到的几个问题, 其中好几个问题的原因是处理storm版本兼容性比较麻烦导致的

  • maven找不到backtype.storm.包
    一般在正式玩storm之前,会跑一下storm自带的sample, 是由java开发的, 环境中依赖maven。编译的时候报错找不到backtype.storm.*包。原因可能是:
    1)可能是环境变量classpath出错了,程序找不到库
    2)问题可能出在pom文件中的scope上

    <dependency>
    <groupId>org.apache.storm</groupId>
    <artifactId>storm-core</artifactId>
    <version>0.10.0-beta1</version>
    <scope>provided</scope>

    storm 安装的lib路径下已经存在storm-core或storm库,程序又将storm库打包进去,造成storm运行topology时候识别出多个相同库的问题
    3) 可能是使用了storm1.0以上版本,backtype.storm对应的包是org.apache.storm, 我对应的就是这种情况, sample的版本是0.x, 我用的1.0

  • jsoncpp: ambiguous overload for ‘operator[]’ (operand types are ‘Json::Value’ and ‘int’)

class SplitSentence : public Bolt
{
    public:
        ...
        void Process(Tuple &tuple)
        {
            std::string s = tuple.GetValues()[0].asString();
            ...
        }
}

原因是当参数是常量值0的时候,0可能被认为是NULL, 无法确定把它当作是 UINT 还是const char*,string来处理, 无法定位重载方法。应该是他使用了一个不同版本的jsoncpp, 不含value 的operator[]重载方法。

class SplitSentence : public Bolt
{
    public:
        ...
        void Process(Tuple &tuple)
        {
            int i = 0;
            std::string s = tuple.GetValues()[i].asString();
            ...
        }
}
  • 发布topologies 时,出现不能序列化log4j.Logger 的异常
    一般是storm安装的lib库logger库和项目打包依赖的logger库冲突, 凡是遇到这种情况, 都是以storm安装依赖库为准, 删除或替换掉项目中对应的库解决

  • 多语言支持打包问题
    开始一直无法将c++可执行程序和shell脚本打包进jar包, 后来找到解决方法:

    • 项目根目录建立multilang/resources子目录
    • 将可执行文件放入该目录
    • 将脚本目录加入编译目录
      eclipse java build path -> add folder -> 勾选multilang
    • 重新build
    • 重新mvn package
  • 可执行程序执行权限问题
    成功打包后, 运行topology, 又出错提示/bin/bash 找不到spout。 猜测应该是权限问题, topology提交部署的过程中会拷贝到节点xxx/tmp/目录,没有执行权限。从一篇博文了解到,确实是这个原因:http://blog.csdn.net/jmppok/article/details/16827837, 在shell脚本中执行可执行文件前chmod修改权限解决, 比如spout 对应脚本:

#/bin/bash

chmod a+x spout
./spout
  • org.apache.storm.utils.DisruptorQueue.consumeBatchToCursor

这里写图片描述

而后来发现原因是之前项目中的bolt wordcounter没有删除(kill),和cpp demo的wordcounter冲突

  • 之后topology 跑起来了, 搞定, 结果如下:

storm ui

动态统计结果输出

  • 最后贴上c++源码地址和java 源码

        package com.topology;
    
        import org.apache.storm.Config;
        import org.apache.storm.LocalCluster;
        import org.apache.storm.StormSubmitter;
        import org.apache.storm.spout.ShellSpout;
        import org.apache.storm.task.ShellBolt;
        import org.apache.storm.topology.IRichBolt;
        import org.apache.storm.topology.IRichSpout;
        import org.apache.storm.topology.OutputFieldsDeclarer;
        import org.apache.storm.topology.TopologyBuilder;
        import org.apache.storm.tuple.Fields;
    
        import java.util.Map;
    
        /**
         * This topology demonstrates Storm's stream groupings and multilang capabilities.
         */
        public class WordCountTopologyCPP {
            public static class SentenceSpout extends ShellSpout implements IRichSpout{
                public SentenceSpout() {
                  super("/bin/bash", "spout.sh");
                }
    
                @Override
                public void declareOutputFields(OutputFieldsDeclarer declarer) {
                    // TODO Auto-generated method stub
                    declarer.declare(new Fields("sentence"));
                }
    
                @Override
                public Map<String, Object> getComponentConfiguration() {
                    // TODO Auto-generated method stub
                    return null;
                }
    
        }
    
          public static class SplitSentence extends ShellBolt implements IRichBolt {
    
            public SplitSentence() {
              super("/bin/bash", "bolt.sh");
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
              declarer.declare(new Fields("word"));
            }
    
            @Override
            public Map<String, Object> getComponentConfiguration() {
              return null;
            }
          }
    
          public static class WordCount extends ShellBolt implements IRichBolt {
    
            public WordCount() {
              super("/bin/bash", "count.sh");
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
            }
    
            @Override
            public Map<String, Object> getComponentConfiguration() {
              return null;
            }
          }
    
          public static void main(String[] args) throws Exception {
    
            TopologyBuilder builder = new TopologyBuilder();
    
            builder.setSpout("spout", new SentenceSpout(), 2);
    
            builder.setBolt("bolt", new SplitSentence(), 3).shuffleGrouping("spout");
            builder.setBolt("count", new WordCount(), 5).fieldsGrouping("bolt", new Fields("word"));
    
            Config conf = new Config();
            conf.setDebug(true);
    
            if (args != null && args.length > 0) {
              conf.setNumWorkers(3);
              StormSubmitter.submitTopologyWithProgressBar(args[0], conf, builder.createTopology());
            }
            else {
              conf.setMaxTaskParallelism(3);
    
              LocalCluster cluster = new LocalCluster();
              cluster.submitTopology("word-count", conf, builder.createTopology());
    
              Thread.sleep(10*60*1000);
    
              cluster.shutdown();
            }
          }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值