@@ -26,11 +26,11 @@ under the License.
2626
2727# Flink Operator Controller 流程
2828
29- 本页面的目的是深入介绍Flink Operator的逻辑,并提供足够的控制流设计细节 ,以便新开发者能够快速上手。
29+ 本页面的目标是深入介绍 Flink Operator 算子的逻辑,并提供足够关于控制流设计的细节 ,以便新开发者能够快速上手。
3030
31- 我们将假设读者具备良好的Flink Kubernetes及不同类型集群和作业的通用操作经验。有关Flink相关的概念 ,请参阅 https://flink.apache.org/ 。
31+ 我们将假设读者具备良好的 Flink Kubernetes 及不同类型集群和作业的通用操作经验。有关 Flink 相关的概念 ,请参阅 https://flink.apache.org/ 。
3232
33- 我们还将假设读者对Flink Kubernetes Operator本身有深入的用户级理解 。
33+ 我们还将假设读者对 Flink Kubernetes Operator 本身有深入的用户级理解 。
3434
3535本文档主要关注操作机制的 *** 为什么?*** 和 *** 怎么做?*** ,而用户层面的 *** 是什么?*** 已经在其他地方有文档说明。
3636
@@ -45,9 +45,9 @@ under the License.
4545
4646## 观察阶段
4747
48- 在观察阶段,Observer模块负责观察当前 (某一时间点)已部署的Flink资源 (已提交的集群、作业)的状态,并根据这些信息更新自定义资源(CR)的状态字段。
48+ 在观察阶段,Observer 模块负责观察当前 (某一时间点)已部署的 Flink 资源 (已提交的集群、作业)的状态,并根据这些信息更新自定义资源(CR)的状态字段。
4949
50- 观察者始终使用先前部署的配置来确保可以通过REST API访问Flink集群。用户配置可能会影响REST客户端 (如端口配置等),因此我们必须始终使用集群上正在运行的配置。这就是为什么 ` FlinkConfigManager ` 和操作符在整个实现中区分观察和部署配置的主要原因。
50+ 观察者始终使用先前部署的配置来确保可以通过 REST API 访问 Flink 集群。用户配置可能会影响 REST 客户端 (如端口配置等),因此我们必须始终使用集群上正在运行的配置。这就是为什么 ` FlinkConfigManager ` 和操作符在整个实现中区分观察和部署配置的主要原因。
5151
5252观察者不应采取任何行动来更改或提交新的资源,我们将在后文看到这些操作是由协调器模块负责。这种分离的主要原因是,所需的操作不仅依赖于当前集群状态,还取决于用户在此期间可能提交的新规格变更。
5353
@@ -69,21 +69,21 @@ under the License.
6969
7070 如果无法访问作业,我们需要再次检查集群状态(参见步骤 3),或者如果在集群中找不到作业,下一步将取决于资源类型和配置,可能会触发错误或我们只需等待。当无法确定作业状态时,我们将使用 ` RECONCILING ` 状态。
71715 . 观察流程的最后一步是基于观察到的状态进行一些管理。如果一切正常且正在运行,我们将清除之前记录的资源状态错误。如果作业不再运行,我们将清除之前的保存点触发信息,以便在后续的协调阶段重新触发。
72- 6 . 在观察阶段结束时,操作员将更新的资源状态发送到 Kubernetes。这是避免在后续阶段丢失关键信息的关键步骤。一个这样的状态丢失示例:你有一个失败或完成的作业,观察者记录了最新的保存点信息。协调器可能会决定删除此集群以进行升级,但如果此时操作员失败 ,观察者将无法再次记录最后的保存点,因为它无法在已删除的集群上观察到。在执行任何集群操作之前记录状态是逻辑的关键部分。### Observing the SavepointInfo
72+ 6 . 在观察阶段结束时, Operator 将更新的资源状态发送到 Kubernetes。这是避免在后续阶段丢失关键信息的关键步骤。一个这样的状态丢失示例:你有一个失败或完成的作业,观察者记录了最新的保存点信息。协调器可能会决定删除此集群以进行升级,但如果此时 Operator 失败 ,观察者将无法再次记录最后的保存点,因为它无法在已删除的集群上观察到。在执行任何集群操作之前记录状态是逻辑的关键部分。### Observing the SavepointInfo
7373
7474### Observing the SavepointInfo
7575
7676Savepoint 信息是 JobStatus 的一部分,跟踪待处理的保存点(无论是手动还是周期性触发的保存点信息)以及根据配置的保存点历史记录。Savepoint 信息仅在观察步骤中更新运行和终端状态的作业。如果作业正在失败、重启等,这意味着保存点失败并需要重新触发。
7777
78- 我们使用 triggerId 观察待处理的保存点,如果它们已完成,则将其记录到历史记录中。如果历史记录达到配置的大小限制,我们通过正在运行的作业 REST API 处置保存点,这样无需任何用户存储凭据即可完成。如果作业未运行或不健康,我们将清除待处理的保存点触发信息,这实际上从操作员的角度中止了保存点 。
78+ 我们使用 triggerId 观察待处理的保存点,如果它们已完成,则将其记录到历史记录中。如果历史记录达到配置的大小限制,我们通过正在运行的作业 REST API 处置保存点,这样无需任何用户存储凭据即可完成。如果作业未运行或不健康,我们将清除待处理的保存点触发信息,这实际上从 Operator 的角度中止了保存点 。
7979
8080## 验证阶段
8181
8282在资源成功观察并状态更新之后,我们接下来验证传入的资源 spec 字段。
8383
8484如果新的 spec 验证失败,我们将触发一个错误事件给用户,并重置资源中上次成功提交的 spec(我们不会在 Kubernetes 中更新它,仅在本地用于协调)。
8585
86- 这一步非常重要,以确保即使用户提交了不正确的规范,协调也会运行,从而允许操作员在部署资源期间发生任何错误时恢复到之前所需的状态 。
86+ 这一步非常重要,以确保即使用户提交了不正确的规范,协调也会运行,从而允许 Operator 在部署资源期间发生任何错误时恢复到之前所需的状态 。
8787
8888## 协调阶段
8989
@@ -107,7 +107,7 @@ Savepoint 信息是 JobStatus 的一部分,跟踪待处理的保存点(无
107107
108108### 关于部署操作的注意事项
109109
110- 我们必须特别小心部署操作,因为它们会启动集群和作业,这些作业可能会立即开始生成数据和检查点。因此,能够识别部署是否成功/失败至关重要。同时,操作员进程可能会在任何时候失败 ,这使得始终记录正确状态变得困难。
110+ 我们必须特别小心部署操作,因为它们会启动集群和作业,这些作业可能会立即开始生成数据和检查点。因此,能够识别部署是否成功/失败至关重要。同时, Operator 进程可能会在任何时候失败 ,这使得始终记录正确状态变得困难。
111111
112112为了确保我们始终能够恢复部署状态以及集群上正在运行的内容,在尝试部署之前,将要部署的 spec 始终以 ` UPGRADING ` 状态写入状态。此外,向部署的 Kubernetes Deployment 资源添加注解,以便能够区分确切的部署尝试(我们使用 CR 生成版本来实现这一点)。对于会话作业,由于无法添加注解,我们使用一种特殊的方式生成包含相同信息的 jobid。
113113
@@ -125,7 +125,7 @@ Savepoint 信息是 JobStatus 的一部分,跟踪待处理的保存点(无
125125
126126#### UpgradeMode 和暂停/取消行为
127127
128- 操作员必须始终尊重升级模式设置 ,以避免有状态升级时的数据丢失。然而,机制中有一些灵活性,可以处理不健康的作业,并在版本升级期间提供额外的保护。** getAvailableUpgradeMode** 方法是升级逻辑中的一个重要基石,用于根据用户的请求和当前集群状态决定实际使用的升级模式。
128+ Operator 必须始终尊重升级模式设置 ,以避免有状态升级时的数据丢失。然而,机制中有一些灵活性,可以处理不健康的作业,并在版本升级期间提供额外的保护。** getAvailableUpgradeMode** 方法是升级逻辑中的一个重要基石,用于根据用户的请求和当前集群状态决定实际使用的升级模式。
129129
130130在正常健康的情况下,可用的升级模式将与用户在 spec 中的设置相同。然而,在某些情况下,我们需要在保存点和最后状态升级模式之间进行切换。保存点升级模式仅在作业健康且正在运行时可以使用,对于失败、重启或其他不健康的部署,只要 HA 元数据可用(且未显式配置其他方式),我们可以使用最后状态升级模式。这使我们即使在作业失败的情况下也能拥有一个稳健的升级流程,同时保持状态一致性。
131131
@@ -135,7 +135,7 @@ Savepoint 信息是 JobStatus 的一部分,跟踪待处理的保存点(无
135135
136136### 应用程序协调器
137137
138- 应用程序集群在部署/升级/取消操作期间需要处理一些比会话作业更多的额外配置步骤。以下是操作员为确保稳健行为所做的重要事情 :
138+ 应用程序集群在部署/升级/取消操作期间需要处理一些比会话作业更多的额外配置步骤。以下是 Operator 为确保稳健行为所做的重要事情 :
139139
140140** setRandomJobResultStorePath** : 为了防止终止的应用程序在 JM 故障转移时被重新启动,我们必须禁用作业结果清理。这迫使我们为每个应用程序部署创建一个随机的作业结果存储路径,如这里所述:https://issues.apache.org/jira/browse/FLINK-27569 。用户需要稍后手动清理 jobresultstore。
141141
@@ -145,17 +145,17 @@ Savepoint 信息是 JobStatus 的一部分,跟踪待处理的保存点(无
145145
146146## 自定义 Flink 资源状态更新机制
147147
148- JOSDK 提供了内置的方法来更新协调器实现中的资源 spec 和状态,但 Flink 操作员不使用这些方法 ,而是使用自定义的状态更新机制,原因如下。
148+ JOSDK 提供了内置的方法来更新协调器实现中的资源 spec 和状态,但 Flink Operator 不使用这些方法 ,而是使用自定义的状态更新机制,原因如下。
149149
150150当使用 JOSDK 时,CR 的状态只能在协调方法结束时更新。在我们的情况下,我们经常需要在协调流程中间触发状态更新,以提供最大的稳健性。一个这样的例子是在执行部署操作之前记录部署信息到状态中。
151151
152- 另一种看待方式是,Flink 操作员将资源状态用作许多操作的预写日志,以保证在操作员失败时的稳健性 。
152+ 另一种看待方式是,Flink Operator 将资源状态用作许多操作的预写日志,以保证在 Operator 失败时的稳健性 。
153153
154154状态更新机制在 ` StatusRecorder ` 类中实现,该类同时作为最新状态的缓存和更新逻辑。我们需要始终从缓存中更新我们的 CR 状态,因为在控制器流程的开头我们绕过了 JOSDK 的更新机制/缓存,这可能导致返回旧的状态实例。对于实际的状态更新,我们使用一种修改后的乐观锁定机制,只有在状态在此期间未被外部修改时才更新状态。
155155
156- 在正常情况下,这种假设成立,因为操作员是状态的唯一所有者 /更新者。这里的异常可能表明用户篡改了状态,或者另一个操作员实例正在同时管理相同的资源 ,这可能导致严重问题。
156+ 在正常情况下,这种假设成立,因为 Operator 是状态的唯一所有者 /更新者。这里的异常可能表明用户篡改了状态,或者另一个 Operator 实例正在同时管理相同的资源 ,这可能导致严重问题。
157157
158- ## JOSDK 与操作员接口命名冲突
158+ ## JOSDK 与 Operator 接口命名冲突
159159
160160在 JOSDK 世界中,Reconciler 接口代表整个控制/协调流程。在我们的情况下,我们将这些类称为控制器,并将我们自己的 Reconciler 接口保留为控制器流程的特定部分。
161161
0 commit comments