Storm-Kafka 一分钟例子

本文介绍如何在Docker环境下配置Kafka作为Apache Storm的数据源,并通过示例代码展示如何实现这一过程。具体包括配置Docker环境、Gradle依赖、Spout配置及消息处理等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下文章使用了kafka作为storm的sport数据源,依赖于docker-compose环境,如果自己本机已经有了zookeeperkafka环境则可以使用自己的环境。

使用教程

docker-compose.yml

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    ports:
      - "9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 192.168.1.186
      KAFKA_ZOOKEEPER_CONNECT: 192.168.1.186:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

build.gradle

dependencies {
    compile group: 'org.apache.storm', name: 'storm-core', version: '1.2.2'
    compile group: 'org.apache.storm', name: 'storm-kafka-client', version: '1.2.2'
}

Application.java

public class Application {
    public static void main(String[] args) throws Exception {
        KafkaSpoutConfig.Builder<String,String> kafkaBuild = KafkaSpoutConfig.builder("192.168.1.186:32770","test","test1","test2");
        kafkaBuild.setFirstPollOffsetStrategy(KafkaSpoutConfig.FirstPollOffsetStrategy.UNCOMMITTED_LATEST);
        kafkaBuild.setOffsetCommitPeriodMs(100);//设置多长时间向kafka提交一次offset
        kafkaBuild.setProp(ConsumerConfig.GROUP_ID_CONFIG,"testGroup");
        kafkaBuild.setProp(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG,1);
        kafkaBuild.setProp(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG,0);
        KafkaSpoutConfig<String,String> build = kafkaBuild.build();
        KafkaSpout<String,String> kafkaSpout = new KafkaSpout<>(build);
        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout("kafkaSport",kafkaSpout,1);
        builder.setBolt("print-bolt",new PrintBolt(),1)
        .shuffleGrouping("kafkaSport");
        Config config = new Config();
        config.setNumWorkers(1);
        if(args.length==0){
            config.setDebug(true);
            LocalCluster localCluster = new LocalCluster();
            localCluster.submitTopology("test",config,builder.createTopology());
        }else{
            config.setDebug(false);
            StormSubmitter.submitTopology("test",config,builder.createTopology());
        }
    }
}

PrintBolt.java

public class PrintBolt extends BaseRichBolt {
    private OutputCollector collector;

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {}

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

    @Override
    public void execute(Tuple input) {
        String topic = input.getString(0);
        long messageOffet = input.getLong(2);
        String content = input.getString(4);
        System.out.println(content);
        collector.ack(input);
    }
}

往kafka发送一个消息

docker exec -ti 4f27fbb6655c bash /opt/kafka/bin/kafka-console-producer.sh --broker-list 192.168.1.186:32770 --topic test

输入消息回车即可看到程序输出

root@localhost /h/lake# docker exec -ti 4f27fbb6655c bash /opt/kafka/bin/kafka-console-producer.sh --broker-list 192.168.1.186:32770 --topic test
>hello world.
>

输出

