

# 작업 모니터링 및 디버깅
<a name="monitor-profile-glue-job-cloudwatch-metrics"></a>

AWS Glue 작업에 대한 지표를 수집하고 AWS Glue 및 Amazon CloudWatch 콘솔에서 이러한 지표를 시각화하여 문제를 식별하고 수정할 수 있습니다. AWS Glue 작업을 프로파일링하려면 다음 단계를 수행해야 합니다.

1.  지표를 활성화하려면 다음을 수행합니다.

   1.  작업 정의에서 **작업 측정치** 옵션을 활성화합니다. AWS Glue 콘솔에서 또는 작업의 파라미터로서 프로파일링을 활성화할 수 있습니다. 자세한 정보는 [Spark 작업에 대한 작업 속성 정의](add-job.md#create-job) 또는 [AWS Glue 작업에서 작업 파라미터 사용](aws-glue-programming-etl-glue-arguments.md) 섹션을 참조하세요.

   1.  작업 정의에서 **AWS Glue 관찰성 지표** 옵션을 활성화합니다. AWS Glue 콘솔에서 또는 작업의 파라미터로서 관찰성을 활성화할 수 있습니다. 자세한 내용은 [AWS Glue 관찰성 메트릭을 사용한 모니터링](monitor-observability.md)을 참조하세요.

1. 작업 스크립트에서 `GlueContext`를 초기화하는지 확인합니다. 예를 들면 다음 스크립트 조각은 `GlueContext`를 초가화하고 프로파일링된 코드가 스크립트에 있는 위치를 표시합니다. 이 일반적인 형식은 이어지는 디버깅 시나리오에서 사용됩니다.

   ```
   import sys
   from awsglue.transforms import *
   from awsglue.utils import getResolvedOptions
   from pyspark.context import SparkContext
   from awsglue.context import GlueContext
   from awsglue.job import Job
   import time
   
   ## @params: [JOB_NAME]
   args = getResolvedOptions(sys.argv, ['JOB_NAME'])
   
   sc = SparkContext()
   glueContext = GlueContext(sc)
   spark = glueContext.spark_session
   job = Job(glueContext)
   job.init(args['JOB_NAME'], args)
   
   ...
   ...
   code-to-profile
   ...
   ...
   
   
   job.commit()
   ```

1. 작업을 실행합니다.

1. 지표를 시각화하려면 다음을 수행합니다.

   1. AWS Glue 콘솔에서 작업 지표를 시각화하고 드라이버 또는 실행기의 이상 지표를 식별합니다.

   1. 작업 실행 모니터링 페이지, 작업 실행 세부 정보 페이지 또는 Amazon CloudWatch에서 관찰성 지표를 확인합니다. 자세한 내용은 [AWS Glue 관찰성 메트릭을 사용한 모니터링](monitor-observability.md) 섹션을 참조하세요.

1. 식별된 측정치를 사용하여 근본 원인의 범위를 좁힙니다.

1. 원한다면 식별된 드라이버나 작업 실행기의 로그 스트림을 사용하여 근본 원인을 확인할 수 있습니다.

 **AWS Glue 관찰성 지표의 사용 사례** 
+  [OOM 예외 사항 및 작업 이상 현상 디버깅](monitor-profile-debug-oom-abnormalities.md) 
+  [까다로운 단계와 스트래글러 작업 디버깅](monitor-profile-debug-straggler.md) 
+  [여러 작업의 진행 상황 모니터링](monitor-debug-multiple.md) 
+  [DPU 용량 계획 모니터링](monitor-debug-capacity.md) 
+  [리소스 사용률 모니터링을 위해 AWS Glue 관찰성을 사용하여 비용 절감](https://aws.amazon.com/blogs/big-data/enhance-monitoring-and-debugging-for-aws-glue-jobs-using-new-job-observability-metrics) 

# OOM 예외 사항 및 작업 이상 현상 디버깅
<a name="monitor-profile-debug-oom-abnormalities"></a>

AWS Glue에서 메모리 부족(OOM) 예외 사항 및 작업 이상 현상을 디버깅할 수 있습니다. 다음 단원에서는 Apache Spark 드라이버 또는 Spark 실행기의 메모리 부족 예외 사항을 디버깅하는 시나리오를 설명합니다.
+ [드라이버 OOM 예외 사항 디버깅](#monitor-profile-debug-oom-driver)
+ [실행기 OOM 예외 사항 디버깅](#monitor-profile-debug-oom-executor)

## 드라이버 OOM 예외 사항 디버깅
<a name="monitor-profile-debug-oom-driver"></a>

이 시나리오에서는 Spark 작업이 Amazon Simple Storage Service(Amazon S3)에서 여러 작은 파일을 읽습니다. 파일을 Apache Parquet 포맷으로 변환한 다음 Amazon S3에 씁니다. Spark 드라이버에서 메모리 부족이 발생합니다. 입력 Amazon S3 데이터의 파일 수는 서로 다른 Amazon S3 파티션에 걸쳐 100만개가 넘습니다.

프로파일링된 코드는 다음과 같습니다.

```
data = spark.read.format("json").option("inferSchema", False).load("s3://input_path")
data.write.format("parquet").save(output_path)
```

### AWS Glue 콘솔에서 프로파일링된 지표 시각화
<a name="monitor-debug-oom-visualize"></a>

다음 그래프는 드라이버와 실행기에 대한 메모리 사용률(%)을 표시합니다. 이 사용률은 지난 1분 안에 보고된 값에 대한 평균으로 계산된 데이터 하나로 표시됩니다. [드라이버 메모리](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.jvm.heap.usage)가 50% 사용률의 안전 임계값을 넘는 작업의 메모리 프로필을 볼 수 있습니다. 반면에, 모든 실행기의 [평균 메모리 사용률](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)은 여전히 4%보다 낮습니다. 이로써 이 Spark 작업에서 드라이버 실행에 이상이 있음을 명확히 알 수 있습니다.

![\[드라이버 및 실행기의 메모리 사용률(%).\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-memoryprofile.png)


작업 실행이 곧 실패하고 AWS Glue 콘솔의 [**기록(History)**] 탭에 [종료 코드 1로 명령 실패(Command Failed with Exit Code 1)] 오류가 나타납니다. 이 오류 문자열은 시스템 전체 오류(이 경우 메모리 부족)로 인해 작업이 실패했음을 의미합니다.

![\[AWS Glue 콘솔에 표시된 오류 메시지입니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-errorstring.png)


콘솔의 [**기록(History)**] 탭에서 [**오류 로그(Error logs)**] 링크를 선택하여 CloudWatch Logs에서 드라이버 OOM에 대한 결과를 확인합니다. 작업의 오류 로그에서 "**Error**"를 검색하여 작업 실패의 원인이 된 OOM 예외 사항이 정말 발생했는지 확인합니다.

```
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="kill -9 %p"
# Executing /bin/sh -c "kill -9 12039"...
```

작업에 대해 **기록** 탭에서 **로그**를 선택합니다. 작업의 시작 부분에서 다음과 같은 CloudWatch Logs의 드라이버 실행 추적 정보를 찾아볼 수 있습니다. Spark 드라이버에서 모든 디렉터리의 모든 파일을 나열하려고 했으며, `InMemoryFileIndex`를 생성하고 파일마다 작업 하나를 실행합니다. 이로 인해 Spark 드라이버는 모든 작업을 추적하기 위해 메모리에서 매우 많은 상태를 유지해야 합니다. 따라서 메모리 내 인덱스에 대해 다량의 파일을 포함하는 전체 목록을 캐시하므로 드라이버 OOM이 발생하게 됩니다.

### 그룹화를 사용하여 여러 파일의 처리 수정
<a name="monitor-debug-oom-fix"></a>

AWS Glue의 *그룹화* 기능을 사용하여 여러 파일의 처리를 수정할 수 있습니다. 그룹화는 동적 프레임을 사용할 때와 입력 데이터 세트에 파일 수가 많을 때(50,000개 초과) 자동으로 활성화됩니다. 그룹화를 통해 여러 파일을 그룹 하나로 합칠 수 있으므로 작업 하나로 단일 파일 대신에 전체 그룹을 처리할 수 있습니다. 결과적으로 Spark 드라이버는 메모리 안에 훨씬 더 적은 상태를 저장하여 몇 개 작업만 추적합니다. 데이터 세트에 대한 그룹화 수동 활성화에 대한 자세한 내용은 [입력 파일을 더 큰 그룹에서 읽기](grouping-input-files.md) 단원을 참조하십시오.

AWS Glue 작업의 메모리 프로파일을 확인하려면 그룹화가 활성화된 상태에서 다음과 같은 코드를 프로파일링합니다.

```
df = glueContext.create_dynamic_frame_from_options("s3", {'paths': ["s3://input_path"], "recurse":True, 'groupFiles': 'inPartition'}, format="json")
datasink = glueContext.write_dynamic_frame.from_options(frame = df, connection_type = "s3", connection_options = {"path": output_path}, format = "parquet", transformation_ctx = "datasink")
```

AWS Glue 작업 프로필에서 메모리 프로필 및 ETL 데이터 이동을 모니터링할 수 있습니다.

이 드라이버는 AWS Glue 작업의 전체 기간 동안 메모리 사용량의 50%인 임계값 미만으로 실행됩니다. 실행기가 Amazon S3에서 데이터를 스트리밍하고 처리한 후 Amazon S3에 씁니다. 결과적으로 모든 시점에서 5%보다 적은 양의 메모리가 사용됩니다.

![\[문제를 나타냈던 메모리 프로필이 수정되었습니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-memoryprofile-fixed.png)


아래 데이터 이동 프로파일은 작업이 진행됨에 따라 모든 실행기가 마지막 1분 동안 [읽고](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes) [쓴](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes) 총 Amazon S3 바이트 수를 보여줍니다. 둘 다 모든 실행기에서 데이터가 스트리밍될 때 유사한 패턴을 따릅니다. 이 작업은 세 시간 내에 100만 개에 이르는 모든 파일에 대한 처리를 완료합니다.

![\[문제를 나타냈던 데이터 이동 프로필이 수정되었습니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-etlmovement.png)


## 실행기 OOM 예외 사항 디버깅
<a name="monitor-profile-debug-oom-executor"></a>

이 시나리오에서는 Apache Spark 실행기에서 발생할 수 있는 OOM 예외 사항을 디버깅하는 방법을 알아볼 수 있습니다. 다음 코드는 Spark MySQL 리더를 사용하여 약 3400만개 행으로 이루어진 대형 테이블을 Spark 데이터 프레임으로 읽어 들입니다. 그런 다음 Parquet 포맷으로 Amazon S3에 씁니다. 연결 속성을 제공하고 기본 Spark 구성을 사용하여 테이블을 읽을 수 있습니다.

```
val connectionProperties = new Properties()
connectionProperties.put("user", user)
connectionProperties.put("password", password)
connectionProperties.put("Driver", "com.mysql.jdbc.Driver")
val sparkSession = glueContext.sparkSession
val dfSpark = sparkSession.read.jdbc(url, tableName, connectionProperties)
dfSpark.write.format("parquet").save(output_path)
```

### AWS Glue 콘솔에서 프로파일링된 지표 시각화
<a name="monitor-debug-oom-visualize-2"></a>

메모리 사용량 그래프의 경사가 양수이고 50%를 넘는 경우 다음 지표를 내보내기 전에 작업이 실패하면 메모리 부족이 실패 원인이 될 수 있습니다. 다음 그래프는 1분 실행 기간 내에 모든 실행기의 [평균 메모리 사용률](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)이 50%를 급격하게 초과함을 보여줍니다. 이 사용률은 최대 92%에 도달하며 해당 실행기를 실행 중인 컨테이너가 Apache Hadoop YARN에 의해 중지됩니다.

![\[모든 실행기의 평균 메모리 사용률.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-2-memoryprofile.png)


다음 그래프에서처럼, 작업이 실패할 때까지 항상 [단일 실행기](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberAllExecutors)가 실행 중입니다. 이는 새 실행기가 시작되어 중지된 실행기를 대체하기 때문입니다. JDBC 데이터 원본 읽기는 기본적으로 병렬화되지 않습니다. 그 이유는 한 열에서 테이블을 분할하고 여러 연결을 열어야 하기 때문입니다. 따라서 실행기 하나만 전체 테이블에서 순차적으로 읽혀집니다.

![\[이 작업 실행은 작업이 실패할 때까지 단일 실행기가 실행 중임을 보여줍니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-2-execution.png)


다음 그래프에서처럼, Spark는 작업 실패 전에 새 작업 시작을 4회 시도합니다. 세 개 실행기의 [메모리 프로필](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.used)을 볼 수 있습니다. 각 실행기가 모든 메모리를 신속히 소비합니다. 네 번째 실행기에서 메모리 부족이 발생하여 작업이 실패합니다. 따라서 이 작업의 측정치가 즉시 보고되지 않습니다.

![\[실행기의 메모리 프로필.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-2-exec-memprofile.png)


다음 이미지와 같이, OOM 예외로 인해 작업이 실패했던 AWS Glue 콘솔에서 오류 문자열을 확인할 수 있습니다.

![\[AWS Glue 콘솔에 표시된 오류 메시지입니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-2-errorstring.png)


**작업 출력 로그:** 실행기 OOM 예외 사항의 결과를 추가로 확인하려면 CloudWatch Logs를 살펴봅니다. **Error**를 검색하면 지표 대시보드처럼 거의 동일한 기간 내에 네 개 실행기가 중지됨을 확인할 수 있습니다. 이들 실행기는 메모리 제한을 초과할 때 YARN에 의해 모두 종료됩니다.

실행기 1

```
18/06/13 16:54:29 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:54:29 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:54:29 ERROR YarnClusterScheduler: Lost executor 1 on ip-10-1-2-175.ec2.internal: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:54:29 WARN TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, ip-10-1-2-175.ec2.internal, executor 1): ExecutorLostFailure (executor 1 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

실행기 2

```
18/06/13 16:55:35 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:55:35 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:55:35 ERROR YarnClusterScheduler: Lost executor 2 on ip-10-1-2-16.ec2.internal: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:55:35 WARN TaskSetManager: Lost task 0.1 in stage 0.0 (TID 1, ip-10-1-2-16.ec2.internal, executor 2): ExecutorLostFailure (executor 2 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

실행기 3

```
18/06/13 16:56:37 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:56:37 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:56:37 ERROR YarnClusterScheduler: Lost executor 3 on ip-10-1-2-189.ec2.internal: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:56:37 WARN TaskSetManager: Lost task 0.2 in stage 0.0 (TID 2, ip-10-1-2-189.ec2.internal, executor 3): ExecutorLostFailure (executor 3 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.8 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

실행기 4

```
18/06/13 16:57:18 WARN YarnAllocator: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:57:18 WARN YarnSchedulerBackend$YarnSchedulerEndpoint: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:57:18 ERROR YarnClusterScheduler: Lost executor 4 on ip-10-1-2-96.ec2.internal: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
18/06/13 16:57:18 WARN TaskSetManager: Lost task 0.3 in stage 0.0 (TID 3, ip-10-1-2-96.ec2.internal, executor 4): ExecutorLostFailure (executor 4 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
```

### AWS Glue 동적 프레임을 사용하여 가져오기 크기 설정 수정
<a name="monitor-debug-oom-fix-2"></a>

Spark JDBC 가져오기 크기에 대한 기본 구성이 0이므로 JDBC 테이블을 읽는 동안 실행기에서 메모리 부족이 발생했습니다. 이는 Spark가 한 번에 한 개씩 행을 스트리밍하더라도 Spark 실행기의 JDBC 드라이버가 데이터베이스의 3400만개 행을 함께 가져와서 캐시하려고 함을 의미합니다. Spark에서 가져오기 크기 파라미터를 0 이외의 기본값으로 설정하여 이 시나리오를 방지할 수 있습니다.

또한 AWS Glue 동적 프레임을 대신 사용하여 이 문제를 해결할 수도 있습니다. 기본적으로 동적 프레임에서는 가져오기 크기로 1,000개 행이 사용되는데, 일반적으로 충분한 값입니다. 결과적으로 실행기에 사용되는 메모리의 양이 총 메모리의 7%를 초과하지 않습니다. AWS Glue 작업은 단일 실행기만으로 2분 안에 완료됩니다. AWS Glue 동적 프레임을 사용하는 것이 권장되는 접근 방식이지만, Apache Spark `fetchsize` 속성을 사용하여 가져오기 크기를 설정할 수도 있습니다. [Spark SQL, DataFrames 및 데이터 세트 가이드](https://spark.apache.org/docs/2.2.0/sql-programming-guide.html#jdbc-to-other-databases)를 참조하십시오.

```
val (url, database, tableName) = {
 ("jdbc_url", "db_name", "table_name")
 } 
val source = glueContext.getSource(format, sourceJson)
val df = source.getDynamicFrame
glueContext.write_dynamic_frame.from_options(frame = df, connection_type = "s3", connection_options = {"path": output_path}, format = "parquet", transformation_ctx = "datasink")
```

**정상 프로파일링된 측정치:** [실행기 메모리](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.jvm.heap.usage)(AWS Glue 동적 프레임 사용)가 다음 이미지와 같이 안전 임곗값을 절대로 초과하지 않습니다. 데이터베이스에서 행을 읽고 어느 시점에든 JDBC 드라이버에 1,000개 행만 캐시합니다. 메모리 부족 예외는 발생하지 않습니다.

![\[안전 임곗값보다 낮은 실행기 메모리를 보여주는 AWS Glue 콘솔입니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-oom-2-memoryprofile-fixed.png)


# 까다로운 단계와 스트래글러 작업 디버깅
<a name="monitor-profile-debug-straggler"></a>

AWS Glue 작업 프로파일링을 사용하여 추출, 변환 및 로드(ETL) 작업에서 까다로운 단계와 스트래글러 작업을 식별할 수 있습니다. 스트래글러 작업은 AWS Glue 작업의 단계에서 나머지 작업보다 더 오래 걸립니다. 따라서 해당 단계를 완료하는 데 더 오래 걸리므로 작업의 총 실행 시간도 지연됩니다.

## 작은 입력 파일을 큰 출력 파일로 병합
<a name="monitor-profile-debug-straggler-scenario-1"></a>

스트래글러 작업은 여러 작업들 간에 작업량이 균일하지 않게 배포되거나, 데이터 스큐로 인해 한 작업에서 더 많은 데이터를 처리하는 경우에 발생할 수 있습니다.

다음 코드(Apache Spark의 일반 패턴)를 프로파일링하여 다량의 작은 파일을 큰 출력 파일로 병합할 수 있습니다. 예를 들면, 입력 데이터 세트는 JSON Gzip 압축 파일 32GB입니다. 출력 데이터 세트는 거의 190GB에 이르는 압축되지 않은 JSON 파일입니다.

프로파일링된 코드는 다음과 같습니다.

```
datasource0 = spark.read.format("json").load("s3://input_path")
df = datasource0.coalesce(1)
df.write.format("json").save(output_path)
```

### AWS Glue 콘솔에서 프로파일링된 지표 시각화
<a name="monitor-debug-straggler-visualize"></a>

작업을 프로파일링하여 네 가지 지표 세트를 살펴볼 수 있습니다.
+ ETL 데이터 이동
+ 실행기 간의 데이터 셔플
+ 작업 실행
+ 메모리 프로필

**ETL 데이터 이동**: **ETL 데이터 이동** 프로필에서는 처음 6분 안에 완료되는 첫 번째 단계에서 모든 실행기가 바이트를 매우 빠르게 [읽습니다](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes). 하지만 총 작업 실행 시간은 거의 1시간으로, 이 시간 중 대부분을 데이터 [쓰기](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes)가 차지합니다.

![\[ETL 데이터 이동 프로필을 보여주는 그래프.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-1.png)


**실행기 간 데이터 셔플:** 셔플링 중에 [읽고](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.shuffleLocalBytesRead) [쓴](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.shuffleBytesWritten) 바이트 수도 [**작업 실행(Job Execution)**] 및 [**데이터 셔플(Data Shuffle)**] 지표에서 알 수 있듯이 2단계가 끝나기 전 스파이크를 나타냅니다. 모든 실행기의 데이터 셔플 후에는 실행기 번호 3에서만 읽기 및 쓰기가 진행됩니다.

![\[실행기 간의 데이터 셔플 측정치.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-2.png)


**작업 실행:** 아래 그래프와 같이, 다른 모든 실행기는 유휴 상태이며 최종적으로 10:09에 중지됩니다. 이 시점에는 총 실행기 수가 1로 감소됩니다. 이는 실행기 번호 3이 실행 시간이 가장 오래 걸리고 작업 실행 시간의 대부분을 차지하는 스트래글러 작업으로 이루어짐을 보여줍니다.

![\[활성 실행기의 실행 측정치.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-3.png)


**메모리 프로필:** 처음 두 단계 이후에는 [실행기 번호 3](monitoring-awsglue-with-cloudwatch-metrics.md#glue.executorId.jvm.heap.used)에서 메모리를 적극적으로 소비하며 데이터를 처리합니다. 나머지 실행기는 단순 유휴 상태이거나 처음 두 단계가 완료되고 나서 잠시 후에 중지되었습니다.

![\[처음 두 단계 이후의 메모리 프로필 측정치.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-4.png)


### 그룹화를 사용하여 스트래글링 실행기 수정
<a name="monitor-debug-straggler-fix"></a>

AWS Glue의 *그룹화* 기능을 사용하면 실행기가 뒤처지는 것을 방지할 수 있습니다. 그룹화를 사용하면 데이터를 모든 실행기에 균일하게 분포하고 클러스터의 모든 사용 가능한 실행기를 사용하여 파일을 더 큰 파일로 병합할 수 있습니다. 자세한 내용은 [입력 파일을 더 큰 그룹에서 읽기](grouping-input-files.md) 섹션을 참조하세요.

AWS Glue 작업의 ETL 데이터 이동을 확인하려면 그룹화가 활성화된 상태에서 다음과 같은 코드를 프로파일링합니다.

```
df = glueContext.create_dynamic_frame_from_options("s3", {'paths': ["s3://input_path"], "recurse":True, 'groupFiles': 'inPartition'}, format="json")
datasink = glueContext.write_dynamic_frame.from_options(frame = df, connection_type = "s3", connection_options = {"path": output_path}, format = "json", transformation_ctx = "datasink4")
```

**ETL 데이터 이동:** 이제 작업 실행 시간 전체에 걸쳐 데이터 쓰기와 데이터 읽기를 병렬로 스트리밍합니다. 따라서 작업이 8분(이전보다 훨씬 빠름) 내에 완료됩니다.

![\[문제를 나타냈던 ETL 데이터 이동이 수정되었습니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-5.png)


**실행기 간의 데이터 셔플:** 입력 파일이 그룹화 기능을 사용하여 읽는 동안 병합되므로 데이터를 읽은 후에 비용이 많이 들던 데이터 셔플이 발생하지 않습니다.

![\[문제를 나타냈던 데이터 셔플 측정치가 수정되었습니다.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-6.png)


**작업 실행:** 작업 실행 측정치는 데이터 실행 및 처리 중인 총 활성 실행기 수가 상당히 일관되게 유지됨을 보여줍니다. 작업에 단일 스트래글러가 없습니다. 모든 실행기가 활성 상태이며 작업이 완료될 때까지 활성 상태로 유지됩니다. 실행기 간에 중간 데이터 셔플이 없으므로 작업에 단일 단계만 존재합니다.

![\[작업에 스트래글러가 없음을 보여주는 작업 실행 위젯의 측정치.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-7.png)


**메모리 프로파일:** 이 지표는 모든 실행기의 [활성 메모리 소비](monitoring-awsglue-with-cloudwatch-metrics.md#glue.executorId.jvm.heap.used)를 표시하여 모든 실행기에서 활동이 존재함을 재확인합니다. 데이터가 동시에 스트리밍되고 작성되므로, 모든 실행기의 총 메모리 공간이 모든 실행기의 안전 임계값보다 훨씬 낮고 거의 균일합니다.

![\[모든 실행기에서 활성 메모리 소비를 보여주는 메모리 프로필 측정치.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-straggler-8.png)


# 여러 작업의 진행 상황 모니터링
<a name="monitor-debug-multiple"></a>

여러 AWS Glue 작업을 함께 프로파일링하고 작업 간에 데이터 흐름을 모니터링할 수 있습니다. 이 모니터링은 일반적인 워크플로우 패턴으로, 개별 작업 진행 상황, 데이터 처리 백로그, 데이터 재처리 및 작업 북마크를 모니터링해야 합니다,

**Topics**
+ [프로파일링된 코드](#monitor-debug-multiple-profile)
+ [AWS Glue 콘솔에서 프로파일링된 지표 시각화](#monitor-debug-multiple-visualize)
+ [파일 처리 수정](#monitor-debug-multiple-fix)

## 프로파일링된 코드
<a name="monitor-debug-multiple-profile"></a>

이 워크플로우에는 두 가지 작업, 즉 입력 작업과 출력 작업이 있습니다. 입력 작업은 정기 트리거를 사용하여 30분마다 실행하도록 예약되어 있습니다. 출력 작업은 입력 작업의 각각의 성공적인 실행 이후에 실행하도록 예약되어 있습니다. 이러한 예약된 작업은 작업 트리거를 사용하여 제어됩니다.

![\[입력 및 출력 작업 예약을 제어하는 작업 트리거를 보여주는 콘솔 스크린샷.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-1.png)


**입력 작업**: 이 작업은 Amazon Simple Storage Service(Amazon S3) 위치에서 데이터를 읽고 `ApplyMapping`을 사용하여 변환한 다음, 스테이징 Amazon S3 위치에 씁니다. 다음 코드는 입력 작업용으로 프로파일링된 코드입니다.

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": ["s3://input_path"], "useS3ListImplementation":True,"recurse":True}, format="json")
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [map_spec])
datasink2 = glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": staging_path, "compression": "gzip"}, format = "json")
```

**출력 작업**: 이 작업은 Amazon S3의 스테이징 위치에서 입력 작업의 출력을 읽고. 다시 변환한 다음, 대상에 씁니다.

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": [staging_path], "useS3ListImplementation":True,"recurse":True}, format="json")
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [map_spec])
datasink2 = glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": output_path}, format = "json")
```

## AWS Glue 콘솔에서 프로파일링된 지표 시각화
<a name="monitor-debug-multiple-visualize"></a>

다음 대시보드는 출력 작업에 대한 동일한 타임라인에서 입력 작업의 Amazon S3 바이트 쓰기 지표를 Amazon S3 바이트 읽기 지표에 중첩합니다. 이 타임라인은 입력 작업과 출력 작업의 서로 다른 작업 실행을 보여줍니다. 입력 작업(빨간색으로 표시됨)이 30분마다 시작됩니다. 출력 작업(갈색으로 표시됨)은 입력 작업 완료 시 시작되며, 최대 동시성은 1입니다.

![\[읽고 쓴 데이터를 표시하는 그래프.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-4.png)


이 예에서는, [작업 북마크](https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html)가 활성화되지 않습니다. 변환 컨텍스트를 사용하여 스크립트 코드에서 작업 북마크를 활성화하지 않습니다.

**작업 기록**: 입력 및 출력 작업은 오후 12:00부터 시작되는 **기록** 탭에서처럼 여러 번 실행되었습니다.

AWS Glue 콘솔의 입력 작업은 다음과 같습니다.

![\[입력 작업의 기록 탭을 표시하는 콘솔 스크린샷.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-2.png)


다음 이미지는 출력 작업을 보여줍니다.

![\[출력 작업의 기록 탭을 표시하는 콘솔 스크린샷.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-3.png)


**첫 번째 작업 실행**: 아래 읽고 쓴 데이터 바이트 그래프에서처럼, 12:00 \$1 12:30의 입력 및 출력 작업의 첫 번째 작업 실행은 거의 동일한 곡선하 면적을 보입니다. 이 면적은 입력 작업에서 쓴 Amazon S3 바이트와 출력 작업에서 읽은 Amazon S3 바이트를 나타냅니다. 또한 이 데이터는 작성된 Amazon S3 바이트의 비율(30분 동안의 합계 - 입력 작업의 경우 작업 트리거 빈도)로 확인됩니다. 오후 12:00에 시작된 입력 작업 비율의 데이터 지점도 1입니다.

다음 그래프는 모든 작업 실행에 대한 데이터 흐름 비율을 보여줍니다.

![\[데이터 흐름 비율을 보여주는 그래프: 쓴 바이트와 읽은 바이트\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-5.png)


**두 번째 작업 실행**: 두 번째 작업 실행에서 입력 작업에서 쓴 바이트 수와 출력 작업에서 읽은 바이트 수 사이에는 명확한 차이가 있습니다. (출력 작업에 대한 두 작업 실행의 곡선하 면적을 비교하거나, 입력 작업과 출력 작업의 두 번째 실행 시 면적을 비교합니다.) 읽은 바이트 수와 쓴 바이트 수의 비율은 12:30 \$1 13:00의 두 번째 기간인 30분 동안 입력 작업에 의해 작성된 데이터의 약 2.5배를 출력 작업에서 읽었음을 보여줍니다. 이는 작업 북마크가 활성화되지 않았기 때문에 출력 작업이 입력 작업의 첫 번째 작업 실행에서 나오는 출력을 재처리하기 때문입니다. 비율이 1보다 크면 출력 작업에 의해 데이터의 추가 백로그가 처리되었음을 의미합니다.

**세 번째 작업 실행**: 입력 작업은 작성된 바이트 수 면에서 일관성이 거의 유지됩니다(빨간색 곡선하 면적 참조). 하지만, 입력 작업의 세 번째 작업 실행 시간이 예상보다 더 길어졌습니다(빨간색 곡선의 긴 후미부 참조). 결과적으로 출력 작업의 세 번째 작업 실행이 늦게 시작되었습니다. 세 번째 작업은 13:00 \$1 13:30의 나머지 30분 동안 스테이징 위치에 누적된 데이터 부분만 처리했습니다. 바이트 흐름의 비율은 입력 작업의 세 번째 작업 실행에 의해 작성된 데이터의 0.83만 처리되었음을 보여줍니다(13:00의 비율 참조).

**입력 작업과 출력 작업의 중첩**: 입력 작업의 네 번째 작업 실행이 출력 작업의 세 번째 작업 실행이 완료되기 전에 일정에 따라 13:30에 시작되었습니다. 두 작업 실행 사이에 약간의 중첩 부분이 있습니다. 하지만, 출력 작업의 세 번째 작업 실행은 약 13:17에 시작되었을 때 Amazon S3의 스테이징 위치에 나열되어 있는 파일만 캡처합니다. 캡처 데이터는 입력 작업의 첫 번째 작업 실행에서 얻은 모든 데이터 출력으로 구성됩니다. 13:30에서 실제 비율은 약 2.75입니다. 출력 작업의 세 번째 작업 실행에서는 13:30\$114:00의 입력 작업 중 네 번째 작업 실행에서 작성된 데이터의 약 2.75x를 처리했습니다.

이러한 이미지에 표시된 바와 같이, 출력 작업은 입력 작업에 대한 모든 이전 작업 실행의 스테이징 위치부터 데이터를 처리하고 있습니다. 결과적으로, 출력 작업에 대한 네 번째 작업 실행이 가장 길며 입력 작업의 전체 다섯 번째 작업 실행과 겹칩니다.

## 파일 처리 수정
<a name="monitor-debug-multiple-fix"></a>

출력 작업에서 출력 작업의 이전 작업 실행에 의해 처리되지 않은 파일만 처리하도록 해야 합니다. 이렇게 하려면 다음과 같이 출력 작업에서 작업 북마크를 활성화하고 변환 컨텍스트를 설정합니다.

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": [staging_path], "useS3ListImplementation":True,"recurse":True}, format="json", transformation_ctx = "bookmark_ctx")
```

작업 북마크를 활성화한 상태에서는 출력 작업이 입력 작업에 대한 모든 이전 작업 실행의 스테이징 위치에 있는 데이터를 재처리하지 않습니다. 읽고 쓴 데이터를 보여주는 다음 이미지에서는 갈색 곡선하 면적이 상당히 일관되며 빨간 곡선과 비슷합니다.

![\[읽은 데이터와 쓴 데이터를 빨간색 선과 갈색 선으로 표시하는 그래프.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-6.png)


추가 데이터 처리가 없으므로 바이트 흐름의 비율도 거의 1에 가깝게 유지됩니다.

![\[데이터 흐름 비율을 보여주는 그래프: 쓴 바이트와 읽은 바이트\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-7.png)


다음 입력 작업 실행이 시작되기 전에 출력 작업에 대한 작업 실행이 시작되고 스테이징 위치에 있는 파일을 캡처하여 더 많은 데이터를 스테이징 위치에 넣습니다. 이 작업이 계속되는 동안은 이전 입력 작업 실행에서 캡처한 파일만 처리되며 비율이 계속 1에 가깝게 유지됩니다.

![\[데이터 흐름 비율을 보여주는 그래프: 쓴 바이트와 읽은 바이트\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-multiple-7.png)


입력 작업이 예상보다 길어지며, 그 결과로서 출력 작업이 두 입력 작업 실행의 스테이징 위치에 있는 파일을 캡처한다고 가정해 보겠습니다. 그러면 해당 출력 작업 실행에 대해 비율이 1보다 높습니다. 하지만, 출력 작업의 다음 작업 실행에서는 출력 작업의 이전 작업 실행에 의해 이미 처리된 파일이 하나도 처리되지 않습니다.

# DPU 용량 계획 모니터링
<a name="monitor-debug-capacity"></a>

AWS Glue의 작업 측정치를 사용하여 AWS Glue 작업을 확장하는 데 사용할 수 있는 데이터 처리 단위(DPU) 수를 추정할 수 있습니다.

**참고**  
이 페이지는 AWS Glue 버전 0.9 및 1.0에만 적용됩니다. 최신 버전의 AWS Glue에는 용량 계획 시 추가 고려 사항을 적용하는 비용 절감 기능이 포함되어 있습니다.

**Topics**
+ [프로파일링된 코드](#monitor-debug-capacity-profile)
+ [AWS Glue 콘솔에서 프로파일링된 지표 시각화](#monitor-debug-capacity-visualize)
+ [최적 DPU 용량 결정](#monitor-debug-capacity-fix)

## 프로파일링된 코드
<a name="monitor-debug-capacity-profile"></a>

다음 스크립트는 428개의 gzip 압축된 JSON 파일을 포함하는 Amazon Simple Storage Service(Amazon S3) 파티션을 읽습니다. 이 스크립트는 필드 이름에 변경할 매핑을 적용하고 변환한 후 다시 Amazon S3에 Apache Parquet 포맷으로 씁니다. 기본값에 따라 10개 DPU를 프로비저닝하고 이 작업을 실행할 수 있습니다.

```
datasource0 = glueContext.create_dynamic_frame.from_options(connection_type="s3", connection_options = {"paths": [input_path], "useS3ListImplementation":True,"recurse":True}, format="json")
applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [(map_spec])
datasink2 = glueContext.write_dynamic_frame.from_options(frame = applymapping1, connection_type = "s3", connection_options = {"path": output_path}, format = "parquet")
```

## AWS Glue 콘솔에서 프로파일링된 지표 시각화
<a name="monitor-debug-capacity-visualize"></a>

**작업 실행 1:** 이 작업 실행에서는 클러스터에서 부족 프로비저닝된 DPU가 있는지 알아보는 방법을 보여줍니다. AWS Glue의 작업 실행 기능은 [능동적으로 실행 중인 총 실행기 수](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberAllExecutors), [완료된 단계 수](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.aggregate.numCompletedStages), 그리고 [최대 필요 실행기 수](monitoring-awsglue-with-cloudwatch-metrics.md#glue.driver.ExecutorAllocationManager.executors.numberMaxNeededExecutors)를 표시합니다.

최대 필요 실행기 수는 총 실행 중인 작업 수와 보류 작업 수를 합한 다음 실행기당 작업 수로 나누어서 계산합니다. 이 결과는 현재 부하를 충족하는 데 필요한 총 실행기 수를 나타내는 측정치입니다.

이와는 대조적으로, 능동적으로 실행 중인 실행기 수는 활성 Apache Spark 작업을 실행 중인 실행기 수를 측정합니다. 작업이 진행됨에 따라 최대 필요 실행기가 변경될 수 있으며 일반적으로 보류 작업 대기열이 축소되면서 작업 완료에 가까워질수록 줄어듭니다.

다음 그래프의 가로 빨간색 선은 최대 할당 실행기 수를 표시하며, 이는 작업에 할당하는 DPU 수에 따라 달라집니다. 이 경우, 작업 실행에 대해 10개 DPU를 할당합니다. 하나의 DPU는 관리용으로 예약되어 있습니다. 9개 DPU가 각각 실행기 두 개를 실행하며 실행기 하나가 Spark 드라이버용으로 예약되어 있습니다. Spark 드라이버는 기본 애플리케이션에서 실행됩니다. 그러므로 최대 할당 실행기 수는 2\$19 - 1 = 17개입니다.

![\[활성 실행기 및 최대 필요 실행기를 표시하는 작업 측정치.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-capacity-1.png)


그래프가 표시될 때, 최대 필요 실행기 수는 작업 시작 시 107로 시작하지만, 활성 실행기 수는 17개로 유지됩니다. 이 개수는 DPU 수가 10개인 최대 할당 실행기 수와 동일합니다. 최대 필요 실행기 수와 최대 할당 실행기 수 간의 비율(Spark 드라이버에 대해 두 수치에 모두 1을 더함)은 부족 프로비저닝 계수를 제공합니다. 즉, 108/18 = 6x. 최대 병렬화로 실행하고 더 빨리 완료하도록 작업을 확장하기 위해 6(언더프로비저닝 비율)\$19(현재 DPU 용량 - 1) \$1 DPU 1개 = DPU 55개를 프로비저닝할 수 있습니다.

AWS Glue 콘솔은 자세한 작업 지표를 원래 할당된 최대 실행기 수를 나타내는 정적 행으로 표시합니다. 이 콘솔은 지표에 대한 작업 정의에서 할당된 최대 실행기를 계산합니다. 반면 자세한 작업 실행 지표의 경우 이 콘솔은 작업 실행 구성에서 할당된 최대 실행기, 특히 작업 실행에 대해 할당된 DPU를 계산합니다. 개별 작업 실행에 대한 지표를 보려면 작업 실행을 선택하고 **View run metrics(실행 지표 보기)**를 선택합니다.

![\[ETL 데이터 이동을 표시하는 작업 측정치\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-capacity-2.png)


[읽고](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.read_bytes) [쓴](monitoring-awsglue-with-cloudwatch-metrics.md#glue.ALL.s3.filesystem.write_bytes) Amazon S3 바이트를 살펴보면 작업이 Amazon S3에서 데이터를 스트리밍하고 병렬로 쓰는 데 6분을 모두 소비함을 알 수 있습니다. 할당된 DPU의 모든 코어가 Amazon S3에(서) 읽고 쓰고 있습니다. 최대 필요 실행기 수(107)는 입력 Amazon S3 경로의 파일 수(428)와도 일치합니다. 각 실행기는 Spark 작업 네 개를 시작하여 네 개 입력 파일(JSON gzip 압축됨)을 처리할 수 있습니다.

## 최적 DPU 용량 결정
<a name="monitor-debug-capacity-fix"></a>

이전 작업 실행 결과에 따라, 총 할당된 DPU 수를 55로 늘리고 작업이 어떻게 수행되는지 알아볼 수 있습니다. 작업이 이전 소요 시간의 절반에 해당하는 3분 이내에 완료됩니다. 단기 실행 작업이므로 이 경우에는 작업 확장이 선형적이지 않습니다. 장기 지속 작업이나 다량의 작업을 포함하는 작업(최대 필요 실행기 수가 많음)은 선형에 가까운 DPU 확장 성능 가속화가 도움이 됩니다.

![\[총 할당 DPU 수 증가를 보여주는 그래프\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-capacity-3.png)


위 이미지에서 볼 수 있듯이 활성 실행기의 총 수는 할당된 최대값인 107개에 도달합니다. 마찬가지로, 최대 필요 실행기는 최대 할당 실행기 수보다 절대 높지 않습니다. 최대 필요 실행기 수는 능동적으로 실행 중인 작업 수와 보류 중인 작업 수에서 계산되므로 활성 실행기 수보다 작을 수도 있습니다. 이는 짧은 시간 동안 부분적으로 또는 전체적으로 유휴 상태이거나 아직 폐기되지 않은 실행기가 있을 수 있기 때문입니다.

![\[총 활성 실행기 수가 최대 할당 개수에 도달함을 보여주는 그래프\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-capacity-4.png)


이 작업 실행은 6x 이상의 실행기를 사용하여 Amazon S3에서 데이터를 동시에 읽고 씁니다. 결과적으로 이 작업은 읽기 및 쓰기에 모두 더 많은 Amazon S3 대역폭을 사용하여 더 빨리 완료합니다.

### 과다 프로비저닝된 DPU 식별
<a name="monitor-debug-capacity-over"></a>

다음에는, DPU가 100개(99 \$1 2 = 198개 실행기)인 작업을 확장하는 것이 성능을 향상하는 데 도움이 되는지 여부를 결정할 수 있습니다. 다음 그래프와 같이, 작업을 완료하는 데 여전히 3분이 걸립니다. 마찬가지로, 이 작업은 실행기를 107 개 이상(55개 DPU 구성)으로 확장하지 않으며, 남은 91개 실행기가 과다 프로비저닝되고 전혀 사용되지 않습니다. 이는 최대 필요 실행기 수에서 분명히 알 수 있듯이 DPU 수를 늘리는 것이 항상 성능을 향상시키지는 않을 수도 있음을 보여줍니다.

![\[DPU 수를 늘리는 것이 작업 성능을 항상 향상시키지는 않음을 보여주는 그래프.\]](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/monitor-debug-capacity-5.png)


### 시간차 비교
<a name="monitor-debug-capacity-time"></a>

다음 표에 나와 있는 세 가지 작업 실행은 10개 DPU, 55개 DPU 및 100개 DPU에 대한 작업 실행 시간을 요약한 것입니다. 첫 번째 작업 실행을 모니터링함으로써 설정한 추정치를 사용하여 작업 실행 시간을 개선할 DPU 용량을 찾아낼 수 있습니다.


| 작업 ID | DPU 수 | 실행 시간 | 
| --- | --- | --- | 
| jr\$1c894524c8ef5048a4d9... | 10 | 6분 | 
| jr\$11a466cf2575e7ffe6856... | 55 | 3분 | 
| jr\$134fa1ed4c6aa9ff0a814... | 100 | 3분 | 