【Java万花筒】畅览实时数据的奇妙世界:Java库与框架应用指南

Apache Flink可以广泛应用于以下场景:

  • 实时数据分析和处理:对实时数据流进行复杂的计算和分析,例如实时监控、实时统计分析等。
  • 批量数据处理:对大规模批量数据进行高效的处理和分析,例如离线报表生成、离线数据清洗等。
  • 事件驱动的应用程序:构建事件驱动的应用程序,例如实时预警系统、实时物联网应用等。
2.4 Flink的流式处理示例

下面是一个使用Apache Flink进行流式处理的示例代码。假设我们有一个实时的交易数据流,每条交易数据包含交易时间、交易金额和交易类型。我们要统计每分钟的总交易金额,并将结果输出到日志文件中。

import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;

public class StreamingJob {
    public static void main(String[] args) throws Exception {
        // 设置执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 创建交易数据流
        DataStream<Transaction> transactions = env
                .socketTextStream("localhost", 9999)
                .map(new MapFunction<String, Transaction>() {
                    @Override
                    public Transaction map(String value) throws Exception {
                        String[] fields = value.split(",");
                        long timestamp = Long.parseLong(fields[0]);
                        double amount = Double.parseDouble(fields[1]);
                        String type = fields[2];
                        return new Transaction(timestamp, amount, type);
                    }
                });

        // 按照交易时间进行分组,并计算每分钟的总交易金额
        DataStream<TransactionAggregate> result = transactions
                .keyBy("timestamp")
                .timeWindow(Time.minutes(1))
                .sum("amount");

        // 将结果输出到日志文件
        result.print();

        // 执行任务
        env.execute("Streaming Job");
    }

    public static class Transaction {
        public long timestamp;
        public double amount;
        public String type;

        public Transaction(long timestamp, double amount, String type) {
            this.timestamp = timestamp;
            this.amount = amount;
            this.type = type;
        }
    }

    public static class TransactionAggregate {
        public long timestamp;
        public double sumAmount;

        public TransactionAggregate(long timestamp, double sumAmount) {
            this.timestamp = timestamp;
            this.sumAmount = sumAmount;
        }
    }
}

上述代码中,我们使用socketTextStream方法创建了一个流数据源,实时从本地9999端口接收交易数据。然后使用map算子将每条交易数据映射为Transaction对象。接着,我们使用keyBy方法对交易数据按照交易时间进行分组,并使用timeWindow方法定义一个窗口,窗口的大小为1分钟。最后,使用sum算子对窗口内的交易金额进行求和。将结果输出到日志文件中。

2.5 Flink的批处理示例

下面是一个使用Apache Flink进行批处理的示例代码。假设我们有一个包含大量文本文件的目录,我们要统计每个文件中包含特定关键词的行数,并将结果输出到控制台。

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector;

public class BatchJob {
    public static void main(String[] args) throws Exception {
        // 设置执行环境
        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

        // 加载文本文件
        String inputPath = "path/to/text/files";
        DataSet<String> lines = env.readTextFile(inputPath);

        // 统计包含特定关键词的行数
        DataSet<Tuple2<String, Integer>> result = lines
                .flatMap(new Tokenizer())
                .groupBy(0)
                .sum(1);

        // 输出结果
        result.print();

        // 执行任务
        env.execute("Batch Job");
    }

    public static class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
        @Override
        public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
            // 按空格分割每行文本,并输出(单词,1)的键值对
            String[] words = value.toLowerCase().split(" ");
            for (String word : words) {
                if (word.equals("keyword")) {
                    out.collect(new Tuple2<>(word, 1));
                }
            }
        }
    }
}

上述代码中,我们首先使用readTextFile方法加载文本文件,并将每一行作为一个字符串。然后,使用flatMap算子将每行文本按空格分割,并输出(单词,1)的键值对,其中只输出包含特定关键词的行。接着,使用groupBy方法将键值对按照单词进行分组,并使用sum算子对每个单词的频次进行求和。最后,将结果输出到控制台。

