AWS Kinesis-如何从上一个检查点恢复使用

时间:2018-07-24 08:59:54

标签: java amazon-web-services amazon-kinesis

我正在使用KCL(v2)将Kafka使用者转换为AWS Kinesis使用者。在Kafka中,偏移量用于帮助消费者跟踪其最近消费的消息。如果我的Kafka应用程序死了,它将使用偏移量重新启动时从中断处开始消耗。

但是,这在Kinesis中并不相同。我可以设置kinesisClientLibConfiguration.withInitialPositionInStream(...),但是唯一的参数是TRIM_HORIZONLATESTAT_TIMESTAMP。如果我的Kinesis应用程序死了,它将不知道从重新启动时开始在哪里继续消费。

我的KCL使用者非常简单。 main()方法如下:

KinesisClientLibConfiguration config = new KinesisClientLibConfiguration("benTestApp",
            "testStream", new DefaultAWSCredentialsProviderChain(), UUID.randomUUID().toString());
config.withInitialPositionInStream(InitialPositionInStream.TRIM_HORIZON);

Worker worker = new Worker.Builder()
            .recordProcessorFactory(new KCLRecordProcessorFactory())
            .config(config)
            .build();

RecordProcessor是一个简单的实现:

@Override
public void initialize(InitializationInput initializationInput) {
    LOGGER.info("Initializing record processor for shard: {}", initializationInput.getShardId());
}

@Override
public void processRecords(ProcessRecordsInput processRecordsInput) {
    List<Record> records = processRecordsInput.getRecords();
    LOGGER.info("Retrieved {} records", records.size());
    records.forEach(r -> LOGGER.info("Record: {}", StandardCharsets.UTF_8.decode(r.getData())));
}

@Override
public void shutdown(ShutdownInput shutdownInput) {
    LOGGER.info("Shutting down input");
}

如果我检查相应的DynamoDB表,则checkpoint的值将设置为TRIM_HORIZON,并且在消耗记录时不会使用sequenceId更新。

这里确保我使用每条消息的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

由@kdgregory标识,KCL要求用户设置自己的检查点。工作代码:

@Override
public void initialize(InitializationInput initializationInput) {
    LOGGER.info("Initializing record processor for shard: {}", initializationInput.getShardId());
}

@Override
public void processRecords(ProcessRecordsInput processRecordsInput) {
    List<Record> records = processRecordsInput.getRecords();
    LOGGER.info("Retrieved {} records", records.size());
    records.forEach(r -> LOGGER.info("Record with sequenceId {} at date {} : {}", r.getSequenceNumber(),
            r.getApproximateArrivalTimestamp(), StandardCharsets.UTF_8.decode(r.getData())));
    try {
        processRecordsInput.getCheckpointer().checkpoint();
    } catch (InvalidStateException | ShutdownException e) {
        LOGGER.error("Unable to checkpoint");
    }
}

@Override
public void shutdown(ShutdownInput shutdownInput) {
    LOGGER.info("Shutting down input");
    try {
        shutdownInput.getCheckpointer().checkpoint();
    } catch (InvalidStateException | ShutdownException e) {
        LOGGER.error("Unable to checkpoint");
    }
}