

# 检查点

> 译者：[flink.sojb.cn](https://flink.sojb.cn/)


Flink中的每个函数和 算子都可以是**有状态的**（有关详细信息，请参阅[使用state](state.html)）。有状态函数在各个数据元/事件的处理中存储数据，使状态成为任何类型的更精细 算子操作的关键构建块。

为了使状态容错，Flink需要**检查**状态。检查点允许Flink-recovery流中的状态和位置，从而为应用程序提供与无故障执行相同的语义。

[关于流容错](https://flink.sojb.cn/internals/stream_checkpointing.html)的[文档](https://flink.sojb.cn/internals/stream_checkpointing.html)详细描述了Flink的流容错机制背后的技术。

## 先决条件

Flink的检查点机制与流和状态的持久存储交互。一般来说，它需要：

*   一个_持久_（或_耐用_，可以重放记录在一定量的时间）的数据源。这些源的示例是持久消息队列（例如，Apache Kafka，RabbitMQ，Amazon Kinesis，Google PubSub）或文件系统（例如，HDFS，S3，GFS，NFS，Ceph，......）。
*   状态的持久存储，通常是分布式文件系统（例如，HDFS，S3，GFS，NFS，Ceph ......）

## 启用和配置检查点

默认情况下，禁用检查点。为了使检查点，调用`enableCheckpointing(n)`上`StreamExecutionEnvironment`，其中 _N_ 是以毫秒为单位的检查点间隔。

检查点的其他参数包括：

*   _完全一次与至少一次_：您可以选择将模式传递给`enableCheckpointing(n)`方法，以在两个保证级别之间进行选择。对于大多数应用来说，恰好一次是优选的。至少一次可能与某些超低延迟（始终为几毫秒）的应用程序相关。

*   _checkpoint timeout（检查点超时）_：如果当前检查点未完成，则中止检查点的时间。

*   _检查点之间的最短时间_：为确保流应用程序在检查点之间取得一定进展，可以定义检查点之间需要经过多长时间。如果将此值设置为例如_5000_，则无论检查点持续时间和检查点间隔如何，下一个检查点将在上一个检查点完成后的5秒内启动。请注意，这意味着检查点间隔永远不会小于此参数。

    通过定义“检查点之间的时间”而不是检查点间隔来配置应用程序通常更容易，因为“检查点之间的时间”不易受检查点有时需要比平均时间更长的事实的影响（例如，如果目标存储系统暂时很慢）。

    请注意，此值还表示并发检查点的数量为_一_。

*   _并发检查点数_：默认情况下，当一个检查点仍处于运行状态时，系统不会触发另一个检查点。这可确保拓扑不会在检查点上花费太多时间，也不会在处理流方面取得进展。可以允许多个重叠检查点，这对于具有特定处理延迟的管道（例如，因为函数调用需要一些时间来响应的外部服务）而感兴趣，但是仍然希望执行非常频繁的检查点（100毫秒） ）在失败时重新处理很少。

    当定义检查点之间的最短时间时，不能使用此选项。

*   _外部化检查点_：您可以将_外围检查点_配置为外部持久化。外部化检查点将其元数据写入持久存储，并且在作业失败时_不会_自动清除。这样，如果您的工作失败，您将有一个检查点可以从中-recovery。[有关外部化检查点](https://flink.sojb.cn/ops/state/checkpoints.html#externalized-checkpoints)的[部署说明中](https://flink.sojb.cn/ops/state/checkpoints.html#externalized-checkpoints)有更多详细信息。

*   _关于检查点错误的失败/继续任务_：这确定如果在执行任务的检查点过程中发生错误，任务是否将失败。这是默认行为。或者，当禁用此选项时，任务将简单地拒绝检查点协调器的检查点并继续运行。

*   [**Java**](#tab_java_0)
*   [**Scala**](#tab_scala_0)



```
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

// start a checkpoint every 1000 ms
env.enableCheckpointing(1000);

// advanced options:

// set mode to exactly-once (this is the default)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);

// make sure 500 ms of progress happen between checkpoints
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);

// checkpoints have to complete within one minute, or are discarded
env.getCheckpointConfig().setCheckpointTimeout(60000);

// allow only one checkpoint to be in progress at the same time
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);

// enable externalized checkpoints which are retained after job cancellation
env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
```





```
val env = StreamExecutionEnvironment.getExecutionEnvironment()

// start a checkpoint every 1000 ms env.enableCheckpointing(1000)

// advanced options: 
// set mode to exactly-once (this is the default) env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)

// make sure 500 ms of progress happen between checkpoints env.getCheckpointConfig.setMinPauseBetweenCheckpoints(500)

// checkpoints have to complete within one minute, or are discarded env.getCheckpointConfig.setCheckpointTimeout(60000)

// prevent the tasks from failing if an error happens in their checkpointing, the checkpoint will just be declined. env.getCheckpointConfig.setFailTasksOnCheckpointingErrors(false)

// allow only one checkpoint to be in progress at the same time env.getCheckpointConfig.setMaxConcurrentCheckpoints(1)
```



### 相关的配置选项

可以通过设置更多参数和/或默认值`conf/flink-conf.yaml`（参见完整指南的[配置](https://flink.sojb.cn/ops/config.html)）：


---

键：`state.backend`

默认值：`(none)`

描述：状态后台用于存储和检查点状态。

---

键：`state.backend.async`

默认值：`true`

描述：选择状态后台是否应在可能和可配置的情况下使用异步SNAPSHOT方法。某些状态后台可能不支持异步SNAPSHOT，或者仅支持异步SNAPSHOT，并忽略此选项。

---

键：`state.backend.fs.memory-threshold`

默认值：`1024`

描述：状态数据文件的最小大小。小于该值的所有状态块都内联存储在根检查点元数据文件中。

---

键：`state.backend.incremental`

默认值：`false`

描述：如果可能，选择状态后台是否应创建增量检查点。对于增量检查点，仅存储来自先前检查点的差异，而不是完整的检查点状态。某些状态后台可能不支持增量检查点并忽略此选项。

---

键：`state.backend.local-recovery`

默认值：`false`

描述：无

---

键：`state.checkpoints.dir`

默认值：`(none)`

描述：用于在Flink支持的文件系统中存储检查点的数据文件和元数据的默认目录。必须可以从所有参与的进程/节点（即所有TaskManagers和JobManagers）访问存储路径。

---

键：`state.checkpoints.num-retained`

默认值：`1`

描述：要retained的已完成检查点的最大数量。

---

键：`state.savepoints.dir`

默认值：`(none)`

描述：保存点的默认目录。由将后台写入文件系统的状态后台（MemoryStateBackend，FsStateBackend，RocksDBStateBackend）使用。

---

键：`taskmanager.state.local.root - dirs`

默认值：`(none)`

描述：无

## 选择状态后台

Flink的[检查点机制](https://flink.sojb.cn/internals/stream_checkpointing.html)存储定时器和有状态算子中所有状态的一致SNAPSHOT，包括连接器，窗口和任何[用户定义的状态](state.html)。存储检查点的位置（例如，JobManager内存，文件系统，数据库）取决于配置的 **状态后台**。

默认情况下，状态保存在TaskManagers的内存中，检查点存储在JobManager的内存中。为了适当持久化大状态，Flink支持在其他状态后台中存储和检查点状态的各种方法。可以通过配置状态后台的选择`StreamExecutionEnvironment.setStateBackend(…)`。

有关可用状态后台的详细信息以及作业范围和群集范围配置的选项，请参阅[状态后台](https://flink.sojb.cn/ops/state/state_backends.html)。

## 迭代作业中的状态检查点

Flink目前仅为没有迭代的作业提供处理保证。在迭代作业上启用检查点会导致异常。为了强制对迭代程序进行检查点，用户在启用检查点时需要设置一个特殊标志：`env.enableCheckpointing(interval, force = true)`。

请注意，在失败期间，循环边缘中的记录（以及与它们相关的状态变化）将丢失。

## 重启策略

Flink支持不同的重启策略，可以控制在发生故障时如何重新启动作业。欲了解更多信息，请[重新启动策略](https://flink.sojb.cn/dev/restart_strategies.html)。

