簡體   English   中英

KSQL 查詢在簡單聚合中返回意外值

[英]KSQL Query returning unexpected values in simple aggregation

我從針對本身由 Kafka 主題定義的 KTable 的 KSQL 查詢中得到意外結果。 KTABLE 是“Trades”,它由壓縮主題“localhost.dbo.TradeHistory”支持。 它應該包含由 TradeId 鍵入的股票交易的最新信息。 主題的鍵是 TradeId。 每筆交易都有一個 AccountId,我正在嘗試構建一個查詢來獲取按賬戶分組的交易金額的總和。

交易KTABLE的定義

ksql> create table Trades(TradeId int, AccountId int, Spn int, Amount double) with (KAFKA_TOPIC = 'localhost.dbo.TradeHistory', VALUE_FORMAT = 'JSON', KEY = 'TradeId');

...

ksql> describe extended Trades;

Name                 : TRADES
Type                 : TABLE
Key field            : TRADEID
Key format           : STRING
Timestamp field      : Not set - using <ROWTIME>
Value format         : JSON
Kafka topic          : localhost.dbo.TradeHistory (partitions: 1, replication: 1)

Field     | Type
---------------------------------------
ROWTIME   | BIGINT           (system)
ROWKEY    | VARCHAR(STRING)  (system)
TRADEID   | INTEGER
ACCOUNTID | INTEGER
SPN       | INTEGER
AMOUNT    | DOUBLE
---------------------------------------

Local runtime statistics
------------------------
consumer-messages-per-sec:         0 consumer-total-bytes:      3709 consumer-total-messages:        39     last-message: 2019-10-12T20:52:16.552Z

(Statistics of the local KSQL server interaction with the Kafka topic localhost.dbo.TradeHistory)

localhost.dbo.TradeHistory 主題的配置

/usr/bin/kafka-topics --zookeeper zookeeper:2181 --describe --topic localhost.dbo.TradeHistory
Topic:localhost.dbo.TradeHistory    PartitionCount:1    ReplicationFactor:1 Configs:min.cleanable.dirty.ratio=0.01,delete.retention.ms=100,cleanup.policy=compact,segment.ms=100
    Topic: localhost.dbo.TradeHistory   Partition: 0    Leader: 1   Replicas: 1 Isr: 1

在我的測試中,我使用 TradeId 2 向 localhost.dbo.TradeHistory 主題添加消息,這些消息只是更改了交易量。 僅更新金額; AccountId 保持為 1。

localhost.dbo.TradeHistory 主題中的消息

/usr/bin/kafka-console-consumer --bootstrap-server broker:9092 --property print.key=true --topic localhost.dbo.TradeHistory --from-beginning

... (earlier values redacted) ...

2   {"TradeHistoryId":47,"TradeId":2,"AccountId":1,"Spn":1,"Amount":106.0,"__table":"TradeHistory"}
2   {"TradeHistoryId":48,"TradeId":2,"AccountId":1,"Spn":1,"Amount":107.0,"__table":"TradeHistory"}

上面的主題轉儲顯示交易量 2(在賬戶 1 中)從 106.0 變為 107.0。

KSQL 查詢

ksql> select AccountId, count(*) as Count, sum(Amount) as Total from Trades group by AccountId;
1 | 1 | 106.0
1 | 0 | 0.0
1 | 1 | 107.0

問題是,為什么上面顯示的 KSQL 查詢每次我發布交易更新時都會返回一個“中間”值。 如您所見,Count 和 Amount 字段顯示 0,0,然后 KSQL 查詢立即將其“更正”為 1,107.0。 我對這種行為有點困惑。

誰能解釋一下?

非常感謝。

謝謝你的問題。 我在我們的知識庫中添加了一個答案: https://github.com/confluentinc/ksql/pull/3594/files

當 KSQL 看到對表中現有行的更新時,它會在內部發出一個 CDC 事件,其中包含舊值和新值。 聚合通過在應用新值之前首先撤消舊值來處理此問題。

因此,在上面的示例中,當第二次插入發生時,KSQL 首先撤消舊值。 這導致COUNT下降 1, SUM下降舊值106.0 ,即下降到零。 然后 KSQL 應用新的行值,它看到COUNT增加 1 並且SUM增加新值107.0

默認情況下,KSQL 配置為將結果緩沖最多2 秒或 10MB 數據,然后再將結果刷新到 Kafka。 這就是為什么在此示例中插入值時您可能會在 output 上看到輕微延遲的原因。 如果兩個 output 行被緩沖在一起,那么 KSQL 將抑制第一個結果。 這就是為什么您經常看不到中間行是 output。 配置commit.interval.mscache.max.bytes.buffering分別設置為 2 秒和 10MB,可用於調整此行為。 將這些設置中的任何一個設置為零將導致 KSQL 始終 output 所有中間結果。

如果您每次都看到這些中間結果 output,那么很可能您已將這些設置中的一個或兩個設置為零。

我們有一個Github 問題來增強 KSQL 以利用 Kafka Stream 的抑制功能,這將允許用戶更好地控制結果的實現方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM