大致架构



* 每个应用实例部署一个日志agent

* agent实时将日志发送到kafka

* storm实时计算日志

* storm计算结果保存到hbase

storm消费kafka

  • 创建实时计算项目并引入storm和kafka相关的依赖
<dependency>
    <groupId>org.apache.storm</groupId>
    <artifactId>storm-core</artifactId>
    <version>1.0.2</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.storm</groupId>
    <artifactId>storm-kafka</artifactId>
    <version>1.0.2</version>
</dependency>
<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka_2.10</artifactId>
    <version>0.8.2.0</version>
</dependency>
  • 创建消费kafka的spout,直接用storm提供的KafkaSpout即可。
  • 创建处理从kafka读取数据的Bolt,JsonBolt负责解析kafka读取到的json并发送到下个Bolt进一步处理(下一步处理的Bolt不再写,只要继承BaseRichBolt就可以对tuple处理)。
public class JsonBolt extends BaseRichBolt {
    private static final Logger LOG = LoggerFactory
            .getLogger(JsonBolt.class);

    private Fields fields;
    private OutputCollector collector;

    public JsonBolt() {
        this.fields = new Fields("hostIp", "instanceName", "className",
                "methodName", "createTime", "callTime", "errorCode");
    }

    @Override
    public void prepare(Map stormConf, TopologyContext context,
            OutputCollector collector) {
        this.collector = collector;
    }

    @Override
    public void execute(Tuple tuple) {
        String spanDataJson = tuple.getString(0);
        LOG.info("source data:{}", spanDataJson);
        Map<String, Object> map = (Map<String, Object>) JSONValue
                .parse(spanDataJson);
        Values values = new Values();
        for (int i = 0, size = this.fields.size(); i < size; i++) {
            values.add(map.get(this.fields.get(i)));
        }
        this.collector.emit(tuple, values);
        this.collector.ack(tuple);
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(this.fields);
    }
}
  • 创建拓扑MyTopology,先配置好KafkaSpout的配置SpoutConfig,其中zk的地址端口和根节点,将id为KAFKA_SPOUT_ID的spout通过shuffleGrouping关联到jsonBolt对象。
public class MyTopology {

    private static final String TOPOLOGY_NAME = "SPAN-DATA-TOPOLOGY";
    private static final String KAFKA_SPOUT_ID = "kafka-stream";
    private static final String JsonProject_BOLT_ID = "jsonProject-bolt";

    public static void main(String[] args) throws Exception {
        String zks = "132.122.252.51:2181";
        String topic = "span-data-topic";
        String zkRoot = "/kafka-storm";
        BrokerHosts brokerHosts = new ZkHosts(zks);
        SpoutConfig spoutConf = new SpoutConfig(brokerHosts, topic, zkRoot,
                KAFKA_SPOUT_ID);
        spoutConf.scheme = new SchemeAsMultiScheme(new StringScheme());
        spoutConf.zkServers = Arrays.asList(new String[] { "132.122.252.51" });
        spoutConf.zkPort = 2181;
        JsonBolt jsonBolt = new JsonBolt();

        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout(KAFKA_SPOUT_ID, new KafkaSpout(spoutConf));
        builder.setBolt(JsonProject_BOLT_ID, jsonBolt).shuffleGrouping(
                KAFKA_SPOUT_ID);

        Config config = new Config();
        config.setNumWorkers(1);
        if (args.length == 0) {
            LocalCluster cluster = new LocalCluster();
            cluster.submitTopology(TOPOLOGY_NAME, config,
                    builder.createTopology());
            Utils.waitForSeconds(100);
            cluster.killTopology(TOPOLOGY_NAME);
            cluster.shutdown();
        } else {
            StormSubmitter.submitTopology(args[0], config,
                    builder.createTopology());
        }
    }
}
  • 本地测试时直接不带运行参数运行即可,放到集群是需带拓扑名称作为参数。
  • 另外需要注意的是:KafkaSpout默认从上次运行停止时的位置开始继续消费,即不会从头开始消费一遍,因为KafkaSpout默认每2秒钟会提交一次kafka的offset位置到zk上,如果要每次运行都从头开始消费可以通过配置实现。

