[英]Kafka Streams Split 1 Stream in Multiple Stream
我有一個 Projekt 來學習使用 Kafka Streams,但我真的遇到了麻煩。 我正在研究 kafka-streams 版本 1.0.1。 我們有一個主題 Stream,其消息具有以下樣式:
{
"phenomenonTime" : "2017-04-03T16:08:19.000Z",
"resultTime" : "2017-04-03T16:08:19.000Z",
"result" : {
"Temperature" : 0,
"Pressure" : 0,
"Humidity" : 0,
"Mean altitude" : 0,
"Mass PM2.5" : 7.4,
"Mass Error PM2.5" : 1.5,
"Mass PM10" : 12.3,
"Mass Error PM10" : 1.5
}
}
這是一個 Json 格式,這是我的第一個問題,我不知道如何使用 Json Deserializer 或 Serializer。
但我的主要目標是創建主題溫度、壓力、濕度、平均高度……從主要主題的結果字段中創建溫度主題中的正確值。
我如何通過 Kafka Streams 實現這一點? 我希望你能幫助我更好地開始使用 Kafka Streams。
編輯:
Hole Message + key(格式化)
Key c45e9532-9810-11e8-8839-03e1e3365152
Value { "phenomenonTime" : "2017-04-03T16:08:09.000Z",
"resultTime" : "2017-04-03T16:08:09.000Z",
"result" : { "Temperature" : 0,
"Pressure" : 0,
"Humidity" : 0,
"Mean altitude" : 0,
"Mass PM2.5" : 7.1,
"Mass Error PM2.5" : 1.5,
"Mass PM10" : 9.6, "Mass Error PM10" : 1.5 },
"Datastream@iot.navigationLink" : "http://localhost:8080/FROST-Server/v1.0/Observations('c45e9532-9810-11e8-8839-03e1e3365152')/Datastream",
"Datastream" : { "unitOfMeasurement" : { "name" : null, "symbol" : null, "definition" : null }, "@iot.id" : "geo.uni-augsburg.de/Fixed-Wing-UAV-1/Datastreams/LOAC_LOCAL_201704031605.mass" },
"FeatureOfInterest@iot.navigationLink" : "http://localhost:8080/FROST-Server/v1.0/Observations('c45e9532-9810-11e8-8839-03e1e3365152')/FeatureOfInterest",
"FeatureOfInterest" : { "@iot.id" : "c458a1a4-9810-11e8-8839-176a6dbe6951" }, "@iot.id" : "c45e9532-9810-11e8-8839-03e1e3365152", "@iot.selfLink" : "http://localhost:8080/FROST-Server/v1.0/Observations('c45e9532-9810-11e8-8839-03e1e3365152')" }
未格式化:
Key c45e9532-9810-11e8-8839-03e1e3365152
Value { "phenomenonTime" : "2017-04-03T16:08:09.000Z", "resultTime" : "2017-04-03T16:08:09.000Z", "result" : { "Temperature" : 0, "Pressure" : 0, "Humidity" : 0, "Mean altitude" : 0, "Mass PM2.5" : 7.1, "Mass Error PM2.5" : 1.5, "Mass PM10" : 9.6, "Mass Error PM10" : 1.5 }, "Datastream@iot.navigationLink" : "http://localhost:8080/FROST-Server/v1.0/Observations('c45e9532-9810-11e8-8839-03e1e3365152')/Datastream", "Datastream" : { "unitOfMeasurement" : { "name" : null, "symbol" : null, "definition" : null }, "@iot.id" : "geo.uni-augsburg.de/Fixed-Wing-UAV-1/Datastreams/LOAC_LOCAL_201704031605.mass" }, "FeatureOfInterest@iot.navigationLink" : "http://localhost:8080/FROST-Server/v1.0/Observations('c45e9532-9810-11e8-8839-03e1e3365152')/FeatureOfInterest", "FeatureOfInterest" : { "@iot.id" : "c458a1a4-9810-11e8-8839-176a6dbe6951" }, "@iot.id" : "c45e9532-9810-11e8-8839-03e1e3365152", "@iot.selfLink" : "http://localhost:8080/FROST-Server/v1.0/Observations('c45e9532-9810-11e8-8839-03e1e3365152')" }
但是 Datastream@iot.navigationLink、Datastream.... 不是重要的。 但是Key必須是一樣的。
這就是它的樣子( https://i.imgur.com/zvwf3g7.png )
孔導出 Stream:
示例 Kafka 客戶端:
為此,您需要為每個所需的目標主題創建多個KStream
對象。 要從主 json 中提取所需字段,請在 kStream 上使用mapValues
方法。 為了簡化 json 值的工作,您可以使用spring-kafka
庫中的JsonSerde
(groupId:org.springframework.kafka,artifactId:spring-kafka)。
溫度和壓力主題的示例(並對每個所需的目標主題執行相同的操作):
Map<String, String> streamProperties = new HashMap<>();
streamProperties.put("bootstrap.servers", "localhost:9092");
streamProperties.put("key.serde", "org.apache.kafka.common.serialization.Serdes$StringSerde");
streamProperties.put("value.serde", "org.apache.kafka.common.serialization.Serdes$StringSerde");
Map<String, String> streamProperties1 = new HashMap<>(streamProperties);
streamProperties1.put("application.id", "temperature");
Map<String, String> streamProperties2 = new HashMap<>(streamProperties);
streamProperties2.put("application.id", "pressure");
Class<Map<String, Object>> genericMapClass = (Class) Map.class;
Consumed<String, Map<String, Object>> consumed = Consumed.with(Serdes.String(), new JsonSerde<>(genericMapClass));
Produced<String, Map<String, Object>> produced = Produced.with(Serdes.String(), new JsonSerde<>(genericMapClass));
StreamsBuilder streamBuilder1 = new StreamsBuilder();
KStream<String, Map<String, Object>> temperatureKStream = streamBuilder1.stream("mainSourceTopic", consumed);
temperatureKStream.mapValues((generalDetails) -> {
Object temperatureValue = ((Map) generalDetails.get("result")).get("Temperature");
Map<String, Object> temperatureMessageDetails = new HashMap<>();
temperatureMessageDetails.put("Temperature", temperatureValue);
temperatureMessageDetails.put("phenomenonTime", generalDetails.get("phenomenonTime"));
temperatureMessageDetails.put("resultTime", generalDetails.get("resultTime"));
System.out.println("temperatureMessageDetails: " + temperatureMessageDetails);
return temperatureMessageDetails;
}).to("temperatureTopic", produced);
StreamsBuilder streamBuilder2 = new StreamsBuilder();
KStream<String, Map<String, Object>> pressureKStream = streamBuilder2.stream("mainSourceTopic", consumed);
pressureKStream.mapValues((generalDetails) -> {
Object pressureValue = ((Map) generalDetails.get("result")).get("Pressure");
Map<String, Object> pressureMessageDetails = new HashMap<>();
pressureMessageDetails.put("Pressure", pressureValue);
pressureMessageDetails.put("phenomenonTime", generalDetails.get("phenomenonTime"));
pressureMessageDetails.put("resultTime", generalDetails.get("resultTime"));
System.out.println("pressureMessageDetails: " + pressureMessageDetails);
return pressureMessageDetails;
}).to("pressureTopic", produced);
StreamsConfig streamsConfig1 = new StreamsConfig(streamProperties1);
KafkaStreams kafkaStreams1 = new KafkaStreams(streamBuilder1.build(), streamsConfig1);
kafkaStreams1.start();
StreamsConfig streamsConfig2 = new StreamsConfig(streamProperties2);
KafkaStreams kafkaStreams2 = new KafkaStreams(streamBuilder2.build(), streamsConfig2);
kafkaStreams2.start();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
kafkaStreams1.close();
kafkaStreams2.close();
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.