这是一个简单的批处理示例,您可以根据需要修改代码来适应不同的场景和需求。

以上是关于Apache Flink的简要介绍以及流式处理和批处理的示例代码。Apache Flink是一个功能强大的分布式数据处理引擎,具有广泛的应用场景和丰富的特性,可用于实时数据处理、批量数据处理和事件驱动的应用程序开发。

3. Storm
3.1 简介

Storm是一个开源的分布式实时计算系统,可以实时处理大规模的流式数据。它具有高性能、容错性和可扩展性的特点,适用于实时分析、实时监控和实时推荐等场景。

3.2 主要特性
  • 高性能:Storm采用多线程方式处理数据流,能够在毫秒级别的延迟下处理大规模的实时数据。
  • 容错性和可伸缩性:Storm可以在节点故障的情况下保持数据处理的高可靠性,并能够弹性扩展以处理更多的数据流。
  • 多语言支持:Storm支持多种编程语言,包括Java、Python和Scala等,使开发人员能够使用自己熟悉的语言开发和部署实时应用程序。
import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;

public class WordCountTopology {
  public static void main(String[] args) {
    TopologyBuilder builder = new TopologyBuilder();
    builder.setSpout("spout", new RandomSentenceSpout(), 5);
    builder.setBolt("split", new SplitSentenceBolt(), 8).shuffleGrouping("spout");
    builder.setBolt("count", new WordCountBolt(), 12).fieldsGrouping("split", new Fields("word"));
    
    Config config = new Config();
    config.setDebug(true);
    
    LocalCluster cluster = new LocalCluster();
    cluster.submitTopology("word-count", config, builder.createTopology());
    
    Utils.sleep(10000);
    
    cluster.killTopology("word-count");
    cluster.shutdown();
  }
}

3.3 应用场景

Storm可以广泛应用于以下场景:

  • 实时监控和告警:对实时数据进行监控和告警处理,例如网络监控、系统运行状态监控等。
  • 实时推荐系统:根据用户的实时行为数据进行实时推荐,例如电商平台的个性化推荐、音乐平台的智能播放列表等。
  • 日志处理:实时处理和分析大量的日志数据,例如日志实时分析、异常日志检测等。
3.4 Storm示例代码

以下是一个使用Storm进行实时处理的示例代码。假设我们有一个随机产生句子的数据源,我们要对这些句子进行拆分,并统计每个单词的频次。

import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.topology.base.BaseRichSpout;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class WordCountTopology {
    public static class RandomSentenceSpout extends BaseRichSpout {
        private OutputCollector collector;
        private Random random;
        private String[] sentences;

        @Override
        public void open(Map config, TopologyContext context, OutputCollector collector) {
            this.collector = collector;
            this.random = new Random();
            this.sentences = new String[]{"I am happy", "You are sad", "He is angry"};
        }

        @Override
        public void nextTuple() {
            Utils.sleep(100);
            String sentence = sentences[random.nextInt(sentences.length)];
            collector.emit(new Values(sentence));
        }

        @Override
        public void declareOutputFields(org.apache.storm.topology.OutputFieldsDeclarer declarer) {
            declarer.declare(new Fields("sentence"));
        }
    }

    public static class SplitSentenceBolt extends BaseRichBolt {
        private OutputCollector collector;

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

        @Override
        public void execute(Tuple tuple) {
            String sentence = tuple.getStringByField("sentence");
            String[] words = sentence.split("\\s+");
            for (String word : words) {
                collector.emit(new Values(word));
            }
        }

        @Override
        public void declareOutputFields(org.apache.storm.topology.OutputFieldsDeclarer declarer) {
            declarer.declare(new Fields("word"));
        }
    }

    public static class WordCountBolt extends BaseRichBolt {
        private OutputCollector collector;
        private Map<String, Integer> wordCount;

        @Override
        public void prepare(Map config, TopologyContext context, OutputCollector collector) {
            this.collector = collector;
            this.wordCount = new HashMap<>();
        }

        @Override
        public void execute(Tuple tuple) {
            String word = tuple.getStringByField("word");
            int count = wordCount.getOrDefault(word, 0) + 1;
            wordCount.put(word, count);
            collector.ack(tuple);
            if (count >= 5) {
                System.out.println("Word: " + word + ", Count: " + count);
            }
        }

        @Override
        public void declareOutputFields(org.apache.storm.topology.OutputFieldsDeclarer declarer) {

        }
    }

    public static void main(String[] args) throws InterruptedException {
        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout("spout", new RandomSentenceSpout(), 1);
        builder.setBolt("split", new SplitSentenceBolt(), 1).shuffleGrouping("spout");
        builder.setBolt("count", new WordCountBolt(), 1).fieldsGrouping("split", new Fields("word"));

        Config config = new Config();
        config.setDebug(false);

        LocalCluster cluster = new LocalCluster();
        cluster.submitTopology("word-count", config, builder.createTopology());

        Thread.sleep(10000);

        cluster.killTopology("word-count");
        cluster.shutdown();
    }
}