storm消费kafka实现实时计算的更多相关文章

  1. Sprak2.0 Streaming消费Kafka数据实时计算及运算结果保存数据库代码示例

    package com.gm.hive.SparkHive; import java.util.Arrays; import java.util.Collection; import java.uti ...

  2. 基于Kafka的实时计算引擎如何选择?Flink or Spark?

    1.前言 目前实时计算的业务场景越来越多,实时计算引擎技术及生态也越来越成熟.以Flink和Spark为首的实时计算引擎,成为实时计算场景的重点考虑对象.那么,今天就来聊一聊基于Kafka的实时计算引 ...

  3. 基于Kafka的实时计算引擎如何选择?(转载)

    1.前言 目前实时计算的业务场景越来越多,实时计算引擎技术及生态也越来越成熟.以Flink和Spark为首的实时计算引擎,成为实时计算场景的重点考虑对象.那么,今天就来聊一聊基于Kafka的实时计算引 ...

  4. Storm消费Kafka提交集群运行

    1.创建拓扑,配置KafkaSpout.Bolt KafkaTopologyBasic.java: package org.mort.storm.kafka; import org.apache.ka ...

  5. Storm消费Kafka值得注意的坑

    问题描述: kafka是之前早就搭建好的,新建的storm集群要消费kafka的主题,由于kafka中已经记录了很多消息,storm消费时从最开始消费问题解决: 下面是摘自官网的一段话:How Kaf ...

  6. Storm集成Kafka应用的开发

    我们知道storm的作用主要是进行流式计算,对于源源不断的均匀数据流流入处理是非常有效的,而现实生活中大部分场景并不是均匀的数据流,而是时而多时而少的数据流入,这种情况下显然用批量处理是不合适的,如果 ...

  7. Flink消费Kafka数据并把实时计算的结果导入到Redis

    1. 完成的场景 在很多大数据场景下,要求数据形成数据流的形式进行计算和存储.上篇博客介绍了Flink消费Kafka数据实现Wordcount计算,这篇博客需要完成的是将实时计算的结果写到redis. ...

  8. Storm大数据实时计算

    大数据也是构建各类系统的时候一种全新的思维,以及架构理念,比如Storm,Hive,Spark,ZooKeeper,HBase,Elasticsearch,等等 storm,在做热数据这块,如果要做复 ...

  9. 《storm实战-构建大数据实时计算读书笔记》

    自己的思考: 1.接收任务到任务的分发和协调   nimbus.supervisor.zookeeper 2.高容错性                            各个组件都是无状态的,状态 ...

随机推荐

  1. 计蒜客NOIP2017提高组模拟赛(三)day2-小区划分

    传送门 dp,注意边界 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...

  2. 【模版 Floyd最小环】

    输入 输入中有多组数据.请用SeekEof判断是否到达文件结束. 对于每组数据: 第一行有两个正整数N,M,分别表示学校的景点个数和有多少对景点之间直接有边相连.(N< =100,M< = ...

  3. Elasticsearch 创建、更新、删除文档、处理冲突

    ----创建新文档---- 1._index,_type和_id的组合可以唯一标识一个文档,所以确保一个新文档的最简单的办法就是,使用索引请求的POST形式让elsticsearch自动生成唯一_id ...

  4. .eslintrc 文件

    安装 建议采用全局安装方式 npm install -g eslint 初始化 如果你的项目还没有配置文件(.eslintrc)的话,可以通过指定–init参数来生成一个新的配置文件: `eslint ...

  5. Servlet init()

    有时候希望在servlet首次载入时,执行复杂的初始化任务,但并不想每个请求都重复这些任务的时候,用init()方法他在servlet初次创建时被调用,之后处理每个用户的请求时,则不在调用这个方法.因 ...

  6. 一个成功的 Git 分支模型(适用于商业应用开发)

    在这篇文章中,我将推广一下大约一年前我介绍过的一些项目(公私皆有)中使用的开发模型,它们的结果都非常成功.有段时间我非常想写出来分享一下,但是我至今才抽出时间来.我不会言及任何项目细节,仅讨论分支策略 ...

  7. Safari 3D transform变换z-index层级渲染异常

    (猛戳来源:http://www.zhangxinxu.com/wordpress/?p=5569)

  8. Android编译安装失败解决办法

    今天用AndroidStudio开发了一个手机App玩玩,但是偶然遇到一个问题,自己手机上测试得劲的很,分享给朋友做测试,但是nie,意外出现了.... 两个人都给我说个安装失败,这个就比较尴尬了,找 ...

  9. 《Effective Java》 读书笔记(一)

    对象的创建与销毁 ITEM1 使用静态工厂方法代替构造函数 传统的新建一个对象的方法是通过构造函数: Foo foo =new Foo(); 一个类也可以提供一个静态方法产生一个对象: Boolean ...

  10. 77. Combinations(medium, backtrack, 重要, 弄了1小时)

    Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...