

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 執行期疑難排解
<a name="troubleshooting-runtime"></a>

本節包含診斷和修正 Managed Service for Apache Flink 應用程式執行期問題的相關資訊。

**Topics**
+ [故障診斷工具](#troubleshooting-tools)
+ [應用程式問題](troubleshooting-symptoms.md)
+ [應用程式正在重新啟動](troubleshooting-rt-restarts.md)
+ [輸送量太慢](troubleshooting-rt-throughput.md)
+ [無限制狀態成長](troubleshooting-rt-stateleaks.md)
+ [I/O 綁定運算子](troubleshooting-io-bound-operators.md)
+ [Kinesis 資料串流的上游或來源限流](troubleshooting-source-throttling.md)
+ [檢查點](troubleshooting-checkpoints.md)
+ [檢查點逾時](troubleshooting-chk-timeout.md)
+ [Apache Beam 應用程式檢查點失敗](troubleshooting-chk-failure-beam.md)
+ [背壓](troubleshooting-backpressure.md)
+ [資料扭曲](troubleshooting-data-skew.md)
+ [狀態扭曲](troubleshooting-state-skew.md)
+ [與不同區域中的資源整合](troubleshooting-resources-in-different-regions.md)

## 故障診斷工具
<a name="troubleshooting-tools"></a>

偵測應用程式問題的主要工具是 CloudWatch 警示。您可以使用 CloudWatch 警示設定 CloudWatch 指標的閾值，以指出應用程式中的錯誤或瓶頸狀況。如需建議的 CloudWatch 警示的相關資訊，請參閱[搭配 Amazon Managed Service for Apache Flink 使用 CloudWatch 警示](monitoring-metrics-alarms.md)。

# 應用程式問題
<a name="troubleshooting-symptoms"></a>

本節包含針對 Managed Service for Apache Flink 應用程式可能會遇到的錯誤情況的解決方案。

**Topics**
+ [應用程式卡在暫時狀態](#troubleshooting-rt-stuck)
+ [快照建立失敗](#troubleshooting-rt-snapshots)
+ [無法存取 VPC 中的資源](#troubleshooting-rt-vpc)
+ [寫入 Amazon S3 儲存貯體時遺失資料](#troubleshooting-rt-s3)
+ [應用程式處於執行中狀態，但未處理資料](#troubleshooting-rt-processing)
+ [快照、應用程式更新或應用程式停止錯誤： InvalidApplicationConfigurationException](#troubleshooting-rt-appconfigexception)
+ [java.nio.file.NoSuchFileException: /usr/local/openjdk-8/lib/security/cacerts](#troubleshooting-rt-fnf)

## 應用程式卡在暫時狀態
<a name="troubleshooting-rt-stuck"></a>

如果應用程式已保持暫時狀態 (`STARTING`、`UPDATING`、`STOPPING` 或 `AUTOSCALING`) 一段時間，您可以使用 [StopApplication](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_StopApplication.html) 動作停止應用程式，並將 `Force` 參數設定為 `true`。您無法強制停止 `DELETING` 狀態的應用程式。或者，如果應用程式處於 `UPDATING` 或 `AUTOSCALING` 狀態，您可以將其復原至先前執行的版本。復原應用程式時，它會從上次成功的快照載入狀態資料。如果應用程式沒有快照，Managed Service for Apache Flink 會拒絕復原請求。如需復原應用程式的詳細資訊，請參閱 [RollbackApplication](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_RollbackApplication.html) 動作。

**注意**  
強制停止應用程式可能會導致資料遺失或重複。為了防止應用程式重新啟動期間資料遺失或重複處理資料，我們建議您經常拍攝應用程式的快照。

應用程式卡住的原因如下：
+ **應用程式狀態太大：**應用程式狀態太大或過於持續，可能會導致應用程式在檢查點或快照操作期間卡住。檢查應用程式 `lastCheckpointDuration` 和 `lastCheckpointSize` 指標的值是否在穩定增加或異常高。
+ **應用程式的程式碼太大：**確認您的應用程式 JAR 檔案小於 512 MB。不支援大於 512 MB 的 JAR 檔案。
+ **應用程式快照建立失敗：**Managed Service for Apache Flink 會在 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_UpdateApplication.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_UpdateApplication.html) 或 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_StopApplication.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_StopApplication.html) 請求期間擷取應用程式的快照。然後，服務會使用此快照狀態，並使用更新的應用程式組態還原應用程式，以提供*恰好一次*的處理語義。如果自動建立快照失敗，請參閱下文的[快照建立失敗](#troubleshooting-rt-snapshots)。
+ **從快照還原失敗：**如果您移除或變更應用程式更新中的運算子，並嘗試從快照還原，則如果快照包含遺失運算子的狀態資料，還原預設將會失敗。此外，應用程式將卡在 `STOPPED` 或 `UPDATING` 狀態。若要變更此行為並讓還原成功，請將應用程式 [FlinkRunConfiguration](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_FlinkRunConfiguration.html) 的 *AllowNonRestoredState* 參數變更為 `true`。這將允許恢復操作跳過無法對應至新程式的狀態資料。
+ **應用程式初始化所花費的時間較長：**Managed Service for Apache Flink 在等待 Flink 作業啟動時，會使用 5 分鐘的內部逾時 (軟體設定)。如果作業無法在此逾時內啟動，您將會看到如下所示的 CloudWatch 日誌：

  ```
  Flink job did not start within a total timeout of 5 minutes for application: %s under account: %s
  ```

   如果遇到上述錯誤，表示在 Flink 作業 `main` 方法下定義的操作需要 5 分鐘以上的時間，從而導致建立 Flink 作業的操作在 Managed Service for Apache Flink 結束時逾時。我們建議您檢查 Flink **JobManager** 日誌以及應用程式的程式碼，查看 `main` 方法中是否預期存在此延遲。如果沒有，則需要採取措施來解決該問題，以便在 5 分鐘內完成。

您可以使用 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_ListApplications.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_ListApplications.html) 或 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_DescribeApplication.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_DescribeApplication.html) 動作來檢查應用程式狀態。

## 快照建立失敗
<a name="troubleshooting-rt-snapshots"></a>

在下列情況下，Managed Service for Apache Flink 服務無法拍攝快照：
+ 應用程式超過快照限制。快照的限制為 1,000。如需詳細資訊，請參閱[使用快照管理應用程式備份](how-snapshots.md)。
+ 應用程式沒有存取其來源或接收器的許可。
+ 應用程式的程式碼無法正常運作。
+ 應用程式遇到其他組態問題。

在應用程式更新期間或停止應用程式時，如果擷取快照時發生例外狀況，請將應用程式 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_ApplicationSnapshotConfiguration.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_ApplicationSnapshotConfiguration.html) 的 `SnapshotsEnabled` 屬性設定為 `false`，然後重試該請求。

如果應用程式的運算子未正確佈建，快照可能會失敗。如需調整運算子效能的相關資訊，請參閱[運算子擴展](performance-improving.md#performance-improving-scaling-op)。

應用程式回到正常狀態之後，建議您將應用程式的 `SnapshotsEnabled` 屬性設定為 `true`。

## 無法存取 VPC 中的資源
<a name="troubleshooting-rt-vpc"></a>

如果應用程式使用在 Amazon VPC 上執行的 VPC，請執行以下操作以確認應用程式是否可以存取其資源：
+ 檢查 CloudWatch 日誌中是否有下列錯誤。此錯誤表示應用程式無法存取 VPC 中的資源：

  ```
  org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.
  ```

  如果您看到此錯誤，請確認您的路由表設定正確，並且連接器具有正確的連線設定。

  如需設定和分析 CloudWatch 日誌的相關資訊，請參閱[在 Amazon Managed Service for Apache Flink 中記錄和監控](monitoring-overview.md)。

## 寫入 Amazon S3 儲存貯體時遺失資料
<a name="troubleshooting-rt-s3"></a>

使用 Apache Flink 1.6.2 版將輸出寫入 Amazon S3 儲存貯體時，可能會發生一些資料遺失。我們建議您在直接使用 Amazon S3 進行輸出時，使用 Apache Flink 最新支援版本。若要使用 Apache Flink 1.6.2 寫入 Amazon S3 儲存貯體，建議使用 Firehose。如需搭配使用 Firehose 與 Managed Service for Apache Flink 的詳細資訊，請參閱 [Firehose 接收器](earlier.md#get-started-exercise-fh)。

## 應用程式處於執行中狀態，但未處理資料
<a name="troubleshooting-rt-processing"></a>

您可以使用 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_ListApplications.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_ListApplications.html) 或 [https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_DescribeApplication.html](https://docs.aws.amazon.com/managed-service-for-apache-flink/latest/apiv2/API_DescribeApplication.html) 動作來檢查應用程式狀態。如果應用程式進入 `RUNNING` 狀態，但未在將資料寫入接收器，您可以透過將 Amazon CloudWatch 日誌串流新增至應用程式來解決該問題。如需詳細資訊，請參閱[使用應用程式 CloudWatch 記錄選項](cloudwatch-logs.md#adding_cloudwatch)。日誌串流包含可用於對應用程式問題進行疑難排解的訊息。

## 快照、應用程式更新或應用程式停止錯誤： InvalidApplicationConfigurationException
<a name="troubleshooting-rt-appconfigexception"></a>

在快照操作期間或在建立快照的操作 (例如更新或停止應用程式) 期間，可能會發生如下錯誤：

```
An error occurred (InvalidApplicationConfigurationException) when calling the UpdateApplication operation: 

Failed to take snapshot for the application xxxx at this moment. The application is currently experiencing downtime. 
Please check the application's CloudWatch metrics or CloudWatch logs for any possible errors and retry the request. 
You can also retry the request after disabling the snapshots in the Managed Service for Apache Flink console or by updating 
the ApplicationSnapshotConfiguration through the AWS SDK
```

應用程式無法建立快照時，會發生此錯誤。

如果在快照操作或建立快照的操作期間遇到此錯誤，請執行下列動作：
+ 為應用程式停用快照。您可以在 Managed Service for Apache Flink 主控台中執行此操作，也可以使用 [UpdateApplication](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_UpdateApplication.html) 動作的 `SnapshotsEnabledUpdate` 參數。
+ 調查無法建立快照的原因。如需詳細資訊，請參閱[應用程式卡在暫時狀態](#troubleshooting-rt-stuck)。
+ 當應用程式恢復正常狀態時，再重新啟用快照。

## java.nio.file.NoSuchFileException: /usr/local/openjdk-8/lib/security/cacerts
<a name="troubleshooting-rt-fnf"></a>

SSL 信任存放區的位置已在先前的部署中更新。為 `ssl.truststore.location` 參數改用下列值：

```
/usr/lib/jvm/java-11-amazon-corretto/lib/security/cacerts
```

# 應用程式正在重新啟動
<a name="troubleshooting-rt-restarts"></a>

如果您的應用程式運作狀況不正常，其 Apache Flink 作業就會持續失敗並重新啟動。本節說明此狀況的徵狀和疑難排解步驟。

## 徵狀
<a name="troubleshooting-rt-restarts-symptoms"></a>

這種情況可能有下列徵狀：
+ `FullRestarts` 指標不為零。此指標代表自您啟動應用程式後，應用程式作業已重新啟動的次數。
+ `Downtime` 指標不為零。此指標代表應用程式處於 `FAILING` 或 `RESTARTING` 狀態的毫秒數。
+ 應用程式日誌包含狀態變更 (變更為 `RESTARTING` 或 `FAILED`)。您可以使用下列 CloudWatch Logs Insights 查詢，來查詢您的應用程式日誌中是否有這些狀態變更：[分析錯誤：應用程式任務相關的失敗](cloudwatch-logs-reading.md#cloudwatch-logs-reading-apps)。

## 原因和解決方案
<a name="troubleshooting-rt-restarts-causes"></a>

下列情況可能會導致您的應用程式變得不穩定並重複重新啟動：
+ **運算子擲回例外狀況：**如果應用程式中運算子中的任何例外狀況未處理，應用程式會容錯移轉 （透過解譯運算子無法處理失敗）。應用程式會從最新的檢查點重新啟動，以維護「恰好一次」的處理語義。因此，`Downtime` 在這些重新啟動期間不為零。為了防止這種情況發生，我們建議您處理應用程式程式碼中的任何可重試的例外狀況。

  您可以查詢應用程式日誌中是否包含從 `RUNNING` 到 `FAILED` 的應用程式狀態變更，以調查此情況的原因。如需詳細資訊，請參閱[分析錯誤：應用程式任務相關的失敗](cloudwatch-logs-reading.md#cloudwatch-logs-reading-apps)。
+ **未正確佈建 Kinesis 資料串流：**如果您應用程式的來源或目的地是 Kinesis 資料串流，請檢查串流的[指標](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html)是否有 `ReadProvisionedThroughputExceeded`或 `WriteProvisionedThroughputExceeded`錯誤。

  如果看到這些錯誤，您可以增加串流的碎片數目，以增加 Kinesis 串流的可用輸送量。如需詳細資訊，請參閱[如何變更 Kinesis Data Streams 中的開放碎片數目？](https://aws.amazon.com/premiumsupport/knowledge-center/kinesis-data-streams-open-shards/)
+ **其他來源或接收器未正確佈建或不可用：**確認應用程式是否正確佈建來源和接收器。檢查應用程式中使用的任何來源或接收器 （例如 AWS 其他服務，或外部來源或目的地） 是否已妥善佈建、未遇到讀取或寫入限流，或是否定期無法使用。

  如果您遇到相依服務的輸送量相關問題，請增加這些服務的可用資源，或調查任何錯誤或無法使用的原因。
+ **運算子未正確佈建：**如果應用程式中其中一個運算子的執行緒上的工作負載未正確分配，則該運算子可能會超載，而應用程式可能會損毀。如需調整運算子平行處理的相關資訊，請參閱[適當管理運算子擴展](performance-improving.md#performance-improving-scaling-op)。
+ **應用程式失敗，出現 DaemonException：**如果您使用的是 1.11 之前的 Apache Flink 版本，此錯誤會出現在應用程式日誌中。您可能需要升級至更新版本的 Apache Flink，以便使用 0.14 或更新版本的 KPL。
+ **應用程式失敗，出現 TimeoutException、FlinkException 或 RemoteTransportException：**如果任務管理員損毀，這些錯誤可能會出現在應用程式日誌中。如果應用程式超載，任務管理員可能會遇到 CPU 或記憶體資源壓力，導致它們失敗。

  這些錯誤可能如下所示：
  + `java.util.concurrent.TimeoutException: The heartbeat of JobManager with id xxx timed out`
  + `org.apache.flink.util.FlinkException: The assigned slot xxx was removed`
  + `org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException: Connection unexpectedly closed by remote task manager`

  若要疑難排解此狀況，請檢查下列各項：
  + 檢查 CloudWatch 指標以了解 CPU 或記憶體用量是否出現異常尖峰。
  + 檢查應用程式以了解是否有輸送量問題。如需詳細資訊，請參閱[對效能問題進行故障診斷](performance-troubleshooting.md)。
  + 檢查應用程式日誌以了解是否有應用程式程式碼所引發的未處理例外狀況。
+ **應用程式失敗，出現「找不到 JaxbAnnotationModule」錯誤：**如果應用程式使用 Apache Beam，但沒有正確的相依性或相依性版本，則會發生此錯誤。使用 Apache Beam 的 Managed Service for Apache Flink 應用程式必須使用以下版本的相依性：

  ```
  <jackson.version>2.10.2</jackson.version>
  ...
  <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-jaxb-annotations</artifactId>
      <version>2.10.2</version>
  </dependency>
  ```

  如果您未提供正確的 `jackson-module-jaxb-annotations` 版本作為明確的相依性，應用程式會從環境相依性載入該版本，而由於版本不相符，應用程式會在執行期損毀。

  如需將 Apache Beam 與 Managed Service for Apache Flink 搭配使用的詳細資訊，請參閱[使用 CloudFormation使用 Apache Beam 建立應用程式](examples-beam.md)。
+ **應用程式失敗，並顯示 java.io.IOException：網路緩衝區數目不足**

  當應用程式為網路緩衝區配置的記憶體不足時，就會發生這種情況。網路緩衝區可協助子任務之間的通信。它們用於在透過網路傳輸之前存儲記錄，並在將其解析為記錄並移交給子任務之前存儲傳入的資料。所需的網路緩衝區數目可直接根據作業圖表的平行處理層級和複雜度擴展。有許多方法可以緩解此問題：
  + 您可以設定較低的 `parallelismPerKpu`，以便為每個子任務和網路緩衝區配置更多記憶體。請注意，降低 `parallelismPerKpu` 會增加 KPU，因此會增加成本。為了避免這種情況，您可以按相同係數降低平行處理層級來保持相同數量的 KPU。
  + 您可以減少運算子的數目或將它們鏈結起來，以減少所需的緩衝區來簡化作業圖表。
  + 否則，您可以聯絡 https://aws.amazon.com/premiumsupport/ 進行自訂網路緩衝區組態。

# 輸送量太慢
<a name="troubleshooting-rt-throughput"></a>

如果應用程式處理傳入的串流資料速度不夠快，它會效能不佳且變得不穩定。本節說明此狀況的徵狀和疑難排解步驟。

## 徵狀
<a name="troubleshooting-rt-throughput-symptoms"></a>

這種情況可能有下列徵狀：
+ 如果應用程式的資料來源是 Kinesis 串流，則串流的 `millisbehindLatest` 指標會持續增加。
+ 如果應用程式的資料來源是 Amazon MSK 叢集，則叢集的取用者延遲指標會持續增加。如需詳細資訊，請參閱 [Amazon MSK 開發人員指南](https://docs.aws.amazon.com/msk/latest/developerguide/what-is-msk.html)中的[取用者延遲監控](https://docs.aws.amazon.com/msk/latest/developerguide/consumer-lag.html)。
+ 如果應用程式的資料來源是其他服務或來源，請檢查任何可用的取用者延遲指標或可用資料。

## 原因和解決方案
<a name="troubleshooting-rt-throughput-causes"></a>

造成應用程式輸送量緩慢的原因可能有很多。如果應用程式未與輸入保持一致，請檢查以下內容：
+ 如果輸送量延遲急劇增加，然後逐漸減少，請檢查應用程式是否正在重新啟動。應用程式在重新啟動時會停止處理輸入，進而造成延遲急劇增加。如需應用程式故障的相關資訊，請參閱[應用程式正在重新啟動](troubleshooting-rt-restarts.md)。
+ 如果輸送量延遲一致，請檢查應用程式是否已進行效能最佳化。如需最佳化應用程式效能的相關資訊，請參閱[對效能問題進行故障診斷](performance-troubleshooting.md)。
+ 如果輸送量延遲未急劇增加，而是持續增加，並且應用程式已進行效能最佳化，則必須增加應用程式資源。如需增加應用程式資源的相關資訊，請參閱[實作應用程式擴展](how-scaling.md)。
+ 如果應用程式從不同區域的 Kafka 叢集讀取，並且儘管取用者延遲很高，`FlinkKafkaConsumer` 或 `KafkaSource` 大多是閒置狀態 (高 `idleTimeMsPerSecond` 或低 `CPUUtilization`)，則可以增加 `receive.buffer.byte` 的值，例如 2097152。如需詳細資訊，請參閱[自訂 MSK 組態](https://docs.aws.amazon.com/msk/latest/developerguide/msk-configuration-properties.html)中的「高延遲環境」一節。

如需應用程式來源中輸送量緩慢或取用者延遲增加的疑難排解步驟，請參閱[對效能問題進行故障診斷](performance-troubleshooting.md)。

# 無限制狀態成長
<a name="troubleshooting-rt-stateleaks"></a>

如果應用程式未正確處置過期的狀態資訊，這些資訊會持續累積並導致應用程式效能或穩定性問題。本節說明此狀況的徵狀和疑難排解步驟。

## 徵狀
<a name="troubleshooting-rt-stateleaks-symptoms"></a>

這種情況可能有下列徵狀：
+ `lastCheckpointDuration` 指標正在逐漸增加或急劇增加。
+ `lastCheckpointSize` 指標正在逐漸增加或急劇增加。

## 原因和解決方案
<a name="troubleshooting-rt-stateleaks-causes"></a>

下列情況可能會導致應用程式累積狀態資料：
+ 應用程式保留狀態資料的時間超過需要的時間。
+ 應用程式使用持續時間過長的視窗查詢。
+ 您尚未為狀態資料設定 TTL。如需詳細資訊，請參閱 Apache Flink 文件中的[狀態Time-To-Live(TTL)](https://nightlies.apache.org/flink/flink-docs-release-1.18/docs/dev/datastream/fault-tolerance/state/#state-time-to-live-ttl)。
+ 您正在執行的應用程式相依於 Apache Beam 2.25.0 版或更高版本。您可以透過用關鍵實驗和 `use_deprecated_read` 值[擴充 BeamApplicationProperties](https://docs.aws.amazon.com/managed-flink/latest/java/examples-beam.html#examples-beam-configure)，選擇退出讀取轉換的新版本。如需詳細資訊，請參閱 [Apache Beam 文件](https://beam.apache.org/blog/beam-2.25.0/#highlights)。

應用程式有時會面臨持續擴增的狀態大小增長，從長遠來看，這是不可持續的 (畢竟 Flink 應用程式會無限期地執行)。有時，這可以追溯至存儲狀態資料且未正確地老化舊資訊的應用程式。但是有時候，使用者對 Flink 可以提供的東西抱有根本不合理的期望。應用程式可以在跨越數天甚至數週的長時段內使用彙總。除非使用允許增量彙總的 [AggregateFunctions](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/windows/#aggregatefunction)，否則 Flink 需要將整個視窗的事件保持在狀態。

此外，當使用進程函數來實作自訂運算子時，應用程式需要從業務邏輯不再需要的狀態中移除資料。在這種情況下，[狀態存活期](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/fault-tolerance/state/#state-time-to-live-ttl)可用於根據處理時間自動老化資料。Managed Service for Apache Flink 正在使用增量檢查點，因此狀態 TTL 基於 [RocksDB 壓縮](https://github.com/facebook/rocksdb/wiki/Compaction)。在壓縮操作發生之後，您只能觀察到狀態大小的實際縮減 (由檢查點大小表示)。特別是對於低於 200 MB 的檢查點大小，由於狀態到期，您不太可能觀察到任何檢查點大小縮小。儲存點則基於不包含舊資料之狀態的全新副本，因此您可以在 Managed Service for Apache Flink 中觸發快照，以強制移除過期狀態。

出於偵錯目的，停用增量檢查點以更快速地驗證檢查點大小是否確實減小或穩定 (並避免 RocksBS 壓縮的影響) 是可行的。但是，這需要提交票證給服務團隊。

# I/O 綁定運算子
<a name="troubleshooting-io-bound-operators"></a>

最好避免對資料路徑上外部系統的相依性。將參考資料集保持在狀態中，而不是查詢外部系統以富集個別事件，通常效能要高很多。不過，有時候有些相依性無法輕易移至狀態，例如，如果您想要使用 Amazon Sagemaker 上託管的機器學習模型來富集事件。

透過網絡與外部系統進行互動的運算子可能會成為瓶頸並導致背壓。強烈建議使用 [AsyncIO](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/asyncio/) 來實作該功能，以減少單個呼叫的等待時間並避免整個應用程式變慢。

此外，對於具有 I/O 綁定運算子的應用程式，也可以增加 Apache Flink 應用程式的 [ParallelismPerKPU](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_ParallelismConfiguration.html) 設定。此設定描述應用程式每 Kinesis 處理單元 (KPU) 可執行的平行子任務數目。藉由將值從預設值 1 增加到 4，應用程式利用相同的資源 (以相同的成本)，但可擴展至 4 倍的平行處理層級。這非常適用於 I/O 綁定的應用程式，但會給不是 I/O 綁定的應用程式造成額外開銷。

# Kinesis 資料串流的上游或來源限流
<a name="troubleshooting-source-throttling"></a>

**徵狀**：應用程式遇到來自其上游來源 Kinesis 資料串流的 `LimitExceededExceptions`。

**潛在原因**：Apache Flink 程式庫 Kinesis 連接器的預設設定設定為從 Kinesis 資料串流來源讀取，且每次 `GetRecords` 呼叫擷取的最大記錄數目具有非常積極的預設設定。Apache Flink 預設設定為每次`GetRecords`呼叫擷取 10，000 個記錄 （此呼叫預設為每 200 毫秒），但每個碎片的限制只有 1，000 個記錄。

嘗試從 Kinesis 資料串流取用時，此預設行為可能會導致限流，從而影響應用程式的效能和穩定性。

您可以透過檢查 CloudWatch `ReadProvisionedThroughputExceeded` 指標並查看此指標大於零的延長或持續期間來確認這一點。

您也可以透過觀察持續的`LimitExceededException`錯誤，在 Amazon Managed Service for Apache Flink 應用程式的 CloudWatch 日誌中看到此情況。

**解決**方法：您可以執行下列兩項操作之一來解決這種情況：
+ 降低每次`GetRecords`呼叫擷取的記錄數量的預設限制
+ 在 Amazon Managed Service for Apache Flink 應用程式中啟用自適應讀取。如需適性讀取功能的詳細資訊，請參閱 [SHARD\$1USE\$1ADAPTIVE\$1READS](https://nightlies.apache.org/flink/flink-docs-release-1.10/api/java/org/apache/flink/streaming/connectors/kinesis/config/ConsumerConfigConstants.html#SHARD_USE_ADAPTIVE_READS)

# 檢查點
<a name="troubleshooting-checkpoints"></a>

檢查點是 Flink 用於確保應用程式狀態具有容錯能力的機制。該機制允許 Flink 在作業失敗時恢復運算子的狀態，並為應用程式提供與無故障執行相同的語義。使用 Managed Service for Apache Flink，應用程式的狀態會儲存在 RocksDB 中，這是一個內嵌式索引鍵/值存放區，可將其工作狀態保留在磁碟上。取得檢查點時，狀態也會上傳至 Amazon S3，這樣即使磁碟遺失，也可以使用檢查點來還原應用程式狀態。

如需詳細資訊，請參閱[狀態快照如何運作](https://nightlies.apache.org/flink/flink-docs-master/docs/learn-flink/fault_tolerance/#how-does-state-snapshotting-work)。

## 檢查點階段
<a name="troubleshooting-checkpointing-stages"></a>

對於 Flink 中的檢查點運算子子任務，有 5 個主要階段：
+ 等待 [**開始延遲**]：Flink 使用插入串流的檢查點障礙，因此在此階段的時間是運算子等待檢查點障礙到達它的時間。
+ 對齊 [**對齊持續時間**]：在此階段，子任務已到達一個障礙，但它正在等待來自其他輸入串流的障礙。
+ 同步檢查點 [**同步持續時間**]：在此階段，子任務會實際拍攝運算子狀態快照，並阻止該子任務上的所有其他活動。
+ 非同步檢查點 [**非同步持續時間**]：此階段的主要操作是子任務將狀態上傳到 Amazon S3。在此階段，子任務不再被阻止，可以處理記錄。
+ 確認：這通常是一個短暫的階段，只是子任務發送確認給 JobManager 並執行任何遞交訊息 (例如，使用 Kafka 接收器)。

 上述每個階段 (除了「確認」) 都對應到 Flink WebUI 中可用檢查點的持續時間指標，這可以幫助隔離長檢查點的原因。

要查看檢查點上每個可用指標的確切定義，請轉到[歷史記錄](https://nightlies.apache.org/flink/flink-docs-release-1.13/docs/ops/monitoring/checkpoint_monitoring/#history-tab)標籤。

## 調查
<a name="troubleshooting-checkpoints-investigating"></a>

調查長檢查點的持續時間時，最重要的是要確定檢查點的瓶頸，也就是說，什麼運算子和子任務正在採用最長檢查點，該子任務的哪個階段正在花費較長的時間。這可以使用作業檢查點任務下的 Flink WebUI 來確定。Flink 的 Web 介面提供了可協助調查檢查點問題的資料和資訊。如需完整明細，請參閱[監控檢查點](https://nightlies.apache.org/flink/flink-docs-release-1.13/docs/ops/monitoring/checkpoint_monitoring/)。

 首先要注意的是作業圖表中每個運算子的**端對端持續時間**，以確定哪個運算子需要較長時間才能到達檢查點，需要進一步調查。根據 Flink 文件，持續時間的定義如下：

*從觸發時間戳記到最近確認為止的持續時間 (如果尚未收到確認，則為 n/a)。完整檢查點的端對端持續時間由確認檢查點的最後一個子任務決定。此時間通常大於單個子任務對狀態實際執行檢查點需要的時間。*

檢查點的其他持續時間還提供了有關花費時間的更精細資訊。

如果**同步持續時間**很高，則表示快照過程中發生了問題。在這個階段，為實作 snapshotState 介面的類別呼叫 `snapshotState()`；這可以是使用者程式碼，所以執行緒傾印對於調查這一點會有幫助。

**非同步持續時間**長表明將狀態上傳到 Amazon S3 花費了大量時間。如果狀態很大，或者有許多狀態檔案正在上傳，就會發生這種情況。如果是這種情況，則值得調查應用程式如何使用狀態，並確保在可能的情況下使用 Flink 本機資料結構 ([使用具有索引鍵的狀態](https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/fault-tolerance/state/#using-keyed-state))。Managed Service for Apache Flink 會以最小化 Amazon S3 呼叫數目的方式來設定 Flink，以確保不會變得太長。下面是某個運算子的檢查點統計資料範例。它表明，與之前的運算子檢查點統計資料相比，此運算子的**非同步持續時間**相對較長。

![\[調查檢查點\]](http://docs.aws.amazon.com/zh_tw/managed-flink/latest/java/images/checkpoint.png)


**開始延遲**高將表明等待檢查點障礙到達運算子花費了大部分時間。這表明應用程式正在花時間處理記錄，意味著障礙正在緩慢流經作業圖表。如果作業受到背壓或運算子經常處於忙碌狀態，通常就會發生這種情況。以下是作業圖表範例，其中第二個 KeyedProcess 運算子處於忙碌狀態。

![\[調查檢查點\]](http://docs.aws.amazon.com/zh_tw/managed-flink/latest/java/images/checkpoint2.png)


您可以使用 Flink 火焰圖或 TaskManager 執行緒傾印來調查是什麼需要這麼長時間。一旦確定了瓶頸，就可以使用火焰圖或執行緒傾印進一步調查。

## 執行緒傾印
<a name="troubleshooting-checkpoints-investigating-thread-dumps"></a>

執行緒傾印是比火焰圖層級略低的另一種偵錯工具。執行緒傾印會在某個時間點輸出所有執行緒的執行狀態。Flink 接受 JVM 執行緒傾印，這是 Flink 處理序中所有執行緒的執行狀態。執行緒狀態由執行緒的堆疊追蹤以及一些附加資訊來表示。火焰圖實際上是使用快速連續採取的多個堆疊追蹤所建置。該圖形是由這些追蹤構成的可視化呈現，可讓您輕鬆地識別常見程式碼路徑。

```
"KeyedProcess (1/3)#0" prio=5 Id=1423 RUNNABLE
    at app//scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:154)
    at $line33.$read$$iw$$iw$ExpensiveFunction.processElement(<console>>19)
    at $line33.$read$$iw$$iw$ExpensiveFunction.processElement(<console>:14)
    at app//org.apache.flink.streaming.api.operators.KeyedProcessOperator.processElement(KeyedProcessOperator.java:83)
    at app//org.apache.flink.streaming.runtime.tasks.OneInputStreamTask$StreamTaskNetworkOutput.emitRecord(OneInputStreamTask.java:205)
    at app//org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.processElement(AbstractStreamTaskNetworkInput.java:134)
    at app//org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.emitNext(AbstractStreamTaskNetworkInput.java:105)
    at app//org.apache.flink.streaming.runtime.io.StreamOneInputProcessor.processInput(StreamOneInputProcessor.java:66)
    ...
```

以上是從 Flink UI 為單個執行緒取得的執行緒傾印的片段。第一行包含有關此執行緒的一些一般資訊，包括：
+ 執行緒名稱 *KeyedProcess (1/3)\$10*
+ 執行緒優先順序 *prio=5*
+ 唯一的執行緒 ID *Id=1423*
+ 執行緒狀態 *RUNNABLE*

 執行緒名稱通常會提供執行緒一般用途的資訊。運算子執行緒可以通過其名稱來識別，因為運算子執行緒與運算子具有相同的名稱，並且會指出其相關子任務，例如，*KeyedProcess (1/3)\$10* 執行緒來自 *KeyedProcess* 運算子，並且來自第 1 個子任務 (共 3 個)。

執行緒可以是下列幾種狀態之一：
+ NEW：執行緒已建立，但尚未得到處理
+ RUNNABLE：執行緒正在 CPU 上執行
+ BLOCKED：執行緒正在等待另一個執行緒釋放其鎖定
+ WAITING：執行緒正在使用 `wait()`、`join()` 或 `park()` 方法等待
+ TIMED\$1WAITING：執行緒正在使用睡眠、等待、聯結或駐留方法等待，但等待時間最長。

**注意**  
在 Flink 1.13 中，執行緒傾印中單一堆疊追蹤的最大深度限制為 8。

**注意**  
執行緒傾印必須是 Flink 應用程式中偵錯效能問題的最後手段，因為它們可能難以讀取，需要擷取和手動分析多個樣本。如果有可能，最好使用火焰圖。

### Flink 中的執行緒傾印
<a name="troubleshooting-checkpoints-investigating-thread-dumps-flink"></a>

在 Flink 中，透過選擇 Flink UI 左側導覽列上的**任務管理員**選項，選取特定任務管理員，然後瀏覽至**執行緒傾印**標籤，即可取得執行緒傾印。您可以下載執行緒傾印、複製到喜愛的文字編輯器 (或執行緒傾印分析器)，或直接在 Flink Web UI 的文字檢視中進行分析 (不過最後一個選項可能有點繁瑣)。

為了確定在選擇特定運算子後，要用來取得 **TaskManager** 選項卡執行緒傾印的任務管理員。這表明運算子正在運算子的不同子任務上執行，並且可以在不同的任務管理員上執行。

![\[使用執行緒傾印\]](http://docs.aws.amazon.com/zh_tw/managed-flink/latest/java/images/checkpoint4.png)


傾印將由多個堆疊追蹤組成。但是，在調查傾印時，與運算子關聯的傾印最重要。這些很容易找到，因為運算子執行緒與運算子具有相同的名稱，並且會指出與哪個子任務相關聯。例如，以下堆疊追蹤來自 *KeyedProcess* 運算子，並且是第 1 個子任務。

```
"KeyedProcess (1/3)#0" prio=5 Id=595 RUNNABLE
    at app//scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:155)
    at $line360.$read$$iw$$iw$ExpensiveFunction.processElement(<console>:19)
    at $line360.$read$$iw$$iw$ExpensiveFunction.processElement(<console>:14)
    at app//org.apache.flink.streaming.api.operators.KeyedProcessOperator.processElement(KeyedProcessOperator.java:83)
    at app//org.apache.flink.streaming.runtime.tasks.OneInputStreamTask$StreamTaskNetworkOutput.emitRecord(OneInputStreamTask.java:205)
    at app//org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.processElement(AbstractStreamTaskNetworkInput.java:134)
    at app//org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.emitNext(AbstractStreamTaskNetworkInput.java:105)
    at app//org.apache.flink.streaming.runtime.io.StreamOneInputProcessor.processInput(StreamOneInputProcessor.java:66)
    ...
```

如果有多個運算子具有相同名稱，則可能會造成混淆，但我們可以透過命名運算子來解決這個問題。例如：

```
....
.process(new ExpensiveFunction).name("Expensive function")
```

## [火焰圖](https://nightlies.apache.org/flink/flink-docs-release-1.13/docs/ops/debugging/flame_graphs/)
<a name="troubleshooting-checkpoints-investigating-flame-graphs"></a>

火焰圖是一款有用的偵錯工具，它可以可視化目標程式碼的堆疊追蹤，從而允許識別最常見的程式碼路徑。它們透過對堆疊追蹤進行多次取樣來建立。火焰圖的 x 軸顯示不同的堆疊設定檔，y 軸顯示堆疊深度，以及堆疊追蹤中的呼叫。火焰圖中的單個矩形顯示在堆疊框架上，框架的寬度顯示它在堆疊中出現的頻率。如需火焰圖表及其用法的詳細資訊，請參閱[火焰圖](https://www.brendangregg.com/flamegraphs.html)。

在 Flink 中，運算子的火焰圖可以透過 Web UI 存取，方法是選取運算子，然後選擇**火焰圖**標籤。一旦收集到足夠的樣本，火焰圖即會顯示。以下是花費了大量時間執行檢查點的 ProcessFunction 的火焰圖。

![\[使用火焰圖\]](http://docs.aws.amazon.com/zh_tw/managed-flink/latest/java/images/checkpoint3.png)


這是一個非常簡單的火焰圖，其中顯示了所有 CPU 時間都花費在一個 foreach 迴圈內的 ExpensiveFunction 運算子的 `processElement` 內。您還可以取得行號，以幫助確定程式碼的執行位置。

# 檢查點逾時
<a name="troubleshooting-chk-timeout"></a>

如果應用程式未最佳化或正確佈建，檢查點可能會失敗。本節說明此狀況的徵狀和疑難排解步驟。

## 徵狀
<a name="troubleshooting-chk-timeout-symptoms"></a>

如果應用程式的檢查點失敗，`numberOfFailedCheckpoints` 將會大於零。

檢查點可能會因為直接失敗 (例如應用程式錯誤) 或暫時性失敗 (例如應用程式資源不足) 而失敗。檢查應用程式日誌和指標是否有下列徵狀：
+ 程式碼中有錯誤。
+ 存取應用程式相依服務時發生錯誤。
+ 序列化資料時發生錯誤。如果預設的序列化程式無法序列化應用程式資料，則應用程式將失敗。如需有關在應用程式中使用自訂序列化程式的資訊，請參閱 Apache Flink 文件中的[資料類型和序列化](https://nightlies.apache.org/flink/flink-docs-release-1.19/docs/dev/datastream/fault-tolerance/serialization/types_serialization/)。
+ 記憶體不足錯誤。
+ 以下指標急劇增加或穩定增加：
  + `heapMemoryUtilization`
  + `oldGenerationGCTime`
  + `oldGenerationGCCount`
  + `lastCheckpointSize`
  + `lastCheckpointDuration`

如需監控檢查點的詳細資訊，請參閱 Apache Flink 文件中的[監控檢查點](https://nightlies.apache.org/flink/flink-docs-release-1.19/docs/ops/monitoring/checkpoint_monitoring/)。

## 原因和解決方案
<a name="troubleshooting-chk-timeout-causes"></a>

您的應用程式日誌錯誤訊息會顯示直接失敗的原因。暫時性失敗可能有下列原因：
+ 應用程式佈建的 KPU 不足。如需增加應用程式佈建的相關資訊，請參閱[實作應用程式擴展](how-scaling.md)。
+ 應用程式狀態大小太大。您可以使用 `lastCheckpointSize` 指標監控應用程式狀態大小。
+ 應用程式的狀態資料在索引鍵之間分配不平均。如果應用程式使用 `KeyBy` 運算子，請確保您的傳入資料在索引鍵之間已平均分割。如果將大部分資料指派給單一索引鍵，則會產生瓶頸，從而導致失敗。
+ 應用程式遇到記憶體背壓或垃圾回收背壓。監控應用程式的 `heapMemoryUtilization`、`oldGenerationGCTime` 以及 `oldGenerationGCCount`，看是否有值在急劇增加或穩定增加。

# Apache Beam 應用程式檢查點失敗
<a name="troubleshooting-chk-failure-beam"></a>

如果設定 Beam 應用程式時將 [shutdownSourcesAfterIdleMs](https://beam.apache.org/documentation/runners/flink/#:~:text=shutdownSourcesAfterIdleMs) 設定為 0ms，則檢查點可能無法觸發，因為任務處於「FINISHED」狀態。本節說明此狀況的徵狀和解決方案。

## 徵狀
<a name="troubleshooting-chk-failure-beam-symptoms"></a>

前往 Managed Service for Apache Flink 應用程式 CloudWatch 日誌，檢查其中是否記錄了下列日誌訊息。下列日誌訊息指出檢查點無法觸發，因為某些任務已完成。

```
                {
                "locationInformation": "org.apache.flink.runtime.checkpoint.CheckpointCoordinator.onTriggerFailure(CheckpointCoordinator.java:888)",
                "logger": "org.apache.flink.runtime.checkpoint.CheckpointCoordinator",
                "message": "Failed to trigger checkpoint for job your job ID since some tasks of job your job ID has been finished, abort the checkpoint Failure reason: Not all required tasks are currently running.",
                "threadName": "Checkpoint Timer",
                "applicationARN": your application ARN,
                "applicationVersionId": "5",
                "messageSchemaVersion": "1",
                "messageType": "INFO"
                }
```

這也可以在 Flink 儀表板上找到，其中一些任務已進入「FINISHED」狀態，並且無法再執行檢查點。

![\[任務處於「FINISHED」狀態\]](http://docs.aws.amazon.com/zh_tw/managed-flink/latest/java/images/beam_checkpoint_failure.png)


## 原因
<a name="troubleshooting-chk-failure-beam-causes"></a>

shutdownSourcesAfterIdleMs 是 Beam 組態變數，可關閉閒置了一段設定時間 (毫秒) 的來源。一旦來源關閉，無法再執行檢查點。這可能導致[檢查點失敗](https://issues.apache.org/jira/browse/FLINK-2491)。

任務進入「FINISHED」狀態的其中一個原因是當 shutdownSourcesAfterIdleMs 設定為 0ms 時，意味著閒置的任務將立即關閉。

## 解決方案
<a name="troubleshooting-chk-failure-beam-solution"></a>

若要防止任務立即進入「FINISHED」狀態，請將 shutdownSourcesAfterIdleMs 設定為 Long.MAX\$1VALUE。這可以透過兩種方式進行：
+ 選項 1：如果 Beam 組態是在 Managed Service for Apache Flink 應用程式的組態頁面中設定，則可以新增一個鍵值對來設定 shutdpwnSourcesAfteridleMs，如下所示：  
![\[將 shutdownSourcesAfterIdleMs 設定為 Long.MAX_VALUE\]](http://docs.aws.amazon.com/zh_tw/managed-flink/latest/java/images/beam_checkpoint_failure_solution.png)
+ 選項 2：如果 Beam 組態是在 JAR 檔案中設定，您可以按如下方式設定 shutdownSourcesAfterIdleMs：

  ```
                          FlinkPipelineOptions options = PipelineOptionsFactory.create().as(FlinkPipelineOptions.class); // Initialize Beam Options object
  
                          options.setShutdownSourcesAfterIdleMs(Long.MAX_VALUE); // set shutdownSourcesAfterIdleMs to Long.MAX_VALUE
                          options.setRunner(FlinkRunner.class);
  
                          Pipeline p = Pipeline.create(options); // attach specified options to Beam pipeline
  ```

# 背壓
<a name="troubleshooting-backpressure"></a>

Flink 使用背壓來調整個別運算子的處理速度。

由於許多原因，運算子可能難以跟上處理收到的訊息量。該操作可能需要比運算子可用資源更多的 CPU 資源，運算子可能會等待 I/O 操作完成。如果運算子無法以足夠快的速度處理事件，它會在饋送給慢速運算子的上游運算子中造成背壓。這會導致上游運算子減慢速度，從而進一步將背壓傳播到來源，並透過減慢速度來使來源適應應用程式的整體輸送量。您可以在 [Apache Flink™ 如何處理背壓](https://www.ververica.com/blog/how-flink-handles-backpressure)中找到有關背壓及其運作方式的更深入說明。

知道應用程式中的哪些運算子速度緩慢，可為您提供重要資訊來了解應用程式效能問題的根本原因。背壓資訊[透過 Flink 控制面板公開](https://nightlies.apache.org/flink/flink-docs-stable/docs/ops/monitoring/back_pressure/)。若要識別慢速運算子，請尋找具有最接近接收器高背壓值的運算子 (以下範例中為運算子 B)。造成緩慢的運算子就是其中一個下游運算子 (範例中的運算子 C)。B 可以更快地處理事件，但由於無法將輸出轉發到實際的慢速運算子 C，因此會受到背壓。

```
A (backpressured 93%) -> B (backpressured 85%) -> C (backpressured 11%) -> D (backpressured 0%)
```

一旦確定慢速運算子，試著了解它為什麼慢。可能有無數的原因，有時出了什麼問題並不明顯，可能需要數天的偵錯和分析來解決。以下是一些明顯和更常見的原因，其中一些進一步解釋如下：
+ 運算子正在執行緩慢的 I/O，例如網路呼叫 (考慮改用 AsyncIO)。
+ 存在資料扭曲，一個運算子接收的事件比其他運算子多，可查看 Flink 儀表板中單個子任務 (即同一運算子的多個執行個體) 的進/出訊息數目進行驗證。
+ 這是一個消耗資源的操作 (如果沒有資料扭曲，請考慮橫向擴展 CPU/記憶體綁定的工作或增加 I/O 綁定工作的 `ParallelismPerKPU`)
+ 運算子中存在大量記錄 (將生產應用程式的記錄減少到最低限度，或者考慮將偵錯輸出發送到資料串流)。

## 使用捨棄接收器測試輸送量
<a name="troubleshooting-testing-throughput"></a>

[丟棄接收器](https://nightlies.apache.org/flink/flink-docs-stable/api/java/org/apache/flink/streaming/api/functions/sink/DiscardingSink.html)只是忽略它在仍在執行應用程式時收到的所有事件 (沒有任何接收器的應用程式無法執行)。這對於輸送量測試、分析以及驗證應用程式是否正確擴展非常有用。這也是一種非常簡潔實用的完整性檢查，可以驗證接收器是否給應用程式導致背壓 (不過直接檢查背壓指標通常更容易和更直接)。

您可以透過用捨棄的接收器取代應用程式的所有接收器，並建立可產生與生產資料類似資料的模擬來源，來衡量應用程式在特定平行處理設定時的最大輸送量。然後，您也可以增加平行處理層級，以驗證應用程式是否正確擴展，並且沒有只在較高輸送量 (例如由於資料扭曲) 時才會出現的瓶頸。

# 資料扭曲
<a name="troubleshooting-data-skew"></a>

Flink 應用程式在叢集上分散式執行。為了橫向擴展到多個節點，Flink 使用了鍵控串流的概念，這實質上意味著某個串流的事件將依據特定索引鍵 (例如客戶 ID) 進行分割，然後 Flink 可以處理不同節點上的不同分割區。許多 Flink 運算子然後會根據這些分割區評估，例如[鍵控視窗](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/windows/)、[處理函數](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/process_function/)和[非同步 I/O](https://nightlies.apache.org/flink/flink-docs-stable/docs/dev/datastream/operators/asyncio/)。

選擇分割區索引鍵通常取決於業務邏輯。同時，許多最佳實務 (例如 [DynamoDB](https://aws.amazon.com/dynamodb/) 和 Spark) 同樣適用於 Flink，包括：
+ 確保分割區索引鍵的高基數
+ 避免分割區之間的事件量扭曲

 您可以比較 Flink 儀表板中接收/發送的子任務 (即同一運算子的多個執行個體) 的記錄數來識別分割區中是否存在扭曲。此外，Managed Service for Apache Flink 監控也可設定為公開子任務層級的 `numRecordsIn/Out` 和 `numRecordsInPerSecond/OutPerSecond` 指標。

# 狀態扭曲
<a name="troubleshooting-state-skew"></a>

對於有狀態運算子，即負責維護其業務邏輯 (如視窗) 狀態的運算子，資料扭曲總是會導致狀態扭曲。由於資料扭曲，某些子任務比其他子任務收到更多的事件，因此也在狀態中保留了更多資料。但是，即使對於具有均勻平衡分割區的應用程式，在狀態中保留多少資料也可能會出現扭曲。例如，對於工作階段視窗，某些使用者和工作階段分別都可能比其他使用者和工作階段長得多。如果較長的工作階段恰好是相同分割區的一部分，則可能導致相同運算子的不同子任務所保留的狀態大小不平衡。

 狀態扭曲不僅增加了個別子任務所需的記憶體和磁碟資源，還會降低應用程式的整體效能。當應用程式取得檢查點或儲存點時，運算子狀態會保留在 Amazon S3 種，以保護狀態免受節點或叢集故障影響。在此處理程序期間 (特別是在 Managed Service for Apache Flink 上預設只啟用恰好一次的語義中)，處理會從外部暫停，直到檢查點/儲存點執行完成為止。如果有資料扭曲，則完成操作的時間可能會受到已累積了特別大量的狀態之單一子任務所限制。在極端情況下，由於單個子任務無法持續保留狀態，擷取檢查點/儲存點可能會失敗。

 因此，與資料扭曲類似，狀態扭曲也會大幅降低應用程式執行速度。

 若要識別狀態扭曲，可以利用 Flink 儀表板。尋找最新的檢查點或儲存點，並在詳細資料中比較已針對個別子任務儲存的資料量。

# 與不同區域中的資源整合
<a name="troubleshooting-resources-in-different-regions"></a>

您可以啟用 `StreamingFileSink`，透過 Flink 組態中跨區域複寫所需的設定，從 Managed Service for Apache Flink 應用程式寫入不同區域中的 Amazon S3 儲存貯體。若要這樣做，請在 [AWS 支援 中心](https://console.aws.amazon.com/support/home#/)填寫支援票證。