在这个示例中,我们定义了三个组件:RandomSentenceSpoutSplitSentenceBoltWordCountBolt

RandomSentenceSpout是一个数据源,随机产生句子,并将其发送给下一个组件SplitSentenceBolt

SplitSentenceBolt对接收到的句子进行拆分,并将每个单词发送给WordCountBolt

WordCountBolt接收单词并进行频次统计,如果某个单词的频次达到5次,就输出到控制台。

最后,我们使用TopologyBuilder构建拓扑,并使用LocalCluster在本地模式下执行拓扑。

这是一个简单的Storm示例,您可以根据需要修改代码来适应不同的场景和需求。

4. Kafka Streams
4.1 简介

Kafka Streams是一个用于构建实时流处理应用程序的库,基于Apache Kafka提供了高级别的API。它可以实时处理Kafka主题中的数据流,并提供丰富的操作和转换功能,使得开发人员能够灵活处理和分析数据流。

4.2 主要特性
  • 流处理API:Kafka Streams提供了丰富的流处理API,使开发人员能够对数据流进行高效的处理、转换和聚合操作。
  • Exactly-Once语义:Kafka Streams提供了Exactly-Once语义的处理保证,确保数据不被重复处理和丢失。
  • 状态管理:Kafka Streams提供了内置的状态存储和管理功能,使开发人员可以轻松处理有状态的流处理应用程序。
  • 与Kafka无缝集成:Kafka Streams与Apache Kafka无缝集成,可以直接处理Kafka主题中的数据流,简化了系统的搭建和维护工作。
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.kstream.KStream;

import java.util.Properties;

public class WordCountApp {
  public static void main(String[] args) {
    Properties config = new Properties();
    config.put(StreamsConfig.APPLICATION\_ID\_CONFIG, "word-count-app");
    config.put(StreamsConfig.BOOTSTRAP\_SERVERS\_CONFIG, "localhost:9092");
    config.put(StreamsConfig.DEFAULT\_KEY\_SERDE\_CLASS\_CONFIG, Serdes.String().getClass());
    config.put(StreamsConfig.DEFAULT\_VALUE\_SERDE\_CLASS\_CONFIG, Serdes.String().getClass());
    
    StreamsBuilder builder = new StreamsBuilder();
    KStream<String, String> source = builder.stream("input-topic");
    KStream<String, Long> wordCounts = source
      .flatMapValues(value -> Arrays.asList(value.toLowerCase().split(" ")))
      .groupBy((key, value) -> value)
      .count();
    wordCounts.toStream().to("output-topic");
    
    KafkaStreams streams = new KafkaStreams(builder.build(), config);
    streams.start();
  }
}

4.3 应用场景

