![](/img/trans.png)
[英]How does Kafka Stream send final aggregation with KTable#Suppress?
[英]How does this aggregation works in the Kafka stream?
我是 Apache Kafka 的新手。 我閱讀了一個 Steam 應用程序的代碼,偶然發現了聚合操作。 我試圖自己理解它,如果我的解釋正確,我需要確認。
下面提供了從主題和聚合中讀取的代碼片段,
// json Serde
final Serializer<JsonNode> jsonSerializer = new JsonSerializer();
final Deserializer<JsonNode> jsonDeserializer = new JsonDeserializer();
final Serde<JsonNode> jsonSerde = Serdes.serdeFrom(jsonSerializer, jsonDeserializer);
KStreamBuilder builder = new KStreamBuilder();
// read from the topic 'bank-transactions' as `KStream`. I provided the producer below
KStream<String, JsonNode> bankTransactions = builder.stream(Serdes.String(), jsonSerde, "bank-transactions");
// we define the grouping and aggregation here
KTable<String, JsonNode> bankBalance = bankTransactions.groupByKey(Serdes.String(), jsonSerde)
.aggregate(
() -> initialBalance,
(key, transaction, balance) -> newBalance(transaction, balance),
jsonSerde,
"bank-balance-agg"
);
到bank-transactions
主題的數據流產生如下,
public static ProducerRecord<String, String> newRandomTransaction(String name) {
// creates an empty json {}
ObjectNode transaction = JsonNodeFactory.instance.objectNode();
Integer amount = ThreadLocalRandom.current().nextInt(0, 100);
// Instant.now() is to get the current time using Java 8
Instant now = Instant.now();
// we write the data to the json document
transaction.put("name", name);
transaction.put("amount", amount);
transaction.put("time", now.toString());
return new ProducerRecord<>("bank-transactions", name, transaction.toString());
}
初始余額如下啟動,
// create the initial json object for balances
ObjectNode initialBalance = JsonNodeFactory.instance.objectNode();
initialBalance.put("count", 0);
initialBalance.put("balance", 0);
initialBalance.put("time", Instant.ofEpochMilli(0L).toString());
newBalance
方法接受交易和余額並返回新余額,
private static JsonNode newBalance(JsonNode transaction, JsonNode balance) {
// create a new balance json object
ObjectNode newBalance = JsonNodeFactory.instance.objectNode();
newBalance.put("count", balance.get("count").asInt() + 1);
newBalance.put("balance", balance.get("balance").asInt() + transaction.get("amount").asInt());
Long balanceEpoch = Instant.parse(balance.get("time").asText()).toEpochMilli();
Long transactionEpoch = Instant.parse(transaction.get("time").asText()).toEpochMilli();
Instant newBalanceInstant = Instant.ofEpochMilli(Math.max(balanceEpoch, transactionEpoch));
newBalance.put("time", newBalanceInstant.toString());
return newBalance;
}
我有兩個關於分組和聚合的問題,
一種。 是groupByKey
由分組Serdes.String()
和jsonSerde
只執行對蒸汽數據序列化和反序列化? Serdes.String()
是newRandomTransaction
方法中的名稱字符串。
灣我的主張是key, transaction
里面aggregation
了線的功能(key, transaction, balance) -> newBalance(transaction, balance)
從讀取bank-transactions
的話題和balance
從未來initialBalance
從上一行。 那是對的嗎?
盡管它無縫運行,但我在嘗試調試該應用程序時也感到困惑。
groupByKey 是否按 Serdes.String() 分組,而 jsonSerde 僅對 Steam 數據執行序列化和反序列化?
是的,groupByKey 是按鍵分組,可以反序列化並作為字符串進行比較
我的斷言是行 (key, transaction, balance) -> newBalance(transaction, balance) 的聚合函數中的關鍵,交易是從銀行交易主題中讀取的,余額來自上一行的 initialBalance
幾乎。 初始化器在第一個參數上,是的,但是聚合的結果在應用程序的整個執行過程中都被結轉,無休止地聚合。
換句話說,您總是從initialBalance
開始,然后對於每個相同的鍵,您將該transaction
的余額添加到該鍵的當前累積balance
中。 如果您還沒有看到重復的密鑰,那么它才會被添加到初始余額中
是的,您的輸入主題是由 KStreams builder.stream
方法指定的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.