Apache Flink使用Windows在写入Sink之前引发延迟

时间:2017-05-24 13:04:35

标签: apache-flink flink-streaming

我想知道Flink窗口是否有可能导致从数据进入管道直到将其写入Cassandra中的表时延迟10分钟。

我的初衷是将每个事务写入Cassandra中的表并使用Web层的范围键查询表,但由于数据量的原因,我正在寻找延迟写入N秒的选项。这意味着我的表只能拥有至少10分钟的数据。

下面的小图显示了每分钟滚动的10分钟窗口。随着时间的推移,我只想将数据写入超过10分钟的Cassandra(绿色部分)。我想这对Flink来说甚至可能吗?

enter image description here

我可以创建每分钟滚动11分钟的窗口,但我最终会丢掉90%的数据,这似乎是浪费。

最终解决方案

我创建了自己的FlinkKafkaConsumer09名为DelayedKafkaConsumer的主题,其主要原因是覆盖了KafkaFetcher的创建

public class DelayedKafkaConsumer<T> extends FlinkKafkaConsumer09<T> {

    private ConsumerRecordFunction applyDelayAction;

    .............

    @Override
    protected AbstractFetcher<T, ?> createFetcher(SourceContext<T> sourceContext, Map<KafkaTopicPartition, Long> assignedPartitionsWithInitialOffsets,
                                                  SerializedValue<AssignerWithPeriodicWatermarks<T>> watermarksPeriodic,
                                                  SerializedValue<AssignerWithPunctuatedWatermarks<T>> watermarksPunctuated,
                                                  StreamingRuntimeContext runtimeContext, OffsetCommitMode offsetCommitMode) throws Exception {
        return new DelayedKafkaFetcher<>(
            sourceContext, assignedPartitionsWithInitialOffsets, watermarksPeriodic, watermarksPunctuated,
            runtimeContext.getProcessingTimeService(), runtimeContext.getExecutionConfig().getAutoWatermarkInterval(),
            runtimeContext.getUserCodeClassLoader(), runtimeContext.getTaskNameWithSubtasks(),
            runtimeContext.getMetricGroup(), this.deserializer, this.properties, this.pollTimeout, useMetrics, applyDelayAction);
    }

DelayedKafkaFetcher在其runFetchLoop中有一小段代码,在发出记录之前会休眠n毫秒。

private void delayMessage(Long msgTransactTime, Long nowMinusDelay) throws InterruptedException {

        if (msgTransactTime > nowMinusDelay) {
            Long sleepTimeout = msgTransactTime - nowMinusDelay;
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(format("Message with transaction time {0}ms is not older than {1}ms. Sleeping for {2}", msgTransactTime, nowMinusDelay, sleepTimeout));
            }
            TimeUnit.MILLISECONDS.sleep(sleepTimeout);
        }
    }

0 个答案:

没有答案