Kafka KSQL重新分区和密钥更新问题

时间:2019-11-19 00:20:57

标签: apache-kafka ksql

我已经定义了一个流

CREATE STREAM QUOTE (quoteId VARCHAR,
                      counterPartyId VARCHAR)
        WITH (KAFKA_TOPIC='quotes',
              VALUE_FORMAT='JSON',
              KEY='quoteId');

我想汇总到目前为止我得到了多少个报价,以及该事件的最后一个quoteId

CREATE TABLE KQUOTE AS
    SELECT Max(CAST(quoteId as INT)) as quoteId,COUNT(*) AS COUNT
        FROM QUOTE
        GROUP BY 1;

将此表转为流,原因是我想知道聚合结果历史记录。 (似乎我必须使用基础主题来创建流。无法直接从表'KQUOTE'中创建流。)

CREATE stream KQuoteStream (quoteId VARCHAR,
                      count INT)
        WITH (KAFKA_TOPIC='KQUOTE',
              VALUE_FORMAT='JSON',
              KEY='quoteId');

我希望以上使用RAWKEY quoteId,但事实并非如此。正如我们在下面看到的,RAWKEY始终为1(因为在创建表kquote时,我们将常量1分组)。

ksql> select * from KQuoteStream;
1574121797111 | 1 | 806 | 20
1574121979291 | 1 | 807 | 21

尝试通过quoteId重新对流进行分区,以将RAWKEY更改为quoteId

CREATE stream KQuoteStreamByQuoteId
        as
    SELECT quoteId, COUNT FROM KQuoteStream PARTITION BY quoteId;

RAMKEY仍为1

ksql> select * from KQuoteStreamByQuoteId;
1574121797111 | 1 | 806 | 20
1574121979291 | 1 | 807 | 21

顺便说一句:所有主题都具有与1相同的分区,以使事情变得更简单。 有人知道吗?非常感谢 !

1 个答案:

答案 0 :(得分:0)

那绝对是您发现的一个有趣的错误!

这里的诀窍是要了解WITH(KEY='quoteId')实际上并没有做任何事情,这向ksqlDB暗示了关键字段也恰好也存在于{{1 }}。然后,当您quoteId时,它认为您正在按行键进行分区,因此它什么也不做!我同意这种行为是非常不直观的,这就是为什么我们计划删除PARTITION BY quoteId功能以支持更直观(待定)的原因。

同时,解决方法应该是在创建WITH(KEY=...)指定密钥,以便KSQL不会优化重新分区。