[英]Count messages from kafka topic all hour
我想统计来自kakfa主题的消息。
例如,我有这个案例类:
case class Message(timestamp: LocalDateTime)
我收到此类信息,我想计算一下我在一小时内收到多少信息。 假设消息在该主题中排序(时间戳对应于消息在主题中输入的时间)。
我想创建一个这样的案例类:
case class Counter(datetime: LocalDateTime, count: Int)
假设第一个小时我收到100条消息,那么我将收到150条消息:
Counter("2018-05-17 00:00:00", 100)
Counter("2018-05-17 00:01:00", 150)
有什么想法吗? 有关信息,我不能/不想使用kafka-streams。
谢谢!
编辑:
我的资料来源是我想与Consumer API一起使用的kafka主题。 我的接收器是一个postgresql表。
所需的解决方案通常在流处理术语中称为窗口化 ,大多数流处理库都将此作为功能。 Software Mill有一个很好的文章 ,比较了Spark Streaming,Flink,Kafka Streams和Akka Streams。
您可以尝试自己实现它,但是上面提到的库都经过了严格的测试,并具有简单易读的API。 如果您不想使用Kafka Streams,那么其中一项评论( Alpakka项目的一部分)中提到的Akka Streams Kafka值得考虑。
我想出了Flink
解决方案。
我阅读了Flink中有关时间窗口的一些文档,并且此页面讨论了有关主题中的升序时间戳(这是我的情况)。
所以这里是一个解决方案:
val inputStream: DataStream[Message] = env.addSource(kafkaConsumer)
val timedStream: DataStream[Message] = inputStream
.assignAscendingTimestamps(_.timestamp)
val timeWindow = timedStream.timeWindowAll(Time.minutes(1)).sum(1)
它计算1分钟内翻滚窗口内的所有元素。
对于更具体的解决方案,并到达Counter("2018-05-17 00:00:00", 100)
我们必须扩展AllWindowFunction
:
class CustomWindowFunction extends AllWindowFunction[Message, Counter, TimeWindow] {
def apply(window: TimeWindow, input: Iterable[Message], out: Collector[Counter]): Unit = {
out.collect(
Counter(
new LocalDateTime(window.getStart),
input.size
)
)
}
}
然后将其应用于我们的timeStream:
val inputStream: DataStream[MyClass] = env.addSource(kafkaConsumer)
val timedStream: DataStream[MyClass] = inputStream
.assignAscendingTimestamps(_.timestamp)
val timeWindow = timedStream.timeWindowAll(Time.minutes(1)).apply(new CustomWindowFunction())
如果在输入的主题中有Message
类,则在最后获得Counter
类。
这是我现在发现的“更好”的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.