Kafka Streams 词频统计应用
一、Kafka Streams 概述
Kafka Streams是Apache Kafka开源的一个流处理框架,基于Kafka的生产者和消费者,为开发者提供流式处理能力,具有低延迟性、高扩展性、高弹性、高容错的特点,易于集成到现有应用程序中。
它是一套处理分析Kafka中存储数据的客户端类库,处理完的数据可重新写回Kafka,也可发送给外部存储系统。
在流式计算框架模型中,通常需要构建数据流的拓扑结构,例如生产数据源、分析数据的处理器及处理完后发送的目标节点,Kafka流处理框架同样将“输入主题自定义处理器输出主题”抽象成一个DAG拓扑图。
生产者作为数据源不断生产和发送消息至 Kafka 的 ittheme 主题中,通过自定义处理器对每条消息执行相应计算逻辑,最后将结果发送到 Kafka 的 ittheme2 主题中供消费者消费消息数据。
二、Kafka Streams 实践词频统计
2.1 添加依赖
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
<version>2.4.0</version>
</dependency>
注意这里我们要注意版本号一致,避免版本不兼容。
2.2 创建目标主题与接受主题
把 ittheme 主题作为信息来源,再创建一个主题ittheme2,把 ittheme2 作为目标主题接收 ittheme主题的信息;ittheme的主题以生产者信息输出到 ittheme2消费者,ittheme2主题以词频统计方式读取消费者内容。
由于我们之前已经创建了ittheme主题,接下来只需创建ittheme2 主题。
(详情请点击)Kafka集群分布式部署与测试 —— 实操版
# 1.创建ittheme2 主题
kafka-topics.sh --create --topic ittheme2 --partitions 3 --replication-factor 2 --zookeeper master:2181,slave1:2181,slave2:2181
# 2.创建ittheme2生产者
kafka-console-producer.sh --broker-list master:9092,slave1:9092,slave2:9092 --topic ittheme2
# 3.创建ittheme2消费者
kafka-console-consumer.sh --from-beginning --topic ittheme2 --bootstrap-server master:9092,slave1:9092,slave2:9092
如何实现把 ittheme主题作为信息来源,传输到另一个主题ittheme2呢?
我们需要用Kafka Streams 实现词频统计应用,在IDEA上用代码实现。
2.3 代码实现
(1)LogProcessor.java 实现
import org.apache.kafka.streams.processor.Processor;
import org.apache.kafka.streams.processor.ProcessorContext;
import java.util.HashMap;
public class LogProcessor implements Processor<byte[],byte[]> {
//上下文对象
private ProcessorContext processorContext;
public void init(ProcessorContext processorContext) {
//初始化方法
this.processorContext=processorContext;
}
public void process(byte[] key, byte[] value) {
//处理一条消息
String inputOri = new String(value);
HashMap <String,Integer> map = new HashMap<String,Integer>();
int times = 1;
if(inputOri.contains(" ")){
//截取字段
String [] words = inputOri.split(" ");
for (String word : words){
if(map.containsKey(word)){
map.put(word,map.get(word)+1);
}else{
map.put(word,times);
}
}
}
inputOri = map.toString();
processorContext.forward(key,inputOri.getBytes());
}
public void close() {}
}
(2)主程序 App
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.Topology;
import org.apache.kafka.streams.processor.Processor;
import org.apache.kafka.streams.processor.ProcessorSupplier;
import java.util.Properties;
public class App {
public static void main(String[] args) {
//声明来源主题
String fromTopic = "ittheme";
//声明目标主题
String toTopic = "ittheme2";
//设置参数
Properties props = new Properties();
props.put(StreamsConfig.APPLICATION_ID_CONFIG,"LogProcessor");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG,"master:9092,slave1:9092,slave2:9092");
//实例化StreamsConfig
StreamsConfig config = new StreamsConfig(props);
//构建拓扑结构
Topology topology = new Topology();
//添加源处理节点,为源处理节点指定名称和它订阅的主题
topology.addSource("SOURCE",fromTopic)
//添加自定义处理节点,指定名称,处理器类和上一个节点的名称
.addProcessor("PROCESSOR", new ProcessorSupplier() {
public Processor get() {//调用这个方法,就知道这条数据用哪个process处理,
return new LogProcessor();
}
},"SOURCE")
//添加目标处理节点,需要指定目标处理节点的名称,和上一个节点名称。
.addSink("SINK",toTopic,"PROCESSOR");//最后给SINK
//实例化KafkaStreams
KafkaStreams streams = new KafkaStreams(topology,config);
streams.start();
}
}
(3)执行测试
运行App程序后,在master 的 ittheme主题 生产者producer输入 11 11 11 5;
slave1 的 ittheme2 主题 消费者 consumer 经过统计后输出结果。