KSQL KTabke + KTable连接重复结果异常

时间:2020-05-23 17:08:10

标签: apache-kafka ksqldb

我尝试内部连接ktable和ktable。

a b 表:

 create table a_table(r string, time string) with (Kafka_topic='a', Key='r', Value_format='json');
 create table b_table(r string, time string) with (Kafka_topic='b', Key='r', Value_format='json');
通过r键

内部联接 a b 表:

create table ab_table as select * from a_table inner join b_table on a_table.r = b_table.r emit changes;

1)用例。通过慢速模式插入新数据

 ksql> insert into a_table values('1','1', 'timeA');
 --wait 5 second;
 ksql> insert into b_table values('1','1', 'timeB');

select * from ab_table emit changes;-返回1行结果

print AB_TABLE from beginning;-返回1行结果

2)用例。通过快速模式插入新数据

 ksql> insert into a_table values('2','2', 'timeA');insert into b_table values('2','2', 'timeB');

  ksql>  print a from beginning;
    Key format: KAFKA_STRING
    Value format: JSON or KAFKA_STRING
    rowtime: 5/23/20 4:44:06 PM UTC, key: 2, value: {"R":"2","TIME":"timeA"}

   ksql> print b from beginning;
    Key format: KAFKA_STRING
    Value format: JSON or KAFKA_STRING
    rowtime: 5/23/20 4:44:06 PM UTC, key: 2, value: {"R":"2","TIME":"timeB"}

select * from ab_table emit changes;-返回1行结果

print AB_TABLE from beginning;-返回2行结果

rowtime: 5/23/20 4:44:06 PM UTC, key: 2, value: {"A_TABLE_ROWTIME":1590252246657,"A_TABLE_ROWKEY":"2","A_TABLE_R":"2","A_TABLE_TIME":"timeA","B_TABLE_ROWTIME":1590252246657,"B_TABLE_ROWKEY":"2","
B_TABLE_R":"2","B_TABLE_TIME":"timeB"}
rowtime: 5/23/20 4:44:06 PM UTC, key: 2, value: {"A_TABLE_ROWTIME":1590252246680,"A_TABLE_ROWKEY":"2","A_TABLE_R":"2","A_TABLE_TIME":"timeA","B_TABLE_ROWTIME":1590252246680,"B_TABLE_ROWKEY":"2","
B_TABLE_R":"2","B_TABLE_TIME":"timeB"}

什么是地狱?为什么在第二个用例中,我在主题中有两个重复的行?

有关主题\表的更新信息

    name                 : B_TABLE
     Field   | Type                      
    -------------------------------------
     ROWTIME | BIGINT           (system) 
     ROWKEY  | VARCHAR(STRING)  (system) 
     R       | VARCHAR(STRING)           
     TIME    | VARCHAR(STRING)  

    name                 : A_TABLE
     Field   | Type                      
    -------------------------------------
     ROWTIME | BIGINT           (system) 
     ROWKEY  | VARCHAR(STRING)  (system) 
     R       | VARCHAR(STRING)           
     TIME    | VARCHAR(STRING)  

    Name                 : AB_TABLE
     Field           | Type                      
    ---------------------------------------------
     ROWTIME         | BIGINT           (system) 
     ROWKEY          | VARCHAR(STRING)  (system) 
     A_TABLE_ROWTIME | BIGINT                    
     A_TABLE_ROWKEY  | VARCHAR(STRING)           
     A_TABLE_R       | VARCHAR(STRING)           
     A_TABLE_TIME    | VARCHAR(STRING)           
     B_TABLE_ROWTIME | BIGINT                    
     B_TABLE_ROWKEY  | VARCHAR(STRING)           
     B_TABLE_R       | VARCHAR(STRING)           
     B_TABLE_TIME    | VARCHAR(STRING)     


topic "a" with 1 partitions:
    partition 0, leader 1, replicas: 1, isrs: 1

topic "b" with 1 partitions:
    partition 0, leader 1, replicas: 1, isrs: 1

 topic "AB_TABLE" with 1 partitions:
    partition 0, leader 1, replicas: 1, isrs: 1

1 个答案:

答案 0 :(得分:1)

弄清楚这里发生了什么。这与缓冲有关。

默认情况下,ksqlDB正在缓冲来自两个源表更改日志的输入,即主题ab。 (此缓冲对于将报告同一键的更改的所有多条消息压缩为一个输出很有用)。

一次触发两个表的更新时,缓冲意味着刷新缓冲后将填充两个表。由于表-表联接的两端都产生输出,因此两个输入事件彼此匹配,从而导致主题AB_TABLE的两个输出。

PRINT AB_TABLE正确显示了变更日志中的两行。

但是,SELECT * FROM AB_TABLE EMIT CHANGES也在缓冲输入,并且此缓冲将两个更改压缩为一个输出。

可以通过cache.max.bytes.buffering控制缓冲。例如,您可以使用以下命令关闭缓冲:

-- turn off buffering:
SET 'cache.max.bytes.buffering' = 0;

运行以上命令后,我再次运行您的示例,并且AB_TABLE主题中只有一行。

一个人可能会争辩说,无论缓冲多少,表-表联接的正确输出都只是一行。毕竟,处理的第一行应该找不到匹配项,第二行应该找到匹配项。如果您对此有强烈的感觉,请在Github中提出一个错误。