我正在使用Apache Spark从Apache Kafka获取来自Json格式的任何传感器的实时数据。
数据格式示例:
{
"meterId" : "M1",
"meterReading" : "100"
}
我想应用规则来实时提高警报。即如果我没有从过去2小时获得“米M 1”的数据或者仪表读数超过某个限制,则应该创建警报。
那么如何在Scala中实现这一目标呢?
答案 0 :(得分:1)
我会在这里作为答案回答 - 评论太长了。
正如我所说,kafka中的json应该是:每行一条消息 - 发送此消息 - > {"meterId":"M1","meterReading":"100"}
如果您正在使用kafka,可以使用KafkaUtils创建流:
JavaPairDStream<String, String> input = KafkaUtils.createStream(jssc, zkQuorum, group, topics);
配对意味着<kafkaTopicName, JsonMessage>
。所以基本上你可以只看一下jsonmessage如果你不需要使用kafkaTopicName。
对于input
,您可以使用JavaPairDStream documentation中描述的许多方法 - 例如。您可以使用map来仅获取简单JavaDStream的消息。
当然,你可以使用一些json解析器,如gson
,jackson
或org.json
,它取决于用例,不同情况下的性能等等。
所以你需要做这样的事情:
JavaDStream<String> messagesOnly = input.map(
new Function<Tuple2<String, String>, String>() {
public String call(Tuple2<String, String> message) {
return message._2();
}
}
);
现在您只有带有kafka主题名称的消息,现在您可以使用您所描述的逻辑。
JavaPairDStream<String, String> alerts = messagesOnly.filter(
new Function<Tuple2<String, String>, Boolean>() {
public Boolean call(Tuple2<String, String> message) {
// here use gson parser e.g
// filter messages with meterReading that doesnt exceed limit
// return true or false based on your logic
}
}
);
此处您只有提醒信息 - 您可以将其发送到其他地方。
- 编辑后
以下是scala
// batch every 2 seconds
val ssc = new StreamingContext(sparkConf, Seconds(2))
ssc.checkpoint("checkpoint")
val topicMap = topics.split(",").map((_, numThreads.toInt)).toMap
def filterLogic(message: String): Boolean=
{
// here your logic for filtering
}
// map _._2 takes your json messages
val messages = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap).map(_._2)
// filtered data after filter transformation
val filtered = messages.filter(m => filterLogic(m))