一、Kafka-Streams是什么?
Kafka Streams是一个用于构建应用程序和微服务的客户端库,其中输入和输出数据存储在Kafka集群中,它结合了在客户端编写和部署标准Java和Scala应用程序的简单性与Kafka的服务器端集群技术的优势。
它是编写实时应用程序和微服务的最简单方法。
二、Kafka-Streams优点
1、弹性、高度可扩展、容错
2、可以部署到容器、虚拟机、裸机、云
3、同样适用于小型、中型和大型用例
4、与Kafka安全完全集成
5、编写标准的Java和Scala应用程序
6、一次处理语义
7、不需要单独的处理集群
8、支持在Mac、Linux、Windows上开发
三、WordCount代码示例
java
public class WordCountApplication {
public static void main(final String[] args) throws Exception {
Properties props = new Properties();
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-application");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-broker1:9092");
props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> textLines = builder.stream("TextLinesTopic");
KTable<String, Long> wordCounts = textLines
.flatMapValues(textLine -> Arrays.asList(textLine.toLowerCase().split("\\W+")))
.groupBy((key, word) -> word)
.count(Materialized.<String, Long, KeyValueStore<Bytes, byte[]>>as("counts-store"));
wordCounts.toStream().to("WordsWithCountsTopic", Produced.with(Serdes.String(), Serdes.Long()));
KafkaStreams streams = new KafkaStreams(builder.build(), props);
streams.start();
}
}
它实现了WordCount算法,该算法从输入文本中计算单词,且可以对无限的、无界的数据流进行操作。与有界变体类似,它是一种跟踪和更新单词计数的有状态算法。但是,由于它必须假设潜在的无界输入数据,它将定期输出其当前状态和结果,同时继续处理更多数据,因为它无法知道何时处理了"所有"输入数据。
下面我们就实际来跑下这个程序
四、运行官方示例程序
1、创建名为streams-plaintext-input的输入topic
kafka-topics --create \
--bootstrap-server cdh1:9092 \
--replication-factor 1 \
--partitions 1 \
--topic streams-plaintext-input
2、创建名为streams-wordcount-output的输出topic
kafka-topics --create \
--bootstrap-server cdh1:9092 \
--replication-factor 1 \
--partitions 1 \
--topic streams-wordcount-output \
--config cleanup.policy=compact
3、启动WordCountDemo
kafka-run-class org.apache.kafka.streams.examples.wordcount.WordCountDemo
以上是官方的WordCountDemo启动,它源码中指定的bootstrap.servers是localhost:9092,如果是集群环境会报错
我们这里把WordCountDemo放到自己的maven项目中进行修改并运行。
WordCountDemo将从输入topic:streams-plaintext-input读取,对每个读取的消息执行WordCount算法的计算,并将其当前结果连续写入输出topic:streams-wordcount-output。因此,除了日志条目之外,不会有任何STDOUT输出,因为结果会在Kafka中写回。
4、测试观察
下面我们启动控制台生产者和消费者来测试下
kafka-console-producer --topic streams-plaintext-input --broker-list cdh1:9092,cdh2:9092,cdh3:9092
kafka-console-consumer --bootstrap-server cdh1:9092 \--topic streams-wordcount-output \
--from-beginning \
--property print.key=true \
--property print.value=true \
--property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer \
--property value.deserializer=org.apache.kafka.common.serialization.LongDeserializer
下面我们在producer端的控制台输入单词:
aaa bbb ccc ddd
我们再看看consumer端的情况:
我们继续输入
aaa ccc xxx
我们再看看consumer端的情况:
37那个可以忽略,因为crt每30秒回输入下回车
我们看到每次只会统计当次输入单词在历史数据中的count