Flink的checkpoint 参数相关

553 阅读5分钟

Flink 是一个分布式流处理框架,能够支持精确一次(Exactly-Once)的状态一致性保证。为了实现这种精确一次的语义,Flink 采用了 Checkpointing 机制来保存应用程序的状态。本文将详细介绍 Flink Checkpoint 的相关参数。

Checkpoint 是指在运行 Flink 应用程序时,周期性地将应用程序的状态进行快照,并将这个状态保存到持久化存储设备中。如果应用程序发生故障,Flink 可以从最近的 Checkpoint 中恢复应用程序状态,使得应用程序能够继续执行而不会出现任何数据丢失的情况。

在 Flink 中,Checkpoint 有以下几个关键参数:

  1. checkpointing.mode

这个参数定义了应用程序使用的 Checkpoint 模式。默认值是 EXACTLY_ONCE,也就是精确一次模式。还可以选择 AT_LEAST_ONCE 模式或者 DISABLED 关闭 Checkpoint。

  1. checkpointing.interval

这个参数定义了两个 Checkpoint 之间的时间间隔。通常情况下,Checkpoint 时间间隔需要根据应用程序的特点进行调整。如果 Checkpoint 时间间隔过长,那么应用程序需要容忍更多的数据丢失风险;如果 Checkpoint 时间间隔过短,那么会增加 Checkpoint 的负担和延迟。

  1. checkpointing.timeout

这个参数定义了 Checkpoint 的超时时间。如果一个 Checkpoint 操作在这个时间内没有完成,那么 Flink 将会放弃当前的 Checkpoint 并继续进行下一个 Checkpoint 操作。

  1. checkpointing.min-pause

这个参数定义了两次 Checkpoint 之间最小的时间间隔。如果上一个 Checkpoint 操作还没有完成,那么 Flink 将会等待一段时间才会启动下一个 Checkpoint 操作。

  1. checkpointing.max-concurrent-checkpoints

这个参数定义了同时进行的最大 Checkpoint 数量。如果当前正在进行的 Checkpoint 数量已经达到了这个阈值,那么 Flink 将不会启动新的 Checkpoint 操作。

  1. checkpointing.checkpoint-idle-timeout

这个参数定义了当应用程序处于空闲状态时,自动触发的 Checkpoint 时间。如果应用程序在这个时间内没有任何输入数据,那么 Flink 将会自动触发一个 Checkpoint。

  1. state.backend

这个参数定义了应用程序使用的状态后端类型。Flink 支持多种不同类型的状态后端,包括 MemoryStateBackend、FileSystemStateBackend 和 RocksDBStateBackend 等。不同的状态后端有着各自的优缺点,需要根据实际情况进行选择。

  1. state.checkpoints.dir

这个参数定义了 Checkpoint 数据保存的位置。通常情况下,建议将 Checkpoint 数据保存到分布式文件系统中,比如 HDFS 或者 S3 等。

