KGroupedTable.count()返回负值吗?
idAndJobTransaction
.filter((k,v) -> v!=null)
.mapValues(jobTransaction -> {
jobTransaction.setCount(0);
jobTransaction.setId(0L);
jobTransaction.setRunsheet_id(0L);
jobTransaction.setTimestamp(0L);
if(jobTransaction.getDelete_flag() == 1)
return null;
else
return jobTransaction;
} )
.groupBy((id,jobTransaction)->new KeyValue<>(jobTransaction,jobTransaction),Serialized.with(jobTransactionSerde,jobTransactionSerde))
.count()
.toStream()
.mapValues((k,v)-> new JobSummary(k,v))
.peek((k,v)->{
log.info(k.toString());
log.info(v.toString());
}).selectKey((k,v)-> v.getCompany_id()) // So that the count is consumed in order for each company
.to(JOB_SUMMARY,Produced.with(Serdes.Long(),jobSummarySerde));
count方法有时返回负值。大约1%的值是负数。那怎么可能?
编辑1:
我将这种聚合的结果推送到Postgres表中。负值不限于-1,但会变为非常高的值。
我正在使用2个消费者。这有什么区别吗?
Kafka流是否会成为问题?还是我应该研究其他可能的原因?
编辑3: 我能够捕获一些可用的日志,但确实在偷看中看到了负值:
对于JobSummary类,它实际上是一个非常简单的POJO类。这是KStream应用中调用的构造函数。
public JobSummary(JobTransaction j, Long count){
this.setUser_id(j.getUser_id());
this.setHub_id(j.getHub_id());
this.setCity_id(j.getCity_id());
this.setCompany_id(j.getCompany_id());
this.setJob_master_id(j.getJob_master_id());
this.setJob_status_id(j.getJob_status_id());
this.setCount(count);
this.setDate(j.getDate());
}
答案 0 :(得分:1)
我想(这是我唯一能提出的解释),这是一个特殊的极端情况。首先,您必须了解KTable
聚合在内部如何工作。这在另一个问题上得到了解释:TopologyTestDriver sending incorrect message on KTable aggregations
在这种背景下,如果结果表中的当前计数为零,并且上游基表(即idAndJobTransaction
)得到幂等更新(即,基本表从<K,V>
更新为<K,V>
。这将导致一条减法和一条加法记录进入结果表的同一行(请注意,Kafka Streams不会比较新旧数据)表中的值更新,并且盲目地认为两者是不同的。)此外,减法和加法记录被独立地发送到下游,并且下游count()
分两步更新其结果,因此,结果表中的计数从0开始到-1处理减法记录,然后从-1返回到0处理加法记录。