尝试使用kafka流处理器API批处理记录。批处理基于大小和时间。可以说,如果批处理大小达到10,或者最后一个批处理的处理时间超过10秒(大小或最后处理时间以先到者为准),则调用外部API发送批处理并使用ProcessingContext提交。
使用punctuate
定期检查是否可以清除该批次并将其发送到外部系统。
问题-执行标点线程时,流API是否可以调用处理器API process
方法?由于代码在标点线程中调用提交,context.commit()
可以提交尚未由处理方法处理的记录吗?
是否可能在不同的线程中同时执行标点符号线程和处理方法?如果是这样,那么代码中我有尚未处理的提交记录
public class TestProcessor extends AbstractProcessor<String, String> {
private ProcessorContext context;
private List<String> batchList = new LinkedList<>();
private AtomicLong lastProcessedTime = new AtomicLong(System.currentTimeMillis());
private static final Logger LOG = LoggerFactory.getLogger(TestProcessor.class);
@Override
public void init(ProcessorContext context) {
LOG.info("Calling init method " + context.taskId());
this.context = context;
context.schedule(10000, PunctuationType.WALL_CLOCK_TIME, (timestamp) -> {
if(batchList.size() > 0 && System.currentTimeMillis() - lastProcessedTime.get() >
10000){
//call external API
batchList.clear();
lastProcessedTime.set(System.currentTimeMillis());
}
context.commit();
});
}
@Override
public void process(String key, String value) {
batchList.add(value);
LOG.info("Context details " + context.taskId() + " " + context.partition() + " " +
"storeSize " + batchList.size());
if(batchList.size() == 10){
//call external API to send the batch
batchList.clear();
lastProcessedTime.set(System.currentTimeMillis());
}
context.commit();
}
@Override
public void close() {
if(batchList.size() > 0){
//call external API to send the left over records
batchList.clear();
}
}
}
答案 0 :(得分:2)
在以下情况下,流API可以调用处理器API
process
方法吗?punctuate
线程正在执行?
不会,这是不可能的,因为Processor
在单个线程(两个方法使用相同的线程)中执行process
和punctuate
方法。
是否可能出现标点符号线程和处理方法 在不同线程中同时执行?
响应是“不可能的”,上面提供了描述。
请注意,每个主题分区都将拥有您的类TestProcessor
的实例。建议不要使用batchList
之类的Kafka状态存储,而不要使用局部变量lastProcessedTime
和KeyValueStore
,这样您的流将具有容错能力。