Kafka Streams可以广泛应用于以下场景:

  • 实时数据处理和分析:对实时数据流进行复杂的计算和分析,例如实时指标计算、实时数据清洗等。
  • 实时ETL:将实时数据流转换为目标系统的数据格式,例如实时数据同步、实时数据导入等。
  • 实时数据反应式应用:开发实时数据驱动的应用程序,例如实时报警系统、实时业务智能等。
5. Samza
5.1 简介

Samza是一个分布式流处理框架,适用于高吞吐量的实时数据处理场景。它基于Apache Kafka和Apache Hadoop等开源技术,具有高性能、可扩展性和容错性的特点。

5.2 主要特性
  • 处理语义:Samza提供了Exactly-Once语义的处理保证,确保数据不被重复处理和丢失。
  • 容错性和弹性扩展:Samza具有容错性和弹性扩展的能力,可以在节点故障或数据倾斜的情况下保证数据处理的高可靠性和稳定性。
  • 多语言支持:Samza支持多种编程语言,包括Java和Scala等,使开发人员能够使用自己熟悉的语言开发和部署实时应用程序。
  • 与Kafka和Hadoop无缝集成:Samza与Apache Kafka和Apache Hadoop无缝集成,可以直接处理Kafka主题中的数据流,并能够利用Hadoop集群进行大规模离线批处理。
import org.apache.samza.application.StreamApplication;
import org.apache.samza.application.descriptors.StreamApplicationDescriptor;

public class WordCountApp implements StreamApplication {
  @Override
  public void describe(StreamApplicationDescriptor appDescriptor) {
    MessageStream<String> lines = appDescriptor.getInputStream("input-topic");
    OutputStream<String> output = appDescriptor.getOutputStream("output-topic");
    
    lines
      .flatMap(line -> Arrays.asList(line.toLowerCase().split(" ")))
      .map(word -> new KeyValue<>(word, 1))
      .partitionBy(KeyValue::getKey, KeyValue::getValue, "word-count")
      .window(Windows.<String, Integer, TimeWindow>keyedTumblingWindow(Duration.ofMinutes(1), new WordCountSerde()))
      .map((window, word, count) -> String.format("%s: %d", word, count))
      .sendTo(output);
  }
}

5.3 应用场景

Samza可以广泛应用于以下场景:

  • 实时日志处理:对大量日志数据进行实时处理和分析,例如日志过滤、日志聚合等。
  • 实时推荐系统:根据用户的实时行为数据进行实时推荐,例如电商平台的个性化推荐、社交平台的实时动态推送等。
  • 实时数据清洗和转换:对实时数据流进行清洗和转换,例如数据格式转换、数据合并等。
6. Spark Streaming
6.1 简介

Spark Streaming是Apache Spark提供的一个流处理模块,支持以微批次(mini-batches)的方式处理实时数据。它具有高性能、可伸缩性和容错性的特点,适用于聚合计算、实时分析和机器学习等场景。

6.2 主要特性
  • 高性能:Spark Streaming采用了内存计算方式,能够在毫秒级别的延迟下处理大规模的实时数据。
  • 容错性和可伸缩性:Spark Streaming支持容错性和弹性扩展的能力,可以在节点故障或数据倾斜的情况下保证数据处理的高可靠性和稳定性。
  • 数据源支持:Spark Streaming支持多种数据源,包括Kafka、Flume和HDFS等,使开发人员能够灵活地处理各种数据流。
  • 丰富的操作和转换:Spark Streaming提供了丰富的操作和转换函数,可以对数据流进行高效的处理、过滤和聚合操作。

最后

看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面

小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>

image

针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺

image

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

image

image

聚合操作。

最后

看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面

小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>

[外链图片转存中…(img-6FLRO9E7-1714506584301)]

针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺

[外链图片转存中…(img-rXnG3x3i-1714506584301)]

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

[外链图片转存中…(img-TDb2bhyC-1714506584302)]

[外链图片转存中…(img-hKBYcmtU-1714506584302)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值