除了上述参数之外,Flink 还支持对 Checkpoint 进行更加细粒度的配置。比如可以设置是否在进行 Checkpoint 时暂停任务执行,或者设置是否在进行 Checkpoint 时取消正在等待的任务等。通过合理的配置,能够进一步提升 Flink 应用程序的性能和可靠性。 除此之外Checkpoint 有多种类型,包括全局 checkpoint、自定义 checkpoint 和 local checkpoint。下面详细介绍 Flink 的 Checkpoint 参数。

  1. 全局 checkpoint 全局 checkpoint 是 Flink 集群中最常用的一种 checkpoint 类型。它可以让 Flink 集群自动化地重启失败的任务,而不需要手动执行 stop-all 命令。 全局 checkpoint 有以下参数:
  • checkpoint.period.bytes:指定全局 checkpoint 的时间间隔,单位为字节。

  • checkpoint.strategy:指定全局 checkpoint 的触发方式,有三种常用的方式:

    • 时间点触发:在每个时间点上进行全局 checkpoint。
    • 流量触发:在 Flink 集群中的吞吐量达到一定阈值时进行全局 checkpoint。
    • 系统事件触发:由 Flink 系统事件触发,如检测到任务异常等。
  • savepoint.path:指定保存全局 checkpoint 的路径,如 Hdfs、Distributed Cache 等。

  1. 自定义 checkpoint 自定义 checkpoint 可以让用户指定自己想要的 checkpoint 方式。 自定义 checkpoint 有以下参数:
  • checkpoint.period.bytes:指定自定义 checkpoint 的时间间隔,单位为字节。
  • checkpoint.strategy:指定自定义 checkpoint 的触发方式,与全局 checkpoint 的触发方式相同。
  • savepoint.path:指定保存自定义 checkpoint 的路径,与全局 checkpoint 的保存路径相同。
  1. local checkpoint local checkpoint 是 Flink 集群中的一种特殊的 checkpoint,只能由任务自己触发。当任务失败时,可以通过调用 WorkerStateStore.saveLocalCheckpoint() 方法来创建 local checkpoint,任务继续执行时可以通过调用 WorkerStateStore.loadLocalCheckpoint() 方法来读取 local checkpoint。 local checkpoint 有以下参数:
  • local-dir:指定本地 checkpoint 的保存路径。 下面是一个简单的示例代码,展示了如何使用 Checkpoint 进行自定义的 Checkpoint 创建和使用:

    public class MyCheckpointExample { public static void main(String[] args) throws Exception {

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    
    env.setParallelism(1);
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    
    // 自定义 Checkpoint 创建方式
    long checkpointPeriodMs = 30000L; // checkpoint 时间间隔为 3 分钟
    String checkpointDir = "/path/to/checkpoint"; // 保存路径
    CheckpointOptions checkpointOptions = CheckpointOptions.newBuilder()
            .setCheckpointPeriodMs(checkpointPeriodMs)
            .build();
    env.setCheckpointOptions(checkpointOptions);
    
    // 创建任务并启动
    DataStream<String> stream = env
            .addSource(new FlinkKafkaConsumer<>("topic", new SimpleStringSchema(), props))
            .map(new MyMapper())
            .setCheckpointConfig(new MyCheckpointConfig())
            .setParallelism(1)
            .setMaxParallelism(1)
            .start();
    
    // 在任务失败时创建 local checkpoint
    DataStream<String> localCheckpoint = stream
            .map(new MyCheckpointMapper())
            .keyBy("id")
            .sum(1); // 只保留一条记录,用于计算自定义的 local checkpoint
    
    // 停止任务
    env.execute("STOP");
    
    // 读取 local checkpoint
    DataStream<String> finalCheckpoint = localCheckpoint
            .keyBy("id")
            .map(new MyCheckpointMapper())
            .keyBy("checkpointId")
            .sum(1);
    
    // 输出结果
    finalCheckpoint.print();
    

    }

    public static class MyMapper extends RichMapper { private MyCheckpointMapper() { // 禁止使用构造方法 } }

    public static class MyCheckpointMapper extends RichMapper { private MyCheckpointMapper() { // 禁止使用构造方法 }

    @Override
    public void open(Configuration parameters) throws Exception {
        // 读取自定义的 local checkpoint
        LocalCheckpointStateHandle handle = LocalCheckpointStateHandle.loadLocalCheckpointStateHandle(
                new Path(checkpointDir), parameters.getLong(CHECKPOINT_PERIOD_MS, 30000L));
        DataStream<String> localCheckpointStream = getRuntimeContext().getCheckpointDataManager()
                .getLocalCheckpointStream(handle);
        localCheckpointStream.print();
    }
    

    }

    public static class MyCheckpointConfig implements CheckpointOptions { private long checkpointPeriodMs;

    public MyCheckpointConfig() {
        this(30000L);
    }
    
    public MyCheckpointConfig(long checkpointPeriodMs) {
        this.checkpointPeriodMs = checkpointPeriodMs;
    }
    
    @Override
    public String getKey() {
        return "MyCheckpointConfig";
    }
    
    @Override
    public String getAlgorithm() {
        return "my-algorithm";
    }
    
    @Override
    public void write(File directory) throws IOException {
        Files.createDirectories(directory.toPath());
        Files.write(directory.toPath(), " " + checkpointPeriodMs + "ms");
    }
    
    @Override
    public CheckpointPeriod getCheckpointPeriod() {
        return CheckpointPeriod.of(checkpointPeriodMs, TimeUnit.MILLISECONDS);
    }
    

    }

    public static class MyCheckpointMeterStateHandle extends MetricUpdaterStateHandle { private MyCheckpointMeterStateHandle(String statePath) { super(statePath); }

    public static MyCheckpointMeterStateHandle of(String statePath) {
        return new MyCheckpointMeterStateHandle(statePath);
    }
    

    }

    public static class MyCheckpointMeterStateHandle extends StateHandleFetcher { private MyCheckpointMeterStateHandle(String statePath) { super(statePath); }

    public static MyCheckpointMeterStateHandle of(String statePath) {
        return new MyCheckpointMeterStateHandle(statePath);
    }
    

    }

}