...
312034 [Thread-20-print-bolt-executor[3 3]] INFO  o.a.s.d.executor - Processing received message FOR 3 TUPLE: source: kafkaSport:2, stream: default, id: {-3468855975737070311=-8649143164499739979}, [test, 0, 16, null, hello world.]
312034 [Thread-22-__acker-executor[1 1]] INFO  o.a.s.d.executor - Processing received message FOR 1 TUPLE: source: kafkaSport:2, stream: __ack_init, id: {}, [-3468855975737070311 -8649143164499739979 2]
hello world.
312034 [Thread-20-print-bolt-executor[3 3]] INFO  o.a.s.d.task - Emitting: print-bolt __ack_ack [-3468855975737070311 -8649143164499739979]
312034 [Thread-22-__acker-executor[1 1]] INFO  o.a.s.d.executor - BOLT ack TASK: 1 TIME: -1 TUPLE: source: kafkaSport:2, stream: __ack_init, id: {}, [-3468855975737070311 -8649143164499739979 2]
...
<think>好的,用户想了解如何搭建一个实时仓库。首先,我需要明确“实时仓库”在这里的具体含义。通常,实时仓库可能指的是实时数据仓库,用于处理和分析实时数据流,支持实时或近实时的查询和分析。接下来,我需要考虑搭建实时仓库的关键步骤和技术选型。 首先,数据源。实时仓库的数据通常来自多个实时数据流,比如Kafka、MQTT等。需要确认用户的数据源类型,是否已经存在这些数据流,或者需要从头搭建。 然后是数据采集和传输。实时数据需要被高效地采集并传输到存储或处理系统中。这里可能需要使用像Apache Kafka这样的消息队列作为中间件,处理高吞吐量的数据流。 接下来是数据处理层。实时数据处理通常分为流处理和批处理两种模式。对于实时仓库,可能更关注流处理,使用如Apache Flink、Apache Storm或Spark Streaming等技术,进行实时数据的清洗、转换和聚合。 存储层方面,实时仓库需要支持快速写入和查询。传统的数据仓库可能使用HDFS或HBase,但实时场景可能需要更高效的存储,比如Apache Druid、ClickHouse,或者云端的解决方案如AWS Redshift、Google BigQuery等。 数据查询和分析层。用户可能需要通过SQL或BI工具进行实时分析,因此需要支持低延迟查询的引擎,比如Presto、Apache Kylin,或者结合OLAP数据库。 系统架构设计方面,可能需要考虑Lambda架构或Kappa架构。Lambda将批处理和流处理结合,而Kappa则完全基于流处理。需要根据用户的具体需求选择合适的架构。 监控和运维也是重要部分,需要考虑日志监控、性能指标、报警系统等,确保实时仓库的稳定运行。 此外,容错和扩展性。系统需要具备高可用性,能够处理节点故障,并且容易扩展以应对数据量的增长。 安全方面,数据加密、访问控制、合规性等也需要考虑进去。 最后,测试和优化。在搭建完成后,需要进行压力测试,优化性能,确保实时处理的速度和准确性。 可能用户没有明确说明他们的具体业务场景和数据规模,所以在回答时需要保持一定的通用性,同时建议根据实际情况调整技术选型和架构设计。需要确保每个步骤都有清晰的解释,技术术语要准确,并且给出实际例子帮助用户理解。比如,在数据采集层提到Kafka,处理层提到Flink,存储层提到Druid,这样用户可以有具体的参考。同时,强调架构选择的重要性,比如Lambda和Kappa的区别,帮助用户做出合适的选择。可能还需要提醒用户考虑团队的技术栈和熟悉度,选择合适的技术,避免过于复杂难以维护。总之,整个思考过程需要覆盖从数据输入到处理、存储、查询,再到运维和优化的全流程,确保用户能够系统地了解搭建实时仓库的关键要点。</think>搭建实时仓库需从数据采集、处理、存储到查询逐层构建。以下是分步指南: 一、明确需求 1. 确定数据源类型(IoT设备/日志/交易系统) 2. 明确延迟要求(毫秒级或秒级响应) 3. 预估数据规模(日增TB/PB级) 二、核心架构选型(主流方案) $$实时架构 = 数据源 \rightarrow 采集层 \rightarrow 处理层 \rightarrow 存储层 \rightarrow 服务层$$ 1. Lambda架构(批流混合): - 批处理层:HDFS+Hive - 速度层:Kafka+Flink - 服务层:Presto+Redis 2. Kappa架构(全流式): Kafka → Flink → ClickHouse (适合纯实时场景) 三、组件实施步骤 1. 数据采集层 - 日志采集:Filebeat/Fluentd - 消息队列:Apache Kafka(吞吐量$>100k$ msg/s) - 配置示例: ```properties # Kafka生产者配置 bootstrap.servers=broker1:9092 acks=all linger.ms=20 ``` 2. 流处理层 - 计算框架选择: - Apache Flink(事件时间处理) - Spark Structured Streaming(微批处理) - 关键操作: ```java DataStream<Order> orders = env .addSource(new FlinkKafkaConsumer<>("topic", schema, props)) .keyBy(Order::getUserId) .window(TumblingEventTimeWindows.of(Time.minutes(5))) .aggregate(new OrderCounter()); ``` 3. 存储引擎 - 实时宽表:Apache Druid(列式存储,支持$sub-second$查询) - 时序数据:TimescaleDB - 关系型实时:TiDB(HTAP架构) - 数据分层: ```mermaid graph LR ODS[操作数据层] --> DWD[明细层] DWD --> DWS[聚合层] DWS --> ADS[应用层] ``` 4. 查询服务 - OLAP引擎:ClickHouse(单表查询$<100ms$) - 缓存层:Redis(热点数据预加载) - 接口设计: ```python # FastAPI查询示例 @app.get("/realtime/{item_id}") async def get_item_stats(item_id: int): return { "pv": redis.get(f"item:{item_id}:pv"), "uv": clickhouse.execute(f"SELECT COUNT(DISTINCT user) FROM logs WHERE item={item_id}") } ``` 四、运维保障 1. 监控体系: - 数据延迟监控(Prometheus + Grafana) - 端到端正确性校验(DeltaLake ACID特性) 2. 容灾方案: - 多机房Kafka镜像(MirrorMaker2工具) - Flink Savepoint($checkpoint$间隔≤1分钟) 五、典型优化策略 1. 数据压缩:使用Snappy编解码器(Kafka消息压缩率$\approx70\%$) 2. 查询加速:物化视图(ClickHouse的MaterializedView) 3. 资源隔离:YARN队列划分(Flink作业CPU隔离) 完整实施周期参考: - 中小规模(10节点):2-3周 - 大型集群(100+节点):3-6个月 注意事项: 1. 避免过度实时化(非必要场景可采用$T+1$批处理) 2. 数据质量监控需同步建设 3. 预留30%计算资源应对流量突发 实际案例:某电商平台实时大屏 - 处理峰值:$50w$事件/秒 - 端到端延迟:$<2s$ - 技术栈:Kafka + Flink + Druid + Vue前端
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值