[英]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.