

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 런타임 문제 해결
<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`)에 정체되어 있는 경우 `Force` 파라미터가 `true`로 설정된 상태에서 [StopApplication](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_StopApplication.html) 작업을 사용하여 애플리케이션을 중지할 수 있습니다. `DELETING` 상태에서는 애플리케이션을 강제로 중지할 수 없습니다. 또는 애플리케이션이 `UPDATING` 또는 `AUTOSCALING` 상태인 경우 이전 실행 버전으로 회귀할 수 있습니다. 애플리케이션을 회귀시키면 마지막으로 성공한 스냅샷의 상태 데이터가 로드됩니다. 애플리케이션에 스냅샷이 없는 경우 Managed Service for Apache Flink는 회귀 요청을 거부합니다. 애플리케이션 회귀에 대한 자세한 설명은 [RollbackApplication](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_RollbackApplication.html)을 참조하십시오.

**참고**  
애플리케이션을 강제로 중지하면 데이터가 손실되거나 중복될 수 있습니다. 애플리케이션 재시작 시 데이터 손실이나 데이터 중복 처리를 방지하려면 애플리케이션의 스냅샷을 자주 생성하는 것이 좋습니다.

애플리케이션이 정체되는 사유에는 다음이 포함됩니다.
+ **애플리케이션 상태가 너무 큼:** 애플리케이션 상태가 너무 크거나 너무 지속적이면 체크포인트 또는 스냅샷 작업 중에 애플리케이션이 정체될 수 있습니다. 애플리케이션의 지표 `lastCheckpointDuration` 및 `lastCheckpointSize`의 값이 꾸준히 증가하거나 비정상적으로 높은지 확인하십시오.
+ **애플리케이션 코드가 너무 큼:** 애플리케이션 JAR 파일이 512MB보다 작은지 확인하십시오. 512MB보다 큰 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) 요청 중에 애플리케이션의 스냅샷을 찍습니다. 그런 다음 이 서비스는 이 스냅샷 상태를 사용하고 업데이트된 애플리케이션 구성을 사용하여 애플리케이션을 복원하여 *정확히 1회에 한하여* 시맨틱의 처리를 제공합니다. 자동 스냅샷 생성이 실패할 경우, 다음의 [스냅샷 생성 실패](#troubleshooting-rt-snapshots)을 참조하십시오.
+ **스냅샷 실패로부터 복구:** 애플리케이션 업데이트에서 연산자를 제거하거나 변경한 후 스냅샷에서 복구하려고 시도하면 스냅샷에 누락된 연산자에 대한 상태 데이터가 포함되어 있으면 기본적으로 복구가 실패합니다. 또한 이 애플리케이션은 `STOPPED` 또는 `UPDATING` 상태 중 하나로 고정됩니다. [이 동작을 변경하여 복구에 성공하려면 애플리케이션 FlinkRun Configuration의 *AllowNonRestoredState* 파라미터를 `true`으로 변경하십시오.](https://docs.aws.amazon.com/managed-flink/latest/apiv2/API_FlinkRunConfiguration.html) 이렇게 하면 새 프로그램에 매핑할 수 없는 상태 데이터를 재개 작업에서 건너뛰도록 할 수 있습니다.
+ **애플리케이션 초기화 시간이 더 오래 걸림:** 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분 이상 걸리고, 이로 인해 Managed Service for Apache Flink 끝에서 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를 사용하는 것이 좋습니다. Managed Service for Apache Flink와 함께 Firehose를 사용하는 방법에 관한 자세한 설명은 [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` 지표가 0이 아님. 이 지표는 측정 단위는 귀하가 애플리케이션을 시작한 이후 해당 애플리케이션의 작업이 다시 시작된 횟수를 나타냅니다.
+ `Downtime` 지표가 0이 아님. 이 지표는 애플리케이션이 `FAILING` 또는 `RESTARTING` 상태에 있는 밀리초의 수치를 나타냅니다.
+ 애플리케이션 로그는 `RESTARTING` 또는 `FAILED`로의 상태 변경을 포함합니다. 다음과 같은 CloudWatch Logs Insights 쿼리를 사용하여 애플리케이션 로그에서 이러한 상태 변경을 검색할 수 있습니다. [오류 분석: 애플리케이션 작업 관련 실패](cloudwatch-logs-reading.md#cloudwatch-logs-reading-apps).

## 원인 및 해결 방법
<a name="troubleshooting-rt-restarts-causes"></a>

다음과 같은 상태 하에서 애플리케이션은 불안정해지고 반복적으로 다시 시작될 수 있습니다.
+ **연산자가 예외를 발생시키는 경우:** 귀하의 애플리케이션에서 연산자의 예외가 처리되지 않으면 연산자가 오류를 처리할 수 없다고 해석하여 애플리케이션이 페일오버됩니다. “정확히 한 번” 처리하라는 의미를 유지하기 위해 애플리케이션이 최근의 체크포인트에서 다시 시작됩니다. 따라서 이러한 재시작 기간 동안에는 `Downtime`의 값이 0이 아닙니다. 이러한 일이 발생하지 않도록 하려면 애플리케이션 코드에서 재시도 가능한 예외를 모두 처리하는 것이 좋습니다.

  애플리케이션 로그를 검색하여 애플리케이션 상태를 `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에서의 애플리케이션 실패:** 이 오류는 Apache Flink 1.11 이전 버전을 사용하는 경우 귀하의 애플리케이션 로그에 나타납니다. KPL 0.14 또는 그 이후 버전을 사용하려면 Apache Flink를 이후 버전으로 업그레이드해야 할 수 있습니다.
+ **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`를 명시적 의존성으로 제공하지 않으면 애플리케이션이 환경 의존성에서 해당 버전을 로드하고, 버전이 일치하지 않으므로 애플리케이션이 런타임에 충돌합니다.

  Managed Service for Apache Flink와 Apache Beam을 사용하는 방법에 대한 자세한 내용을 알아보려면 [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 설명서의 [상태 존속 시간(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는 증분 체크포인트를 사용하므로 상태 존속 시간은 [RocksDB 압축](https://github.com/facebook/rocksdb/wiki/Compaction)에 근거합니다. 압축 작업이 수행된 후에야 실제 상태 크기 감소(체크포인트 크기로 표시)를 관찰할 수 있습니다. 특히 체크포인트 크기가 200MB 미만인 경우 상태 만료로 인해 체크포인트 크기가 줄어들 가능성은 거의 없습니다. 하지만 세이브 포인트는 이전 데이터가 포함되지 않은 상태의 깨끗한 사본에 근거하므로 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 바운드 연산자가 있는 애플리케이션의 경우 Managed Service for 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` 호출당 인출되는 최대 레코드 수에 대해 매우 엄격한 기본 설정이 사용됩니다. 샤드당 레코드 한도는 레코드 1,000개에 불과하지만 Apache Flink는 기본적으로 `GetRecords` 직접 호출당 10,000개의 레코드를 가져오도록 구성되어 있습니다(이 직접 호출은 기본적으로 200ms마다 수행됨).

이 기본 동작으로 인해 Kinesis 데이터 스트림을 사용하려고 할 때 병목 현상이 발생하여 애플리케이션 성능 및 안정성에 영향을 미칠 수 있습니다.

CloudWatch `ReadProvisionedThroughputExceeded` 지표를 확인하여 이 지표가 0보다 큰 상태가 장기간 또는 지속적으로 이어지는지 보면 이를 확인할 수 있습니다.

Amazon Managed Service for Apache Flink 애플리케이션의 CloudWatch 로그에서 지속적인 `LimitExceededException` 오류가 발생하는지 확인해 이를 파악할 수 있습니다.

**해결 방법**: 다음 두 가지 중 하나를 수행하여 이 시나리오를 해결할 수 있습니다.
+ `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의 웹 인터페이스는 체크포인트 문제를 조사하는 데 도움이 되는 데이터와 정보를 제공합니다. 자세한 설명은 [체크포인트 모니터링](https://nightlies.apache.org/flink/flink-docs-release-1.13/docs/ops/monitoring/checkpoint_monitoring/)을 참조하십시오.

 가장 먼저 살펴볼 것은 Job 그래프에서 각 연산자의 **단대단 지속시간**입니다. 이를 통해 어떤 연산자가 체크포인트에 걸리는 시간이 소요되며 추가 조사가 필요한지 확인할 수 있습니다. Flink 설명서에 따르면 지속시간의 정의는 다음과 같습니다:

*트리거 타임스탬프부터 가장 최근 승인까지 남은 시간(또는 아직 승인이 수신되지 않은 경우 해당 없음). 전체 체크포인트의 단대단 지속 시간은 체크포인트를 승인하는 마지막 하위 작업에 의해 결정됩니다. 이 시간은 일반적으로 단일 하위 작업에서 상태를 실제로 체크포인팅하는 데 필요한 시간보다 큽니다.*

체크포인트를 위한 다른 지속시간은 또한 그 시간이 어디에 사용되는지에 대한 보다 세밀한 정보를 제공합니다.

**동기화 지속 시간**이 길면 스냅샷 중에 문제가 발생한 것입니다. 이 단계에서는 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/ko_kr/managed-flink/latest/java/images/checkpoint.png)


**개시 지연**이 높으면 대부분의 시간이 체크포인트 장벽이 연산자에게 도달하기를 기다리는 데 소비되고 있다는 것을 알 수 있습니다. 이는 애플리케이션에서 기록을 처리하는 데 시간이 오래 걸리고 있다는 것을 의미하며, 이는 작업 그래프를 통해 장벽이 느리게 흐르고 있음을 의미합니다. 이는 일반적으로 Job이 역압을 받거나 연산자가 계속 바쁠 경우에 해당합니다. 다음은 두 번째 KeyedProcess 연산자가 사용 중인 JobGraph의 예입니다.

![\[체크포인트 조사\]](http://docs.aws.amazon.com/ko_kr/managed-flink/latest/java/images/checkpoint2.png)


Flink Graphs 또는 TaskManager 스레드 덤프를 사용하여 무엇이 그렇게 오래 걸리는지 조사할 수 있습니다. 병목 현상이 확인되면 Flame-graph 또는 스레드 덤프를 사용하여 더 자세히 조사할 수 있습니다.

## 스레드 덤프
<a name="troubleshooting-checkpoints-investigating-thread-dumps"></a>

스레드 덤프는 플레임 그래프보다 약간 낮은 수준에 있는 또 다른 디버깅 도구입니다. 스레드 덤프는 특정 시점의 모든 스레드의 실행 상태를 출력합니다. Flink는 Flink 프로세스 내 모든 스레드의 실행 상태인 JVM 스레드 덤프를 사용합니다. 스레드 상태는 스레드의 스택 트레이스와 몇 가지 추가 정보로 표시됩니다. 실제로 플레임 그래프는 여러 개의 스택 트레이스를 연속으로 빠르게 캡처하여 작성합니다. 그래프는 이러한 트레이스를 바탕으로 만든 가시화이므로 일반적인 코드 경로를 쉽게 식별할 수 있습니다.

```
"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*
+ 스레드 상태 *실행 가능*

 스레드 명칭은 일반적으로 스레드의 일반적인 용도에 대한 정보를 제공합니다. 연산자 스레드는 연산자와 명칭이 같기 때문에 연산자 스레드는 그 명칭으로 식별할 수 있으며 스레드가 어떤 하위 작업과 관련되어 있는지를 나타냅니다. 예컨대, *KeyedProcess (1/3)\$10* 스레드는 *KeyedProcess* 연산자 출신으로서 (3개 중) 첫 번째 하위 태스크에서 온 것입니다.

스레드는 몇 가지 상태 중 하나일 수 있습니다.
+ 신규 – 스레드가 생성되었지만 아직 처리되지는 않았음.
+ 실행 가능 – 스레드가 CPU에서 실행 중임.
+ 차단됨 – 스레드가 다른 스레드에 의한 잠금 해제를 기다리고 있음.
+ 대기 – `wait()`, `join()`, 또는 `park()` 메서드를 사용함으로써 스레드가 대기 중임.
+ TIMED\$1WAITING – 스레드가 sleep, wait, join 또는 park 메서드를 사용하여 대기 중이지만 대기 시간은 최대로 설정되어 있음.

**참고**  
Flink 1.13에서는 스레드 덤프에 있는 단일 스택 트레이스의 최대 깊이가 8로 제한됩니다.

**참고**  
스레드 덤프는 읽기가 어렵고 여러 샘플을 채취하여 수동으로 분석해야 하므로 Flink 애플리케이션에서 성능 문제를 디버깅할 때 최후의 수단이어야 합니다. 가능하면 플레임 그래프를 사용하는 것이 좋습니다.

### Flink의 스레드 덤프
<a name="troubleshooting-checkpoints-investigating-thread-dumps-flink"></a>

Flink에서는 Flink UI의 왼쪽 탐색 표시줄에서 **작업 관리자** 옵션을 선택하고 특정 작업 관리자를 선택한 다음 스레드 덤프 탭으로 이동하여 **스레드 덤프**를 가져올 수 있습니다. 스레드 덤프는 다운로드하거나 즐겨 사용하는 텍스트 편집기 (또는 스레드 덤프 분석기) 에 복사하거나 Flink 웹 UI의 텍스트 보기 내에서 직접 분석할 수 있습니다 (하지만 이 마지막 옵션은 약간 복잡할 수 있습니다).

스레드 덤프를 수행할 작업 관리자를 결정하려면 특정 연산자를 선택한 경우 **TaskManager** 탭의 스레드 덤프를 사용할 수 있습니다. 이는 연산자가 연산자의 여러 하위 작업에서 실행되고 있으며 다른 작업 관리자에서 실행될 수 있음을 나타냅니다.

![\[스레드 덤프 사용\]](http://docs.aws.amazon.com/ko_kr/managed-flink/latest/java/images/checkpoint4.png)


덤프는 여러 스택 트레이스로 구성됩니다. 하지만 덤프를 조사할 때는 연산자와 관련된 것이 가장 중요합니다. 연산자 스레드는 연산자와 이름이 같을 뿐만 아니라 해당 스레드가 어떤 하위 작업과 관련되어 있는지 알 수 있기 때문에 쉽게 찾을 수 있습니다. 예를 들어 다음 스택 트레이스는 *KeyedProcess* 연산자에서 가져온 것이며 첫 번째 하위 태스크입니다.

```
"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에서는 연산자를 선택한 다음 **FlameGraph** 탭을 선택하여 웹 UI를 통해 연산자에 대한 플레임 그래프에 액세스할 수 있습니다. 샘플이 충분히 수집되면 플레임 그래프가 표시됩니다. 다음은 체크포인트에 많은 시간이 걸렸던 ProcessFunction의 플레임 그래프입니다.

![\[플레임 그래프 사용\]](http://docs.aws.amazon.com/ko_kr/managed-flink/latest/java/images/checkpoint3.png)


이것은 매우 간단한 플레임 그래프로, 모든 CPU 시간이 ExpensiveFunction 연산자의 `processElement`내의 foreach 룩에 소비되고 있음을 보여줍니다. 또한 라인 번호도 확인할 수 있어 코드 실행이 이루어지는 위치를 파악하는 데 도움이 됩니다.

# 체크포인트 시간이 초과되었습니다.
<a name="troubleshooting-chk-timeout"></a>

애플리케이션이 최적화되지 않았거나 제대로 프로비저닝되지 않은 경우 체크포인트가 실패할 수 있습니다. 이 섹션에서는 이러한 상태에 대한 증상과 문제 해결 조치들을 설명합니다.

## 증상
<a name="troubleshooting-chk-timeout-symptoms"></a>

애플리케이션의 체크포인트에 장애가 발생하는 경우 `numberOfFailedCheckpoints` 값은 0보다 커집니다.

애플리케이션 오류와 같은 직접적인 장애나 애플리케이션 리소스 부족과 같은 일시적인 장애로 인해 체크포인트가 실패할 수 있습니다. 애플리케이션 로그와 지표에서 다음과 같은 증상이 있는지 확인하십시오.
+ 코드에 오류가 있습니다.
+ 애플리케이션의 종속 서비스에 액세스하는 중 오류가 발생했습니다.
+ 데이터를 직렬화하는 중 오류가 발생했습니다. 기본 시리얼라이저가 애플리케이션 데이터를 직렬화할 수 없는 경우 애플리케이션이 실패합니다. 애플리케이션에서 사용자 지정 직렬 변환기를 사용하는 방법에 관한 자세한 설명은 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로 설정하도록 구성된 경우 작업이 “완료” 상태이기 때문에 체크포인트가 트리거되지 않을 수 있습니다. 이 섹션에서는 그러한 상황의 증상과 해결 방법을 설명합니다.

## 증상
<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 대시보드에서도 이 문제를 확인할 수 있습니다.

![\[“완료” 상태인 작업은\]](http://docs.aws.amazon.com/ko_kr/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)가 발생할 수 있습니다.

작업이 “완료” 상태로 전환되는 원인 중 하나는 ShutdownSourcesAfterIdleMs가 0ms로 설정된 경우입니다. 즉, 유휴 상태인 작업이 즉시 종료됩니다.

## Solution
<a name="troubleshooting-chk-failure-beam-solution"></a>

작업이 즉시 “완료” 상태로 전환되지 않도록 하려면 shutdownSourcesAfterIdleMs를 Long.MAX\$1VALUE를 설정하십시오. 이것은 두 가지 방법으로 수행될 수 있습니다.
+ 옵션 1: Managed Service for Apache Flink 애플리케이션 구성 페이지에서 빔 구성을 설정한 경우 다음과 같이 새 키 값 쌍을 추가하여 shutdpwnSourcesAfteridleMs를 설정할 수 있습니다.  
![\[shutdpwnSourcesAfteridleMs를 Long.MAX_VALUE로 설정합니다.\]](http://docs.aws.amazon.com/ko_kr/managed-flink/latest/java/images/beam_checkpoint_failure_solution.png)
+ 옵션 2: JAR 파일에 빔 컨피그레이션이 설정된 경우 다음과 같이 shutdpwnSourcesAfteridleMs를 설정할 수 있습니다:

  ```
                          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는 여러 노드의 여러 파티션을 처리할 수 있습니다. 그런 다음 [키 윈도우](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/) 등과 같은 여러 Flink 연산자를 이러한 파티션을 기반으로 평가합니다.

파티션 키 선택은 대개 비즈니스 로직에 따라 달라집니다. 동시에 다음과 같은 [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에서 정확히 1회의 시맨틱이 기본으로 활성화되어 있는 경우) 체크포인트/세이브포인트가 완료될 때까지 외부 관점에서 처리가 중단됩니다. 데이터 편중이 있는 경우 특히 많은 양의 상태가 누적된 단일 하위 작업으로 인해 작업을 완료하는 데 걸리는 시간이 제한될 수 있습니다. 극단적인 경우에는 단일 하위 작업이 상태를 유지할 수 없어 체크포인트/세이브포인트 가져오기가 실패할 수 있습니다.

 따라서 상태 편중은 데이터 편중과 마찬가지로 애플리케이션 속도를 크게 저하시킬 수 있습니다.

 상태 편중을 식별하기 위해 Flink 대시보드를 활용할 수 있습니다. 최근 체크포인트 또는 세이브포인트를 찾아 세부 정보에서 개별 하위 작업에 대해 저장된 데이터의 양을 비교해 보세요.

# 서로 다른 리전의 리소스와 통합
<a name="troubleshooting-resources-in-different-regions"></a>

Flink 구성에서 지역 간 복제에 필요한 설정을 통해 Managed Service for Apache Flink 애플리케이션과 다른 지역에 있는 Amazon S3 버킷에 쓸 수 있도록 `StreamingFileSink`의 사용을 활성화할 수 있습니다. 이를 위해서는 [AWS Support 센터](https://console.aws.amazon.com/support/home#/)에 지원 티켓을 제출하십시오.