

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

# Kinesis Client Library 사용
<a name="kcl"></a>

## Kinesis Client Library란?
<a name="kcl-library-what-is"></a>

Kinesis Client Library(KCL)는 Amazon Kinesis Data Streams에서 데이터를 사용하고 처리하는 프로세스를 간소화하도록 설계된 독립형 Java 소프트웨어 라이브러리입니다. KCL은 분산 컴퓨팅과 관련된 많은 복잡한 작업을 처리하므로 개발자는 데이터 처리를 위한 비즈니스 로직을 구현하는 데 집중할 수 있습니다. 여러 워커 간의 로드 밸런싱, 워커 실패 문제에 대한 응답, 처리된 레코드의 체크포인트 지정, 스트림의 샤드 수 변경에 대한 응답과 같은 활동을 관리합니다.

KCL은 기본 라이브러리의 최신 버전, 보안 개선 사항, 버그 수정을 통합하도록 자주 업데이트됩니다. 알려진 문제를 방지하고 모든 최신 개선 사항을 활용하려면 최신 버전의 KCL을 사용하는 것이 좋습니다. 최신 KCL 버전을 찾으려면 [KCL Github](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요.

**중요**  
알려진 버그와 문제를 방지하려면 최신 KCL 버전을 사용하는 것이 좋습니다. KCL 2.6.0 이하를 사용하는 경우 스트림 용량이 변경될 때 샤드 처리를 차단할 수 있는 드문 상황을 방지하려면 KCL 2.6.1 이상으로 업그레이드하세요.
KCL은 Java 라이브러리입니다. MultiLangDaemon이라는 Java 기반 대몬을 통해 Java 이외의 언어를 지원합니다. MultiLangDaemon은 STDIN 및 STDOUT을 통해 KCL 애플리케이션과 상호 작용합니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [비 Java 언어로 KCL을 사용하여 소비자 개발](develop-kcl-consumers-non-java.md) 섹션을 참조하세요.
KCL 3.x에서는 AWS SDK for Java 버전 2.27.19\$12.27.23을 사용하지 마십시오. 이러한 버전에는 KCL의 DynamoDB 사용과 관련된 예외 오류가 발생하는 문제가 포함되어 있습니다. 이 문제를 방지하려면 AWS SDK for Java 버전 2.28.0 이상을 사용하는 것이 좋습니다.

## KCL의 주요 기능 및 이점
<a name="kcl-benefits"></a>

KCL의 주요 기능 및 관련 이점은 다음과 같습니다.
+ **확장성**: KCL을 사용하면 여러 워커에 처리 로드를 분산하여 애플리케이션을 동적으로 확장할 수 있습니다. 수동 또는 자동 크기 조정을 통해 애플리케이션을 확장하거나 축소할 수 있으며 로드 재분배를 걱정할 필요가 없습니다.
+ **로드 밸런싱**: KCL은 사용 가능한 워커 간에 처리 로드의 균형을 자동으로 조정하여 워커 간에 작업을 균등하게 분산합니다.
+ **체크포인트**: KCL은 처리된 레코드의 체크포인트를 관리하여 애플리케이션이 마지막으로 성공적으로 처리된 위치에서 처리를 재개할 수 있도록 합니다.
+ **내결함성**: KCL은 내장된 내결함성 메커니즘을 제공하여 개별 워커가 실패하더라도 데이터 처리가 계속되도록 합니다. KCL은 at-least-once 전송도 제공합니다.
+ **스트림 수준 변경 처리**: KCL은 데이터 볼륨 변경으로 인해 발생할 수 있는 샤드 분할 및 병합에 적응합니다. 상위 샤드가 완료되고 체크포인트가 지정된 후에만 하위 샤드가 처리되게 하여 순서를 유지합니다.
+ **모니터링**: KCL은 소비자 수준 모니터링을 위해 Amazon CloudWatch와 통합됩니다.
+ **다중 언어 지원**: KCL은 기본적으로 Java를 지원하며 MultiLangDaemon을 통해 여러 비 Java 프로그래밍 언어를 활성화합니다.

# KCL 개념
<a name="kcl-concepts"></a>

이 섹션에서는 Kinesis Client Library(KCL)의 핵심 개념과 상호 작용을 설명합니다. 이러한 개념은 KCL 소비자 애플리케이션을 개발하고 관리하는 데 필수적입니다.
+ **KCL 소비자 애플리케이션** - Kinesis Client Library를 사용하여 Kinesis Data Streams에서 레코드를 읽고 처리하도록 설계된 사용자 지정 구축 애플리케이션입니다.
+ **워커** - KCL 소비자 애플리케이션은 일반적으로 분산된 형태이며 하나 이상의 워커가 동시에 동작합니다. KCL은 분산 방식으로 스트림의 데이터를 소비하도록 워커를 조정하고 여러 워커에 로드를 균등하게 분산합니다.
+ **스케줄러** - KCL 워커가 데이터 처리를 시작하는 데 사용하는 상위 수준 클래스입니다. 각 KCL 워커에 하나의 스케줄러가 있습니다. 스케줄러는 Kinesis Data Streams에서 샤드 정보 동기화, 워커 간 샤드 할당 추적, 워커에 할당된 샤드를 기반으로 스트림 데이터 처리 등 다양한 작업을 초기화하고 감독합니다. 스케줄러는 처리할 스트림의 이름, AWS 자격 증명과 같이 스케줄러의 동작에 영향을 미치는 다양한 구성을 수행할 수 있습니다. 스케줄러는 스트림에서 레코드 프로세서로 데이터 레코드 전송을 시작합니다.
+ **레코드 프로세서** - KCL 소비자 애플리케이션이 데이터 스트림에서 가져온 데이터를 처리하는 로직을 정의합니다. 레코드 프로세서에서 자체 사용자 지정 데이터 처리 로직을 구현해야 합니다. KCL 워커가 스케줄러를 인스턴스화합니다. 그런 다음 스케줄러는 리스를 보유한 샤드 각각에 대해 하나의 레코드 프로세서를 인스턴스화합니다. 한 워커가 여러 레코드 프로세서를 실행할 수 있습니다.
+ **리스** - 워커와 샤드 간의 할당을 정의합니다. KCL 소비자 애플리케이션은 리스를 사용하여 여러 워커에 데이터 레코드 처리를 분산합니다. 각 샤드는 특정 시점에 리스에 의해 한 워커에게만 바인딩되며 각 워커는 하나 이상의 리스를 동시에 보유할 수 있습니다. 중지 또는 실패로 인해 워커가 리스 보유를 중지하면 KCL이 다른 워커에 리스를 할당합니다. 리스에 대한 자세한 내용은 [Github 설명서: Lease Lifecycle](https://github.com/awslabs/amazon-kinesis-client/blob/master/docs/lease-lifecycle.md#lease-lifecycle) 섹션을 참조하세요.
+ **리스 테이블** - KCL 소비자 애플리케이션의 모든 리스를 추적하는 데 사용되는 고유한 Amazon DynamoDB 테이블입니다. 각 KCL 소비자 애플리케이션은 자체 리스 테이블을 생성합니다. 리스 테이블은 모든 워커의 상태를 유지하여 데이터 처리를 조정하는 데 사용됩니다. 자세한 내용은 [KCL의 DynamoDB 메타데이터 테이블 및 로드 밸런싱](kcl-dynamoDB.md) 단원을 참조하십시오.
+ **체크포인트** - 마지막으로 성공적으로 처리된 레코드의 위치를 샤드에 지속적으로 저장하는 프로세스입니다. KCL은 워커가 실패하거나 애플리케이션이 다시 시작되는 경우 마지막 체크포인트 위치에서 처리를 재개할 수 있도록 체크포인트를 관리합니다. 체크포인트는 리스 메타데이터의 일부로 DynamoDB 리스 테이블에 저장됩니다. 이를 통해 워커는 이전 워커가 중지한 위치에서 계속 처리할 수 있습니다.

# KCL의 DynamoDB 메타데이터 테이블 및 로드 밸런싱
<a name="kcl-dynamoDB"></a>

KCL은 워커의 리스 및 CPU 사용률 지표와 같은 메타데이터를 관리합니다. KCL은 DynamoDB 테이블을 사용하여 이러한 메타데이터를 추적합니다. 각 Amazon Kinesis Data Streams 애플리케이션에 대해 KCL은 메타데이터 관리를 위해 리스 테이블, 워커 지표 테이블, 조정자 상태 테이블이라는 세 개의 DynamoDB 테이블을 생성합니다.

**참고**  
KCL 3.x에는 *워커 지표*와 *조정자 상태* 테이블이라는 두 가지 새로운 메타데이터 테이블이 도입되었습니다.

**중요**  
 DynamoDB에서 메타데이터 테이블을 생성하고 관리하려면 KCL 애플리케이션에 적절한 권한을 추가해야 합니다. 자세한 내용은 [KCL 소비자 애플리케이션에 필요한 IAM 권한](kcl-iam-permissions.md)을 참조하세요.  
KCL 소비자 애플리케이션은 이 세 가지 DynamoDB 메타데이터 테이블을 자동으로 제거하지 않습니다. 불필요한 비용을 방지하기 위해 소비자 애플리케이션을 폐기할 때 KCL 소비자 애플리케이션에서 생성한 이러한 DynamoDB 메타데이터 테이블을 제거해야 합니다.

## 리스 테이블
<a name="kcl-leasetable"></a>

리스 테이블은 KCL 소비자 애플리케이션의 스케줄러가 리스하고 처리 중인 샤드를 추적하는 데 사용되는 고유한 Amazon DynamoDB 테이블입니다. 각 KCL 소비자 애플리케이션은 자체 리스 테이블을 생성합니다. KCL은 기본적으로 소비자 애플리케이션의 이름을 리스 테이블 이름으로 사용합니다. 구성을 사용하여 사용자 지정 테이블 이름을 설정할 수 있습니다. 또한 KCL은 효율적인 리스 검색을 위해 파티션 키 leaseOwner를 사용하여 리스 테이블에 [글로벌 보조 인덱스](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html)를 생성합니다. 글로벌 보조 인덱스는 기본 리스 테이블의 leaseKey 속성을 미러링합니다. 애플리케이션이 시작될 때 KCL 소비자 애플리케이션에 대한 리스 테이블이 없는 경우 워커 중 하나가 이 애플리케이션에 대한 리스 테이블을 생성합니다.

소비자 애플리케이션이 실행되는 동안 [Amazon DynamoDB 콘솔](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ConsoleDynamoDB.html)을 사용하여 리스 테이블을 볼 수 있습니다.

**중요**  
각 KCL 소비자 애플리케이션 이름은 리스 테이블 이름의 중복을 방지하기 위해 고유해야 합니다.
Kinesis Data Streams 자체와 관련된 비용 외에도 DynamoDB 테이블 관련 비용이 계정에 청구됩니다.

리스 테이블의 각 행은 소비자 애플리케이션의 스케줄러가 처리 중인 샤드를 나타냅니다. 주요 필드는 다음과 같습니다.
+ **leaseKey:** 단일 스트림 처리의 경우 샤드 ID입니다. KCL을 사용한 멀티스트림 처리의 경우 `account-id:StreamName:streamCreationTimestamp:ShardId`로 구성됩니다. leaseKey는 리스 테이블의 파티션 키입니다. 멀티스트림 처리에 대한 자세한 내용은 [KCL을 사용한 멀티스트림 처리](kcl-multi-stream.md) 섹션을 참조하세요.
+ **checkpoint:** 샤드의 가장 최근 체크포인트 시퀀스 번호입니다.
+ **checkpointSubSequenceNumber:** Kinesis Producer Library의 집계 기능을 사용할 때 이는 Kinesis 레코드 내의 개별 사용자 레코드를 추적하는 **체크포인트**에 대한 확장입니다.
+ **leaseCounter:** 워커가 현재 리스를 활발하게 처리하고 있는지 확인하는 데 사용됩니다. 리스 소유권이 다른 워커에게 이전되면 leaseCounter가 증가합니다.
+ **leaseOwner:** 현재 이 리스를 보유하는 워커입니다.
+ **ownerSwitchesSinceCheckpoint:** 마지막 체크포인트 이후 이 리스가 워커를 변경한 횟수입니다.
+ **parentShardId:** 이 샤드의 상위 ID입니다. 하위 샤드에서 처리를 시작하기 전에 상위 샤드가 완전히 처리되어 올바른 레코드 처리 순서를 유지하는지 확인합니다.
+ **childShardId:** 이 샤드의 분할 또는 병합으로 인한 하위 샤드 ID 목록입니다. 샤드 계보를 추적하고 리샤딩 작업 중에 처리 순서를 관리하는 데 사용됩니다.
+ **startingHashKey:** 이 샤드에 대한 해시 키 범위의 하한입니다.
+ **endingHashKey:** 이 샤드에 대한 해시 키 범위의 상한입니다.

KCL에서 멀티스트림 처리를 사용하는 경우 리스 테이블에 다음 두 개의 필드가 추가로 표시됩니다. 자세한 내용은 [KCL을 사용한 멀티스트림 처리](kcl-multi-stream.md) 단원을 참조하십시오.
+ **shardID:** 샤드의 ID입니다.
+ **streamName:** `account-id:StreamName:streamCreationTimestamp` 형식의 데이터 스트림 식별자입니다.

## 워커 지표 테이블
<a name="kcl-worker-metrics-table"></a>

워커 지표 테이블은 각 KCL 애플리케이션의 고유한 Amazon DynamoDB 테이블이며 각 워커의 CPU 사용률 지표를 기록하는 데 사용됩니다. 이러한 지표는 KCL에서 효율적인 리스 할당을 수행하여 워커 간에 리소스 사용률을 균형 있게 유지하는 데 사용됩니다. KCL은 기본적으로 워커 지표 테이블의 이름에 `KCLApplicationName-WorkerMetricStats`를 사용합니다.

## 조정자 상태 테이블
<a name="kcl-coordinator-state-table"></a>

조정자 상태 테이블은 각 KCL 애플리케이션의 고유한 Amazon DynamoDB 테이블이며 워커의 내부 상태 정보를 저장하는 데 사용됩니다. 예를 들어 조정자 상태 테이블은 리더 선택에 관한 데이터 또는 KCL 2.x에서 KCL 3.x로의 인플레이스 마이그레이션과 관련된 메타데이터를 저장합니다. KCL은 기본적으로 조정자 상태 테이블의 이름에 `KCLApplicationName-CoordinatorState`를 사용합니다.

## KCL에서 생성한 메타데이터 테이블의 DynamoDB 용량 모드
<a name="kcl-capacity-mode"></a>

기본적으로 Kinesis Client Library(KCL)는 [온디맨드 용량 모드](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/on-demand-capacity-mode.html)를 사용하여 리스 테이블, 워커 지표 테이블, 조정자 상태 테이블과 같은 DynamoDB 메타데이터 테이블을 생성합니다. 이 모드는 트래픽을 수용하도록 읽기 및 쓰기 용량을 자동으로 조정하며 용량 계획이 필요하지 않습니다. 이러한 메타데이터 테이블을 더 효율적으로 운영하려면 용량 모드를 온디맨드 모드로 유지하는 것이 좋습니다.

리스 테이블을 [프로비저닝된 용량 모드](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/provisioned-capacity-mode.html)로 전환하려면 다음 모범 사례를 따르세요.
+ 사용 패턴 분석:
  + Amazon CloudWatch 지표를 사용하여 애플리케이션의 읽기 및 쓰기 패턴과 사용량(RCU, WCU)을 모니터링합니다.
  + 최대 및 평균 처리량 요구 사항을 이해합니다.
+ 필요한 용량 계산:
  + 분석 내용을 기반으로 읽기 용량 단위(RCU)와 쓰기 용량 단위(WCU)를 추정합니다.
  + 샤드 수, 체크포인트 빈도, 워커 수 등의 요소를 고려합니다.
+ 오토 스케일링 구현:
  + [DynamoDB 오토 스케일링](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/provisioned-capacity-mode.html#ddb-autoscaling)을 사용하여 프로비저닝된 용량을 자동으로 조정하고 적절한 최소 및 최대 용량 제한을 설정합니다.
  + DynamoDB 오토 스케일링은 KCL 메타데이터 테이블이 용량 제한에 도달하여 스로틀링을 일으키지 않도록 방지하는 데 도움이 됩니다.
+ 정기적인 모니터링 및 최적화:
  + `ThrottledRequests`에 대한 CloudWatch 지표를 지속적으로 모니터링합니다.
  + 시간이 지나면서 워크로드의 변화에 따라 용량을 조정합니다.

KCL 소비자 애플리케이션에 대한 메타데이터 DynamoDB 테이블에 `ProvisionedThroughputExceededException`이 발생하는 경우 DynamoDB 테이블의 프로비저닝된 처리량 용량을 늘려야 합니다. 소비자 애플리케이션을 처음 생성할 때 특정 수준의 읽기 용량 단위(RCU) 및 쓰기 용량 단위(WCU)를 설정하는 경우 사용량이 증가함에 따라 부족해질 수 있습니다. 예를 들어 KCL 소비자 애플리케이션이 자주 체크포인트를 수행하거나 샤드가 많은 스트림에서 작동하는 경우 더 많은 용량 단위가 필요할 수 있습니다. DynamoDB에서 프로비저닝된 처리량에 대한 자세한 내용은 Amazon DynamoDB 개발자 안내서의 [DynamoDB 처리량 용량](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/capacity-mode.html) 및 [테이블 업데이트](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.Basics.html#WorkingWithTables.Basics.UpdateTable)를 참조하세요.

## KCL이 워커에게 리스를 할당하고 로드의 균형을 조정하는 방법
<a name="kcl-assign-leases"></a>

KCL은 워커를 실행하는 컴퓨팅 호스트에서 CPU 사용률 지표를 지속적으로 수집하고 모니터링하여 워크로드의 균등한 분산을 보장합니다. 이러한 CPU 사용률 지표는 DynamoDB의 워커 지표 테이블에 저장됩니다. KCL에서 일부 워커가 다른 워커에 비해 CPU 사용률이 더 높음을 감지하면 워커 간에 리스를 재할당하여 사용량이 높은 워커의 로드를 줄입니다. 목표는 소비자 애플리케이션 플릿에서 워크로드의 균형을 더 균등하게 조정하여 단일 워커의 과부하를 방지하는 것입니다. KCL은 소비자 애플리케이션 플릿 전체에 CPU 사용률을 분산하므로 적절한 수의 워커를 선택하여 소비자 애플리케이션 플릿 용량을 적절하게 조정하거나 오토 스케일링을 사용하여 컴퓨팅 용량을 효율적으로 관리하여 비용을 절감할 수 있습니다.

**중요**  
KCL은 특정 사전 조건이 충족되는 경우에만 워커로부터 CPU 사용률 지표를 수집할 수 있습니다. 자세한 내용은 [사전 조건](develop-kcl-consumers-java.md#develop-kcl-consumers-java-prerequisites)을 참조하세요. KCL이 워커로부터 CPU 사용률 지표를 수집할 수 없는 경우 KCL은 다시 워커당 처리량을 사용하여 리스를 할당하고 플릿의 워커 간에 로드의 균형을 조정합니다. KCL은 특정 시점에 각 워커가 수신하는 처리량을 모니터링하고 리스를 재할당하여 각 워커가 할당된 리스에서 유사한 총 처리량 수준을 얻을 수 있도록 합니다.

# KCL을 사용하여 소비자 개발
<a name="develop-kcl-consumers"></a>

Kinesis Client Library(KCL)를 사용하여 Kinesis Data Streams의 데이터를 처리하는 소비자 애플리케이션을 빌드할 수 있습니다.

KCL은 여러 언어로 제공됩니다. 이 주제에서는 Java 및 비 Java 언어로 KCL 소비자를 개발하는 방법을 소개합니다.
+ Kinesis Client Library Javadoc 참조를 확인하려면 [Amazon Kinesis Client Library Javadoc](https://javadoc.io/doc/software.amazon.kinesis/amazon-kinesis-client/latest/index.html)을 참조하세요.
+ GitHub에서 Java용 KCL을 다운로드하려면 [Amazon Kinesis Client Library for Java](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요.
+ Apache Maven에서 Java용 KCL을 찾으려면 [KCL Maven Central Repository](https://central.sonatype.com/artifact/software.amazon.kinesis/amazon-kinesis-client)를 참조하세요.

**Topics**
+ [Java에서 KCL을 사용하여 소비자 개발](develop-kcl-consumers-java.md)
+ [비 Java 언어로 KCL을 사용하여 소비자 개발](develop-kcl-consumers-non-java.md)

# Java에서 KCL을 사용하여 소비자 개발
<a name="develop-kcl-consumers-java"></a>

## 사전 조건
<a name="develop-kcl-consumers-java-prerequisites"></a>

KCL 3.x를 사용하여 시작하기 전에 다음이 있는지 확인합니다.
+ Java Development Kit(JDK) 8 이상
+ AWS SDK for Java 2.x
+ 종속성 관리를 위한 Maven 또는 Gradle

KCL은 워커가 작동 중인 컴퓨팅 호스트에서 CPU 사용률과 같은 CPU 사용률 지표를 수집하여 로드의 균형을 조정함으로써 워커 간에 리소스 사용률 수준을 균등하게 유지합니다. KCL이 워커로부터 CPU 사용률 지표를 수집할 수 있게 하려면 다음 사전 조건을 충족해야 합니다.

 **Amazon Elastic Compute Cloud(Amazon EC2)**
+ 운영 체제는 Linux OS여야 합니다.
+ EC2 인스턴스에서 [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)를 활성화해야 합니다.

 **Amazon EC2의 Amazon Elastic Container Service(Amazon ECS)**
+ 운영 체제는 Linux OS여야 합니다.
+ [ECS 작업 메타데이터 엔드포인트 버전 4](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ec2-metadata.html)를 활성화해야 합니다.
+ Amazon ECS 컨테이너 에이전트 버전은 1.39.0 이상이어야 합니다.

 **의 Amazon ECS AWS Fargate**
+ [Fargate 작업 메타데이터 엔드포인트 버전 4](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v4-fargate.html)를 활성화해야 합니다. Fargate 플랫폼 버전 1.4.0 이상을 사용하는 경우 기본적으로 활성화됩니다.
+ Fargate 플랫폼 버전 1.4.0 이상.

 **Amazon EC2의 Amazon Elastic Kubernetes Service(Amazon EKS)** 
+ 운영 체제는 Linux OS여야 합니다.

 **의 Amazon EKS AWS Fargate**
+ Fargate 플랫폼 버전 1.3.0 이상.

**중요**  
KCL이 워커로부터 CPU 사용률 지표를 수집할 수 없는 경우 KCL은 다시 워커당 처리량을 사용하여 리스를 할당하고 플릿의 워커 간에 로드의 균형을 조정합니다. 자세한 내용은 [KCL이 워커에게 리스를 할당하고 로드의 균형을 조정하는 방법](kcl-dynamoDB.md#kcl-assign-leases) 단원을 참조하십시오.

## 종속성 설치 및 추가
<a name="develop-kcl-consumers-java-installation"></a>

Maven을 사용하는 경우 `pom.xml` 파일에 다음 종속성을 추가합니다. 3.x.x를 최신 KCL 버전으로 교체했는지 확인합니다.

```
<dependency>
    <groupId>software.amazon.kinesis</groupId>
    <artifactId>amazon-kinesis-client</artifactId>
    <version>3.x.x</version> <!-- Use the latest version -->
</dependency>
```

Gradle을 사용하는 경우 `build.gradle` 파일에 다음을 추가합니다. 3.x.x를 최신 KCL 버전으로 교체했는지 확인합니다.

```
implementation 'software.amazon.kinesis:amazon-kinesis-client:3.x.x'
```

[Maven Central Repository](https://search.maven.org/artifact/software.amazon.kinesis/amazon-kinesis-client)에서 KCL의 최신 버전을 확인할 수 있습니다.

## 소비자 구현
<a name="develop-kcl-consumers-java-implemetation"></a>

KCL 소비자 애플리케이션은 다음과 같은 주요 구성 요소로 구성됩니다.

**Topics**
+ [RecordProcessor](#implementation-recordprocessor)
+ [RecordProcessorFactory](#implementation-recordprocessorfactory)
+ [스케줄러](#implementation-scheduler)
+ [기본 소비자 애플리케이션](#implementation-main)

### RecordProcessor
<a name="implementation-recordprocessor"></a>

RecordProcessor는 Kinesis 데이터 스트림 레코드를 처리하는 비즈니스 로직이 상주하는 핵심 구성 요소입니다. 애플리케이션이 Kinesis 스트림에서 수신하는 데이터를 처리하는 방법을 정의합니다.

주요 책임:
+ 샤드 처리 초기화
+ Kinesis 스트림의 레코드 배치 처리
+ 샤드 처리 종료(예: 샤드가 분할 또는 병합되거나 리스가 다른 호스트로 인계되는 경우)
+ 진행 상황 추적을 위한 체크포인트 처리

다음은 구현 예제를 보여줍니다.

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import software.amazon.kinesis.exceptions.InvalidStateException;
import software.amazon.kinesis.exceptions.ShutdownException;
import software.amazon.kinesis.lifecycle.events.*;
import software.amazon.kinesis.processor.ShardRecordProcessor;

public class SampleRecordProcessor implements ShardRecordProcessor {
    private static final String SHARD_ID_MDC_KEY = "ShardId";
    private static final Logger log = LoggerFactory.getLogger(SampleRecordProcessor.class);
    private String shardId;

    @Override
    public void initialize(InitializationInput initializationInput) {
        shardId = initializationInput.shardId();
        MDC.put(SHARD_ID_MDC_KEY, shardId);
        try {
            log.info("Initializing @ Sequence: {}", initializationInput.extendedSequenceNumber());
        } finally {
            MDC.remove(SHARD_ID_MDC_KEY);
        }
    }

    @Override
    public void processRecords(ProcessRecordsInput processRecordsInput) {
        MDC.put(SHARD_ID_MDC_KEY, shardId);
        try {
            log.info("Processing {} record(s)", processRecordsInput.records().size());
            processRecordsInput.records().forEach(r -> 
                log.info("Processing record pk: {} -- Seq: {}", r.partitionKey(), r.sequenceNumber())
            );
            
            // Checkpoint periodically
            processRecordsInput.checkpointer().checkpoint();
        } catch (Throwable t) {
            log.error("Caught throwable while processing records. Aborting.", t);
        } finally {
            MDC.remove(SHARD_ID_MDC_KEY);
        }
    }

    @Override
    public void leaseLost(LeaseLostInput leaseLostInput) {
        MDC.put(SHARD_ID_MDC_KEY, shardId);
        try {
            log.info("Lost lease, so terminating.");
        } finally {
            MDC.remove(SHARD_ID_MDC_KEY);
        }
    }

    @Override
    public void shardEnded(ShardEndedInput shardEndedInput) {
        MDC.put(SHARD_ID_MDC_KEY, shardId);
        try {
            log.info("Reached shard end checkpointing.");
            shardEndedInput.checkpointer().checkpoint();
        } catch (ShutdownException | InvalidStateException e) {
            log.error("Exception while checkpointing at shard end. Giving up.", e);
        } finally {
            MDC.remove(SHARD_ID_MDC_KEY);
        }
    }

    @Override
    public void shutdownRequested(ShutdownRequestedInput shutdownRequestedInput) {
        MDC.put(SHARD_ID_MDC_KEY, shardId);
        try {
            log.info("Scheduler is shutting down, checkpointing.");
            shutdownRequestedInput.checkpointer().checkpoint();
        } catch (ShutdownException | InvalidStateException e) {
            log.error("Exception while checkpointing at requested shutdown. Giving up.", e);
        } finally {
            MDC.remove(SHARD_ID_MDC_KEY);
        }
    }
}
```

다음은 예제에서 사용된 각 메서드에 대한 상세 설명입니다.

**initialize(InitializationInput initializationInput)**
+ 용도: 레코드 처리에 필요한 리소스 또는 상태를 설정합니다.
+ 호출 시점: KCL이 이 레코드 프로세서에 샤드를 할당할 때 한 번 호출됩니다.
+ 중요 사항:
  + `initializationInput.shardId()`: 이 프로세서가 처리할 샤드의 ID입니다.
  + `initializationInput.extendedSequenceNumber()`: 처리를 시작할 시퀀스 번호입니다.

**processRecords(ProcessRecordsInput processRecordsInput)**
+ 용도: 수신 레코드를 처리하고 선택적으로 진행 상황을 체크포인트합니다.
+ 호출 시점: 레코드 프로세서가 샤드에 대한 리스를 유지하는 동안 반복됩니다.
+ 중요 사항:
  + `processRecordsInput.records()`: 처리할 레코드 목록입니다.
  + `processRecordsInput.checkpointer()`: 진행 상황을 체크포인트하는 데 사용됩니다.
  + KCL이 실패하지 않도록 처리 중에 예외를 처리했는지 확인합니다.
  + 예상치 못한 워커 충돌 또는 재시작 전에 체크포인트되지 않은 데이터와 같은 일부 시나리오에서 동일한 레코드가 두 번 이상 처리될 수 있으므로 이 방법은 멱등성이 있어야 합니다.
  + 데이터 일관성을 보장하기 위해 체크포인트를 지정하기 전에 항상 버퍼링된 데이터를 플러시합니다.

**leaseLost(LeaseLostInput leaseLostInput)**
+ 용도: 이 샤드 처리와 관련된 모든 리소스를 정리합니다.
+ 호출 시점: 다른 스케줄러가 이 샤드에 대한 리스를 인수하는 경우에 호출됩니다.
+ 중요 사항:
  + 이 메서드에서는 체크포인트가 허용되지 않습니다.

**shardEnded(ShardEndedInput shardEndedInput)**
+ 용도: 이 샤드 및 체크포인트에 대한 처리를 완료합니다.
+ 호출 시점: 샤드가 분할되거나 병합될 때 호출되어 이 샤드에 대한 모든 데이터가 처리되었음을 나타냅니다.
+ 중요 사항:
  + `shardEndedInput.checkpointer()`: 최종 체크포인트를 수행하는 데 사용됩니다.
  + 처리를 완료하려면 이 방법의 체크포인트가 필수입니다.
  + 여기에서 데이터와 체크포인트를 플러시하지 않으면 샤드를 다시 열 때 데이터 손실 또는 중복 처리가 발생할 수 있습니다.

**shutdownRequested(ShutdownRequestedInput shutdownRequestedInput)**
+ 용도: KCL이 종료될 때 체크포인트를 수행하고 리소스를 정리합니다.
+ 호출 시점: 애플리케이션이 종료되는 경우와 같이 KCL이 종료될 때 호출됩니다.
+ 중요 사항:
  + `shutdownRequestedInput.checkpointer()`: 종료 전에 체크포인트를 수행하는 데 사용됩니다.
  + 애플리케이션이 중지되기 전에 진행 상황이 저장되도록 메서드에 체크포인트를 구현했는지 확인합니다.
  + 여기에서 데이터와 체크포인트를 플러시하지 않으면 애플리케이션이 다시 시작될 때 데이터가 손실되거나 레코드가 재처리될 수 있습니다.

**중요**  
KCL 3.x는 이전 워커를 종료하기 전에 체크포인트를 지정하여 한 워커에서 다른 워커로 리스를 인계할 때 데이터 재처리를 줄입니다. `shutdownRequested()` 메서드에서 체크포인트 로직을 구현하지 않으면 이 이점을 이용할 수 없습니다. `shutdownRequested()` 메서드 내에 체크포인트 로직을 구현했는지 확인합니다.

### RecordProcessorFactory
<a name="implementation-recordprocessorfactory"></a>

RecordProcessorFactory는 새 RecordProcessor 인스턴스를 생성하는 역할을 합니다. KCL은 이 팩토리를 사용하여 애플리케이션이 처리해야 하는 각 샤드에 대해 새 RecordProcessor를 생성합니다.

주요 책임:
+ 온디맨드 방식으로 새 RecordProcessor 인스턴스 생성
+ 각 RecordProcessor가 올바르게 초기화되었는지 확인

다음은 구현 예제입니다.

```
import software.amazon.kinesis.processor.ShardRecordProcessor;
import software.amazon.kinesis.processor.ShardRecordProcessorFactory;

public class SampleRecordProcessorFactory implements ShardRecordProcessorFactory {
    @Override
    public ShardRecordProcessor shardRecordProcessor() {
        return new SampleRecordProcessor();
    }
}
```

이 예제에서는 shardRecordProcessor()가 호출될 때마다 팩토리에서 새 SampleRecordProcessor를 생성합니다. 필요한 초기화 로직을 포함하도록 이를 확장할 수 있습니다.

### 스케줄러
<a name="implementation-scheduler"></a>

스케줄러는 KCL 애플리케이션의 모든 활동을 조정하는 상위 수준 구성 요소입니다. 데이터 처리의 전반적인 오케스트레이션을 담당합니다.

주요 책임:
+ RecordProcessors의 수명 주기 관리
+ 샤드에 대한 리스 관리 처리
+ 체크포인트 조정
+ 애플리케이션의 여러 워커 간에 샤드 처리 로드의 균형 조정
+ 정상적인 종료 및 애플리케이션 종료 신호 처리

스케줄러는 일반적으로 기본 애플리케이션에서 생성되고 시작됩니다. 스케줄러의 구현 예제는 기본 소비자 애플리케이션 섹션에서 확인할 수 있습니다.

### 기본 소비자 애플리케이션
<a name="implementation-main"></a>

기본 소비자 애플리케이션은 모든 구성 요소를 하나로 묶어줍니다. KCL 소비자 설정, 필요한 클라이언트 생성, 스케줄러 구성, 애플리케이션의 수명 주기 관리를 담당합니다.

주요 책임:
+  AWS 서비스 클라이언트 설정(Kinesis, DynamoDB, CloudWatch)
+ KCL 애플리케이션 구성
+ 스케줄러 생성 및 시작
+ 애플리케이션 종료 처리

다음은 구현 예제입니다.

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.kinesis.KinesisAsyncClient;
import software.amazon.kinesis.common.ConfigsBuilder;
import software.amazon.kinesis.common.KinesisClientUtil;
import software.amazon.kinesis.coordinator.Scheduler;
import java.util.UUID;

public class SampleConsumer {
    private final String streamName;
    private final Region region;
    private final KinesisAsyncClient kinesisClient;

    public SampleConsumer(String streamName, Region region) {
        this.streamName = streamName;
        this.region = region;
        this.kinesisClient = KinesisClientUtil.createKinesisAsyncClient(KinesisAsyncClient.builder().region(this.region));
    }

    public void run() {
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        CloudWatchAsyncClient cloudWatchClient = CloudWatchAsyncClient.builder().region(region).build();
        
        ConfigsBuilder configsBuilder = new ConfigsBuilder(
            streamName, 
            streamName, 
            kinesisClient, 
            dynamoDbAsyncClient,
            cloudWatchClient, 
            UUID.randomUUID().toString(), 
            new SampleRecordProcessorFactory()
        );

        Scheduler scheduler = new Scheduler(
            configsBuilder.checkpointConfig(),
            configsBuilder.coordinatorConfig(),
            configsBuilder.leaseManagementConfig(),
            configsBuilder.lifecycleConfig(),
            configsBuilder.metricsConfig(),
            configsBuilder.processorConfig(),
            configsBuilder.retrievalConfig()
        );

        Thread schedulerThread = new Thread(scheduler);
        schedulerThread.setDaemon(true);
        schedulerThread.start();
    }

    public static void main(String[] args) {
        String streamName = "your-stream-name"; // replace with your stream name
        Region region = Region.US_EAST_1; // replace with your region
        new SampleConsumer(streamName, region).run();
    }
}
```

 KCL은 기본적으로 전용 처리량으로 향상된 팬아웃(EFO) 소비자를 생성합니다. 향상된 팬아웃에 대한 자세한 내용은 [전용 처리량으로 향상된 팬아웃 소비자 개발](enhanced-consumers.md) 섹션을 참조하세요. 소비자가 2명 미만이거나 200ms 미만의 읽기 전파 지연이 필요하지 않은 경우, 공유 처리량 소비자를 사용하도록 스케줄러 객체에서 다음 구성을 설정해야 합니다.

```
configsBuilder.retrievalConfig().retrievalSpecificConfig(new PollingConfig(streamName, kinesisClient))
```

다음 코드는 공유 처리량 소비자를 사용하는 스케줄러 객체를 생성하는 예제입니다.

**가져오기**:

```
import software.amazon.kinesis.retrieval.polling.PollingConfig;
```

**코드**:

```
Scheduler scheduler = new Scheduler(
            configsBuilder.checkpointConfig(),
            configsBuilder.coordinatorConfig(),
            configsBuilder.leaseManagementConfig(),
            configsBuilder.lifecycleConfig(),
            configsBuilder.metricsConfig(),
            configsBuilder.processorConfig(),
            configsBuilder.retrievalConfig().retrievalSpecificConfig(new PollingConfig(streamName, kinesisClient))
        );/
```

# 비 Java 언어로 KCL을 사용하여 소비자 개발
<a name="develop-kcl-consumers-non-java"></a>

이 섹션에서는 Python, Node.js, .NET, Ruby에서 Kinesis Client Library(KCL)를 사용하는 소비자의 구현을 다룹니다.

KCL은 Java 라이브러리입니다. `MultiLangDaemon`이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 대몬은 Java 기반이며, Java 이외의 언어로 KCL을 사용하는 경우 백그라운드에서 실행됩니다. 따라서 비 Java 언어용 KCL을 설치하고 비 Java 언어로만 소비자 앱을 작성한 경우에도 `MultiLangDaemon` 때문에 시스템에 Java를 설치해야 합니다. `MultiLangDaemon`에는 사용 사례에 적합하게 사용자 지정해야 하는 몇 가지 기본 설정이 있습니다(예: 연결되는 AWS 리전). GitHub의 `MultiLangDaemon`에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang)를 참조하세요.

핵심 개념은 언어 간에 동일하게 유지되지만 언어별 고려 사항과 구현이 몇 가지 있습니다. KCL 소비자 개발에 대한 핵심 개념은 [Java에서 KCL을 사용하여 소비자 개발](develop-kcl-consumers-java.md) 섹션을 참조하세요. Python, Node.js, .NET, Ruby에서 KCL 소비자를 개발하는 방법과 최신 업데이트에 대한 자세한 내용은 다음 GitHub 리포지토리를 참조하세요.
+ Python: [amazon-kinesis-client-python](https://github.com/awslabs/amazon-kinesis-client-python)
+ Node.js: [amazon-kinesis-client-nodejs](https://github.com/awslabs/amazon-kinesis-client-nodejs)
+ .NET: [amazon-kinesis-client-net](https://github.com/awslabs/amazon-kinesis-client-net)
+ Ruby: [amazon-kinesis-client-ruby](https://github.com/awslabs/amazon-kinesis-client-ruby)

**중요**  
JDK 8을 사용하는 경우 다음과 같은 비 Java KCL 라이브러리 버전을 사용하지 마세요. 이러한 버전에는 JDK 8과 호환되지 않는 종속성(로그백)이 포함되어 있습니다.  
KCL Python 3.0.2 및 2.2.0
KCL Node.js 2.3.0
KCL .NET 3.1.0
KCL Ruby 2.2.0
JDK 8을 사용하여 작업하는 경우 이러한 영향을 받는 버전 이전 또는 이후에 릴리스된 버전을 사용하는 것이 좋습니다.

# KCL을 사용한 멀티스트림 처리
<a name="kcl-multi-stream"></a>

이 섹션에서는 2개 이상의 데이터 스트림을 동시에 처리할 수 있는 KCL 소비자 애플리케이션의 생성을 가능하게 해주는 KCL의 필수 변경 사항을 설명합니다.
**중요**  
멀티스트림 처리는 KCL 2.3 이상에서만 지원됩니다.
멀티스트림 처리는 비 Java 언어로 작성되어 `multilangdaemon`으로 실행되는 KCL 소비자는에게 지원되지 *않습니다*.
멀티스트림 처리는 KCL 1.x의 모든 버전에서 지원되지 *않습니다*.
+ **MultistreamTracker 인터페이스**
  + 여러 스트림을 동시에 처리할 수 있는 소비자 애플리케이션을 구축하려면 [MultistreamTracker](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/processor/MultiStreamTracker.java)라는 새 인터페이스를 구현해야 합니다. 이 인터페이스에는 KCL 소비자 애플리케이션에서 처리할 데이터 스트림 및 해당 구성 목록을 반환하는 `streamConfigList` 메서드가 포함되어 있습니다. 처리 중인 데이터 스트림은 소비자 애플리케이션 런타임 중에 변경될 수 있습니다. `streamConfigList`는 처리할 데이터 스트림의 변경 사항을 알아보기 위해 KCL에서 주기적으로 직접적으로 호출됩니다.
  + `streamConfigList`는 [StreamConfig](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/StreamConfig.java#L23) 목록을 채웁니다.

  ```
  package software.amazon.kinesis.common;
  
  import lombok.Data;
  import lombok.experimental.Accessors;
  
  @Data
  @Accessors(fluent = true)
  public class StreamConfig {
      private final StreamIdentifier streamIdentifier;
      private final InitialPositionInStreamExtended initialPositionInStreamExtended;
      private String consumerArn;
  }
  ```
  + `StreamIdentifier` 및 `InitialPositionInStreamExtended`는 필수 필드이며 `consumerArn`은 선택 사항입니다. KCL을 사용하여 향상된 팬아웃 소비자 애플리케이션을 구현하는 경우에만 `consumerArn`을 제공해야 합니다.
  + 에 대한 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/v2.5.8/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/StreamIdentifier.java\$1L129](https://github.com/awslabs/amazon-kinesis-client/blob/v2.5.8/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/StreamIdentifier.java#L129) `StreamIdentifier`참조하십시오. `StreamIdentifier`를 생성하려면 KCL 2.5.0 이상에서 사용할 수 있는 `streamArn` 및 `streamCreationEpoch`에서 멀티스트림 인스턴스를 생성하는 것이 좋습니다. `streamArm`를 지원하지 않는 KCL v2.3 및 v2.4에서는 `account-id:StreamName:streamCreationTimestamp` 형식을 사용하여 멀티스트림 인스턴스를 생성하세요. 이 형식은 사용되지 않으며 다음 메이저 릴리스부터 더 이상 지원되지 않습니다.
  +  MultistreamTracker에는 리스 테이블(formerStreamsLeasesDeletionStrategy)에서 오래된 스트림의 리스를 삭제하기 위한 전략도 포함되어 있습니다. 소비자 애플리케이션 런타임 중에는 전략을 변경할 수 없다는 점에 유의하세요. 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/processor/FormerStreamsLeasesDeletionStrategy.java](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/processor/FormerStreamsLeasesDeletionStrategy.java)를 참조하세요.
+   [ConfigsBuilder](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/ConfigsBuilder.java)는 KCL 버전 2.x 이상에서 KCL 소비자 애플리케이션을 구축할 때 사용할 모든 KCL 구성 설정을 지정하는 데 사용할 수 있는 애플리케이션 전체 클래스입니다. `ConfigsBuilder` 클래스는 이제 `MultistreamTracker` 인터페이스를 지원합니다. 하나의 데이터 스트림 이름으로 ConfigsBuilder를 초기화하여 레코드를 소비할 수 있습니다. 

  ```
  /**
       * Constructor to initialize ConfigsBuilder with StreamName
       * @param streamName
       * @param applicationName
       * @param kinesisClient
       * @param dynamoDBClient
       * @param cloudWatchClient
       * @param workerIdentifier
       * @param shardRecordProcessorFactory
       */
      public ConfigsBuilder(@NonNull String streamName, @NonNull String applicationName,
              @NonNull KinesisAsyncClient kinesisClient, @NonNull DynamoDbAsyncClient dynamoDBClient,
              @NonNull CloudWatchAsyncClient cloudWatchClient, @NonNull String workerIdentifier,
              @NonNull ShardRecordProcessorFactory shardRecordProcessorFactory) {
          this.appStreamTracker = Either.right(streamName);
          this.applicationName = applicationName;
          this.kinesisClient = kinesisClient;
          this.dynamoDBClient = dynamoDBClient;
          this.cloudWatchClient = cloudWatchClient;
          this.workerIdentifier = workerIdentifier;
          this.shardRecordProcessorFactory = shardRecordProcessorFactory;
      }
  ```  

또는 동시에 여러 스트림을 처리하는 KCL 소비자 애플리케이션을 구현하려는 경우 `MultiStreamTracker`로 ConfigsBuilder를 초기화할 수 있습니다.

```
* Constructor to initialize ConfigsBuilder with MultiStreamTracker
     * @param multiStreamTracker
     * @param applicationName
     * @param kinesisClient
     * @param dynamoDBClient
     * @param cloudWatchClient
     * @param workerIdentifier
     * @param shardRecordProcessorFactory
     */
    public ConfigsBuilder(@NonNull MultiStreamTracker multiStreamTracker, @NonNull String applicationName,
            @NonNull KinesisAsyncClient kinesisClient, @NonNull DynamoDbAsyncClient dynamoDBClient,
            @NonNull CloudWatchAsyncClient cloudWatchClient, @NonNull String workerIdentifier,
            @NonNull ShardRecordProcessorFactory shardRecordProcessorFactory) {
        this.appStreamTracker = Either.left(multiStreamTracker);
        this.applicationName = applicationName;
        this.kinesisClient = kinesisClient;
        this.dynamoDBClient = dynamoDBClient;
        this.cloudWatchClient = cloudWatchClient;
        this.workerIdentifier = workerIdentifier;
        this.shardRecordProcessorFactory = shardRecordProcessorFactory;
    }
```
+ KCL 소비자 애플리케이션에 대해 멀티스트림 지원이 구현됨에 따라 이제 애플리케이션 리스 테이블의 각 행에는 이 애플리케이션이 처리하는 여러 데이터 스트림의 샤드 ID와 스트림 이름이 포함됩니다.
+ KCL 소비자 애플리케이션에 대한 멀티스트림 지원이 구현되면 leaseKey는 `account-id:StreamName:streamCreationTimestamp:ShardId` 구조를 취합니다. 예를 들어 `111111111:multiStreamTest-1:12345:shardId-000000000336`입니다.

**중요**  
기존 KCL 소비자 애플리케이션이 하나의 데이터 스트림만 처리하도록 구성된 경우 `leaseKey`(리스 테이블의 파티션 키)는 샤드 ID입니다. 여러 데이터 스트림을 처리하도록 기존 KCL 소비자 애플리케이션을 재구성하면 리스 테이블이 손상됩니다. 멀티스트림을 지원하려면 `leaseKey` 구조가 `account-id:StreamName:StreamCreationTimestamp:ShardId`와 같아야 하기 때문입니다.

# KCL에서 AWS Glue 스키마 레지스트리 사용
<a name="kcl-glue-schema"></a>

Kinesis Data Streams를 AWS Glue 스키마 레지스트리와 통합할 수 있습니다. AWS Glue 스키마 레지스트리를 사용하면 스키마를 중앙에서 검색, 제어 및 발전시키는 동시에 생성된 데이터를 등록된 스키마에서 지속적으로 검증할 수 있습니다. 스키마는 데이터 레코드의 구조와 포맷을 정의합니다. 스키마는 신뢰할 수 있는 데이터 게시, 소비 또는 저장을 위한 버전 지정 사양입니다. AWS Glue 스키마 레지스트리를 사용하면 스트리밍 애플리케이션 내에서 end-to-end 데이터 품질 및 데이터 거버넌스를 개선할 수 있습니다. 자세한 내용은 [AWS Glue Schema Registry](https://docs.aws.amazon.com/glue/latest/dg/schema-registry.html)를 참조하세요. 이 통합을 설정하는 방법 중 하나는 Java용 KCL을 사용하는 것입니다.

**중요**  
AWS Glue Kinesis Data Streams에 대한 스키마 레지스트리 통합은 KCL 2.3 이상에서만 지원됩니다.
AWS Glue Kinesis Data Streams에 대한 스키마 레지스트리 통합은에서 실행되는 Java 이외의 언어로 작성된 KCL 소비자에는 지원되지 *않습니다*`multilangdaemon`.
AWS Glue Kinesis Data Streams에 대한 스키마 레지스트리 통합은 KCL 1.x 버전에서 지원되지 *않습니다*.

KCL을 사용하여 Kinesis Data Streams와 AWS Glue 스키마 레지스트리의 통합을 설정하는 방법에 대한 자세한 지침은 [사용 사례: Amazon Kinesis Data Streams와 AWS Glue 스키마 레지스트리 통합의 "KPL/KCL 라이브러리를 사용하여 데이터와 상호 작용" 섹션을 참조하세요.](https://docs.aws.amazon.com/glue/latest/dg/schema-registry-integrations.html#schema-registry-integrations-kds)

# KCL 소비자 애플리케이션에 필요한 IAM 권한
<a name="kcl-iam-permissions"></a>

 KCL 소비자 애플리케이션과 연결된 IAM 역할 또는 사용자에게 다음 권한을 추가해야 합니다.

 보안 모범 사례에 AWS 따라 세분화된 권한을 사용하여 다양한 리소스에 대한 액세스를 제어해야 합니다. AWS Identity and Access Management (IAM)을 사용하면에서 사용자 및 사용자 권한을 관리할 수 있습니다 AWS. IAM 정책에는 허용된 작업과 작업이 적용되는 리소스가 명시적으로 나열됩니다.

다음 표에는 KCL 소비자 애플리케이션에 일반적으로 필요한 최소 IAM 권한이 나와 있습니다.


**KCL 소비자 애플리케이션에 대한 최소 IAM 권한**  

| 서비스 | 작업 | 리소스(ARN) | 용도 | 
| --- | --- | --- | --- | 
| Amazon Kinesis Data Streams |  `DescribeStream` `DescribeStreamSummary` `RegisterStreamConsumer`  |  KCL 애플리케이션이 데이터를 처리할 Kinesis 데이터 스트림입니다.`arn:aws:kinesis:region:account:stream/StreamName`  |  레코드를 읽으려고 하기 전에 소비자는 데이터 스트림이 존재하는지, 데이터 스트림이 활성 상태인지, 샤드가 데이터 스트림에 포함되어 있는지를 확인합니다. 샤드에 소비자를 등록합니다.  | 
| Amazon Kinesis Data Streams |  `GetRecords` `GetShardIterator` `ListShards`  | KCL 애플리케이션이 데이터를 처리할 Kinesis 데이터 스트림입니다.`arn:aws:kinesis:region:account:stream/StreamName` |  샤드에서 레코드를 읽습니다.  | 
| Amazon Kinesis Data Streams |  `SubscribeToShard` `DescribeStreamConsumer` |  KCL 애플리케이션이 데이터를 처리할 Kinesis 데이터 스트림입니다. 향상된 팬아웃(EFO) 소비자를 사용하는 경우에만 이 작업을 추가합니다. `arn:aws:kinesis:region:account:stream/StreamName/consumer/*`  |  향상된 팬아웃(EFO) 소비자를 위한 샤드를 구독합니다.  | 
| Amazon DynamoDB |  `CreateTable` `DescribeTable` `UpdateTable` `Scan` `GetItem` `PutItem` `UpdateItem` `DeleteItem`  |  리스 테이블(KCL에서 생성한 DynamoDB의 메타데이터 테이블)입니다. `arn:aws:dynamodb:region:account:table/KCLApplicationName`  |  이러한 작업은 KCL이 DynamoDB에서 생성된 리스 테이블을 관리하는 데 필요합니다.  | 
| Amazon DynamoDB |  `CreateTable` `DescribeTable` `Scan` `GetItem` `PutItem` `UpdateItem` `DeleteItem`  |  KCL에서 생성한 워커 지표 및 조정자 상태 테이블(DynamoDB의 메타데이터 테이블)입니다. `arn:aws:dynamodb:region:account:table/KCLApplicationName-WorkerMetricStats` `arn:aws:dynamodb:region:account:table/KCLApplicationName-CoordinatorState`  |  KCL이 DynamoDB에서 워커 지표 및 조정자 상태 메타데이터 테이블을 관리하려면 이 작업이 필요합니다.  | 
| Amazon DynamoDB | `Query` |  리스 테이블의 글로벌 보조 인덱스입니다. `arn:aws:dynamodb:region:account:table/KCLApplicationName/index/*`  |  이 작업은 KCL이 DynamoDB에서 생성된 리스 테이블의 글로벌 보조 인덱스를 읽는 데 필요합니다.  | 
| Amazon CloudWatch | `PutMetricData` |  \$1  |  애플리케이션을 모니터링하는 데 유용한 지표를 CloudWatch에 업로드합니다. `PutMetricData` 작업이 간접 호출되는 CloudWatch에는 특정 리소스가 없으므로 별표(\$1)가 사용됩니다.  | 

**참고**  
ARN의 "리전", "계정", "StreamName" 및 "KCLApplicationName"을 각각 자체 AWS 리전, AWS 계정 번호, Kinesis 데이터 스트림 이름 및 KCL 애플리케이션 이름으로 바꿉니다. ARNs KCL 3.x는 DynamoDB에 메타데이터 테이블 두 개를 추가로 생성합니다. KCL에서 생성한 DynamoDB 메타데이터 테이블에 대한 자세한 내용은 [KCL의 DynamoDB 메타데이터 테이블 및 로드 밸런싱](kcl-dynamoDB.md) 섹션을 참조하세요. 구성을 사용하여 KCL에서 생성한 메타데이터 테이블의 이름을 사용자 지정하는 경우 KCL 애플리케이션 이름 대신 지정된 테이블 이름을 사용합니다.

다음은 KCL 소비자 애플리케이션에 대한 정책 문서 예제입니다.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kinesis:DescribeStream",
                "kinesis:DescribeStreamSummary",
                "kinesis:RegisterStreamConsumer",
                "kinesis:GetRecords",
                "kinesis:GetShardIterator",
                "kinesis:ListShards"
            ],
            "Resource": "arn:aws:kinesis:us-east-1:123456789012:stream/STREAM_NAME"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kinesis:SubscribeToShard",
                "kinesis:DescribeStreamConsumer"
            ],
            "Resource": "arn:aws:kinesis:us-east-1:123456789012:stream/STREAM_NAME/consumer/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:CreateTable",
                "dynamodb:DescribeTable",
                "dynamodb:UpdateTable",
                "dynamodb:GetItem",
                "dynamodb:UpdateItem",
                "dynamodb:PutItem",
                "dynamodb:DeleteItem",
                "dynamodb:Scan"
            ],
            "Resource": [
            "arn:aws:dynamodb:us-east-1:123456789012:table/KCL_APPLICATION_NAME"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:CreateTable",
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:UpdateItem",
                "dynamodb:PutItem",
                "dynamodb:DeleteItem",
                "dynamodb:Scan"
            ],
            "Resource": [
            "arn:aws:dynamodb:us-east-1:123456789012:table/KCL_APPLICATION_NAME-WorkerMetricStats",
    "arn:aws:dynamodb:us-east-1:123456789012:table/KCL_APPLICATION_NAME-CoordinatorState"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:Query"
            ],
            "Resource": [
            "arn:aws:dynamodb:us-east-1:123456789012:table/KCL_APPLICATION_NAME/index/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData"
            ],
            "Resource": "*"
        }
    ]
}
```

------

예제 정책을 사용하기 전에 다음을 항목을 확인합니다.
+ REGION을 로 바꿉니다 AWS 리전 (예: us-east-1).
+ ACCOUNT\$1ID를 AWS 계정 ID로 바꿉니다.
+ STREAM\$1NAME을 해당 Kinesis 데이터 스트림의 이름으로 바꿉니다.
+ CONSUMER\$1NAME을 소비자 이름으로, 일반적으로 KCL을 사용할 때의 애플리케이션 이름으로 바꿉니다.
+ KCL\$1APPLICATION\$1NAME을 해당 KCL 애플리케이션 이름으로 바꿉니다.

# KCL 구성
<a name="kcl-configuration"></a>

구성 속성을 설정하여 특정 요구 사항에 적합하게 Kinesis Client Library의 기능을 사용자 지정할 수 있습니다. 다음 표에서는 구성 속성과 클래스를 설명합니다.

**중요**  
KCL 3.x에서 로드 밸런싱 알고리즘은 워커당 동일한 수의 리스가 아니라 워커 간에 균등한 CPU 사용률을 달성하는 것을 목표로 합니다. `maxLeasesForWorker`를 너무 낮게 설정하면 워크로드의 균형을 효과적으로 조정하는 KCL의 능력이 제한될 수 있습니다. `maxLeasesForWorker` 구성을 사용하는 경우 가능한 최상의 로드 분산을 위해 값을 늘리는 것이 좋습니다.


**이 표는 KCL의 구성 속성을 보여줍니다.**  

| 구성 속성 | 구성 클래스 | 설명 | 기본값  | 
| --- | --- | --- | --- | 
| applicationName | ConfigsBuilder | 이 KCL 애플리케이션의 이름입니다. tableName 및 consumerName의 기본값으로 사용됩니다. | 해당 사항 없음 | 
| tableName | ConfigsBuilder |  Amazon DynamoDB 리스 테이블에 사용된 테이블 이름 재정의를 허용합니다.  | 해당 사항 없음 | 
| streamName | ConfigsBuilder |  이 애플리케이션이 레코드를 처리하는 스트림의 이름입니다.  | 해당 사항 없음 | 
| workerIdentifier | ConfigsBuilder |  이 애플리케이션 프로세서 인스턴스화를 나타내는 고유 식별자입니다. 고유해야 합니다.  | 해당 사항 없음 | 
| failoverTimeMillis | LeaseManagementConfig |  리스 소유자가 실패했다고 간주하기 전에 전달해야 하는 시간(밀리초)입니다. 샤드 수가 많은 애플리케이션의 경우 리스 추적에 필요한 DynamoDB IOPS 수를 줄이기 위해 더 높은 수로 설정할 수 있습니다.  | 10,000(10초) | 
| shardSyncIntervalMillis | LeaseManagementConfig |  샤드 sync 호출 사이의 시간.  | 60,000(60초) | 
| cleanupLeasesUponShardCompletion | LeaseManagementConfig |  설정하면, 하위 리스에서 처리를 시작하자마자 리스가 제거됩니다.  | TRUE | 
| ignoreUnexpectedChildShards | LeaseManagementConfig |  설정하면, 진행 중인 샤드가 있는 하위 샤드가 무시됩니다. 이는 주로 DynamoDB Streams용입니다.  | FALSE | 
| maxLeasesForWorker | LeaseManagementConfig |  단일 워커가 수락해야 하는 최대 리스 수입니다. 이 값을 너무 낮게 설정하면 워커가 모든 샤드를 처리할 수 없는 경우, 데이터가 손실되어 워커 간의 리스 할당이 최적화되지 않을 수 있습니다. 구성할 때 총 샤드 수, 워커 수, 워커 처리 용량을 고려합니다.  | 무제한 | 
| maxLeaseRenewalThreads | LeaseManagementConfig |  리스 갱신 스레드 풀의 크기를 제어합니다. 애플리케이션에서 사용할 수 있는 리스가 많을수록 이 풀의 크기가 커야 합니다.  | 20 | 
| billingMode | LeaseManagementConfig |  DynamoDB에서 생성된 리스 테이블의 용량 모드를 결정합니다. 온디맨드 모드(PAY\$1PER\$1REQUEST)와 프로비저닝 모드의 두 가지 옵션이 있습니다. 용량 계획이 필요하지 않고 워크로드에 따라 자동으로 확장되므로 온디맨드 모드의 기본 설정을 사용하는 것이 좋습니다.  | PAY\$1PER\$1REQUEST(온디맨드 모드) | 
| initialLeaseTableReadCapacity | LeaseManagementConfig | Kinesis Client Library에서 프로비저닝된 용량 모드로 DynamoDB 리스 테이블을 새로 생성해야 하는 경우에 사용되는 DynamoDB 읽기 용량입니다. billingMode 구성에서 기본 온디맨드 용량 모드를 사용하는 경우 이 구성을 무시할 수 있습니다. | 10 | 
| initialLeaseTableWriteCapacity | LeaseManagementConfig | Kinesis Client Library에서 DynamoDB 리스 테이블을 새로 생성해야 하는 경우 사용되는 DynamoDB 읽기 용량입니다. billingMode 구성에서 기본 온디맨드 용량 모드를 사용하는 경우 이 구성을 무시할 수 있습니다. | 10 | 
| initialPositionInStreamExtended | LeaseManagementConfig |  애플리케이션이 읽기를 시작해야 하는 스트림 내 초기 위치입니다. 최초 리스 생성 시에만 사용됩니다.  |  InitialPositionInStream.TRIM\$1HORIZON  | 
| reBalanceThresholdPercentage | LeaseManagementConfig |  로드 밸런싱 알고리즘이 워커 간 샤드 재할당을 고려해야 할 시기를 결정하는 백분율 값입니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | 10 | 
| dampeningPercentage | LeaseManagementConfig |  단일 리밸런싱 작업에서 오버로드된 워커로부터 이동할 로드의 양을 줄이는 데 사용되는 백분율 값입니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | 60 | 
| allowThroughputOvershoot | LeaseManagementConfig |  총 리스 처리량이 원하는 처리량을 초과하더라도 오버로드된 워커로부터 추가 리스를 가져와야 하는지 여부를 결정합니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | TRUE | 
| disableWorkerMetrics | LeaseManagementConfig |  리스를 재할당하거나 로드 밸런싱을 수행할 때 KCL이 워커의 리소스 지표(예: CPU 사용률)를 무시해야 하는지 여부를 결정합니다. KCL이 CPU 사용률에 따라 로드 밸런싱되지 않게 하려면 이 값을 TRUE로 설정합니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | FALSE | 
| maxThroughputPerHostKBps | LeaseManagementConfig |  리스 할당 중에 워커에게 할당하는 최대 처리량입니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | 무제한 | 
| isGracefulLeaseHandoffEnabled | LeaseManagementConfig |  워커 간의 리스 핸드오프 동작을 제어합니다. true로 설정할 경우 KCL은 샤드의 RecordProcessor가 다른 워커에게 리스를 인계하기 전에 처리를 완료하기에 충분한 시간을 허용하여 리스를 정상적으로 이전하려고 시도합니다. 이렇게 하면 데이터 무결성을 보장하고 원활한 이전을 보장할 수 있지만 핸드오프 시간이 늘어날 수 있습니다. false로 설정하면 RecordProcessor가 정상적으로 종료될 때까지 기다리지 않고 리스가 즉시 핸드오프됩니다. 이에 따라 핸드오프가 빨라질 수 있지만 처리가 불완전해질 위험이 있습니다. 참고: 정상적인 리스 핸드오프 기능을 활용하려면 RecordProcessor의 shutdownRequested() 메서드 내에서 체크포인트를 구현해야 합니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | TRUE | 
| gracefulLeaseHandoffTimeoutMillis | LeaseManagementConfig |  리스를 다음 소유자에게 강제로 이전하기 전에 현재 샤드의 RecordProcessor가 정상적으로 종료될 때까지 기다리는 최소 시간(밀리초)을 지정합니다. 일반적으로 processRecords 메서드가 기본값보다 오래 실행되는 경우 이 설정을 늘리는 것이 좋습니다. 이렇게 하면 RecordProcessor가 리스 이전이 발생하기 전에 처리를 완료할 충분한 시간을 확보할 수 있습니다. 이는 KCL 3.x에 도입된 새로운 구성입니다.  | 30,000(30초) | 
| maxRecords | PollingConfig |  Kinesis가 반환하는 최대 레코드 수를 설정할 수 있습니다.  | 10,000 | 
| retryGetRecordsInSeconds | PollingConfig |  실패에 대한 GetRecords 시도 사이의 지연을 구성합니다.  | 없음 | 
| maxGetRecordsThreadPool | PollingConfig |  GetRecords에 사용되는 스레드 풀 크기.  | 없음 | 
| idleTimeBetweenReadsInMillis | PollingConfig |  데이터 스트림에서 데이터를 폴링하기 위해 GetRecords 호출 간에 KCL이 대기하는 시간을 결정합니다. 단위는 밀리초입니다.  | 1,500 | 
| callProcessRecordsEvenForEmptyRecordList | ProcessorConfig |  설정하면, Kinesis에서 제공된 레코드가 없는 경우에도 레코드 프로세서가 직접적으로 호출됩니다.  | FALSE | 
| parentShardPollIntervalMillis | CoordinatorConfig |  상위 샤드가 완료되었는지를 확인하기 위해 레코드 프로세서가 폴링을 수행해야 하는 간격입니다. 단위는 밀리초입니다.  | 10,000(10초) | 
| skipShardSyncAtWorkerInitializationIfLeaseExist | CoordinatorConfig |  리스 테이블에 기존 리스가 있는 경우 샤드 데이터 동기화를 비활성화합니다.  |  FALSE  | 
| shardPrioritization | CoordinatorConfig |  사용할 샤드 우선 순위.  |  NoOpShardPrioritization  | 
| ClientVersionConfig | CoordinatorConfig |  애플리케이션이 실행할 KCL 버전 호환성 모드를 결정합니다. 이 구성은 이전 KCL 버전에서 마이그레이션하는 경우에만 해당됩니다. 3.x로 마이그레이션할 때는 이 구성을 `CLIENT_VERSION_CONFIG_COMPATIBLE_WITH_2X`로 설정해야 합니다. 마이그레이션이 완료되면 이 구성을 제거할 수 있습니다.  | CLIENT\$1VERSION\$1CONFIG\$13X | 
| taskBackoffTimeMillis | LifecycleConfig |  실패한 KCL 작업을 재시도하기 위한 대기 시간입니다. 단위는 밀리초입니다.  | 500(0.5초) | 
| logWarningForTaskAfterMillis | LifecycleConfig |  작업이 완료되지 않은 경우 얼마나 대기한 후 경고가 기록될지를 지정합니다.  | 없음 | 
| listShardsBackoffTimeInMillis | RetrievalConfig | 실패 발생 시 ListShards 호출 간에 대기하는 시간(밀리초)입니다. 단위는 밀리초입니다. | 1,500(1.5초) | 
| maxListShardsRetryAttempts | RetrievalConfig | 포기하기 전에 ListShards가 재시도하는 최대 횟수입니다. | 50 | 
| metricsBufferTimeMillis | MetricsConfig |  지표를 CloudWatch에 게시하기 전에 버퍼링할 최대 기간(밀리초)을 지정합니다.  | 10,000(10초) | 
| metricsMaxQueueSize | MetricsConfig |  CloudWatch에 게시하기 전에 버퍼링할 최대 지표 수를 지정합니다.  | 10,000 | 
| metricsLevel | MetricsConfig |  활성화하고 게시할 CloudWatch 지표의 세부 수준을 지정합니다. 가능한 값: NONE, SUMMARY, DETAILED  |  MetricsLevel.DETAILED  | 
| metricsEnabledDimensions | MetricsConfig |  CloudWatch 지표에 허용되는 차원을 제어합니다.  | 모든 차원 | 

**KCL 3.x에서 중단된 구성**

KCL 3.x에서는 다음 구성 속성이 중단됩니다.


**이 표는 KCL 3.x의 중단된 구성 속성을 보여줍니다.**  

| 구성 속성 | 구성 클래스 | 설명 | 
| --- | --- | --- | 
| maxLeasesToStealAtOneTime | LeaseManagementConfig |  애플리케이션이 한 번에 스틸을 시도해야 하는 최대 리스 수입니다. KCL 3.x는 이 구성을 무시하고 워커의 리소스 사용률을 기반으로 리스를 재할당합니다.  | 
| enablePriorityLeaseAssignment | LeaseManagementConfig |  대상 리스 수와 관계없이 여전히 최대 리스 한도를 준수하면서 워커가 매우 오래 전에 만료된 리스(장애 조치 시간의 3배 동안 갱신되지 않은 리스) 및 새 샤드 리스를 우선적으로 가져올지 여부를 제어합니다. KCL 3.x는 이 구성을 무시하고 만료된 리스를 항상 워커 간에 분산합니다.  | 

**중요**  
이전 KCL 버전에서 KCL 3.x로 마이그레이션하는 동안에도 중단된 구성 속성이 있어야 합니다. 마이그레이션 중에 KCL 워커는 먼저 KCL 2.x 호환 모드로 시작하고, 애플리케이션의 모든 KCL 워커가 KCL 3.x를 실행할 준비가 되었음을 감지하면 KCL 3.x 기능 모드로 전환합니다. 이러한 중단된 구성은 KCL 워커가 KCL 2.x 호환 모드를 실행하는 동안에 필요합니다.

# KCL 버전 수명 주기 정책
<a name="kcl-version-lifecycle-policy"></a>

이 주제에서는 Amazon Kinesis Client Library(KCL)의 버전 수명 주기 정책을 간략하게 설명합니다.는 새로운 기능 및 개선 사항, 버그 수정, 보안 패치 및 종속성 업데이트를 지원하기 위해 KCL 버전에 대한 새 릴리스를 AWS 정기적으로 제공합니다. 최신 기능, 보안 업데이트, 기본 종속성을 지원하려면 KCL 버전을 최신 상태로 유지하는 것이 좋습니다. 지원되지 않는 KCL 버전은 사용하지 **않는** 것이 좋습니다.

주요 KCL 버전의 수명 주기는 다음 세 단계로 구성됩니다.
+ **일반 가용성(GA)** -이 단계에서는 메이저 버전이 완전히 지원됩니다.는 버그 및 보안 수정뿐만 아니라 Kinesis Data Streams에 대한 새로운 기능 또는 API 업데이트에 대한 지원을 포함하는 일반 마이너 및 패치 버전 릴리스를 AWS 제공합니다.
+ **유지 관리 모드** - 패치 버전 릴리스를 AWS 제한하여 중요한 버그 수정 및 보안 문제만 해결합니다. 메이저 버전은 Kinesis Data Streams의 새 기능 또는 API에 대한 업데이트를 받지 않습니다.
+ **지원 종료** - 메이저 버전은 더 이상 업데이트 또는 릴리스를 받지 않습니다. 이전에 게시된 릴리스는 공개 패키지 관리자를 통해 계속 사용할 수 있으며 코드는 GitHub에 그대로 유지됩니다. 사용자의 재량으로 지원 종료에 도달한 버전을 사용할 수 있습니다. 최신 메이저 버전으로 업그레이드하는 것이 좋습니다.


| 메이저 버전 | 현재 단계 | 릴리스 날짜 | 유지 관리 모드 날짜 | 지원 종료일 | 
| --- | --- | --- | --- | --- | 
| KCL 1.x | 유지 관리 모드 | 2013-12-19 | 2025-04-17 | 2026-01-30 | 
| KCL 2.x | 정식 출시 | 2018-08-02 | -- | -- | 
| KCL 3.x | 정식 출시 | 2024-11-06 | -- | -- | 

# 이전 KCL 버전에서 마이그레이션
<a name="kcl-migration-previous-versions"></a>

이 주제에서는 이전 버전의 Kinesis Client Library(KCL)에서 마이그레이션하는 방법을 설명합니다.

## KCL 3.0의 새로운 기능
<a name="kcl-migration-new-3-0"></a>

Kinesis Client Library(KCL) 3.0은 이전 버전과 비교하여 몇 가지 주요 개선 사항을 도입했습니다.
+  과도하게 사용된 워커에서 소비자 애플리케이션 플릿의 활용도가 낮은 워커로 작업을 자동으로 재배포하여 소비자 애플리케이션의 컴퓨팅 비용을 절감합니다. 이 새로운 로드 밸런싱 알고리즘은 워커 간에 균등하게 분산된 CPU 사용률을 보장하고 워커를 오버프로비저닝할 필요가 없습니다.
+  리스 테이블의 읽기 작업을 최적화하여 KCL과 관련된 DynamoDB 비용이 감소합니다.
+ 현재 워커가 처리한 레코드에 대한 체크포인트를 완료할 수 있게 하여 리스가 다른 워커에게 재할당될 때 데이터의 재처리를 최소화합니다.
+  성능 및 보안 기능을 개선하기 AWS SDK for Java 2.x 위해를 사용하여 AWS SDK for Java 1.x에 대한 종속성을 완전히 제거합니다.

자세한 내용은 [KCL 3.0 릴리스 정보](https://github.com/awslabs/amazon-kinesis-client/blob/master/CHANGELOG.md)를 참조하세요.

**Topics**
+ [KCL 3.0의 새로운 기능](#kcl-migration-new-3-0)
+ [KCL 2.x에서 KCL 3.x로 마이그레이션](kcl-migration-from-2-3.md)
+ [이전 KCL 버전으로 롤백](kcl-migration-rollback.md)
+ [롤백 후 KCL 3.x로 롤포워드](kcl-migration-rollforward.md)
+ [프로비저닝된 용량 모드가 있는 리스 테이블 모범 사례](kcl-migration-lease-table.md)
+ [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md)

# KCL 2.x에서 KCL 3.x로 마이그레이션
<a name="kcl-migration-from-2-3"></a>

이 주제에서는 소비자를 KCL 2.x에서 KCL 3.x로 마이그레이션하는 단계별 지침을 제공합니다. KCL 3.x는 KCL 2.x 소비자의 인플레이스 마이그레이션을 지원합니다. 워커를 롤링 방식으로 마이그레이션하면서 Kinesis 데이터 스트림의 데이터를 계속 사용할 수 있습니다.

**중요**  
KCL 3.x는 KCL 2.x와 인터페이스와 메서드를 동일하게 유지합니다. 따라서 마이그레이션 중에 레코드 처리 코드를 업데이트할 필요가 없습니다. 그러나 적절한 구성을 설정하고 마이그레이션에 필요한 단계를 확인해야 합니다. 원활한 마이그레이션 경험을 위해 다음 마이그레이션 단계를 따르는 것이 좋습니다.

## 1단계: 사전 조건
<a name="kcl-migration-from-2-3-prerequisites"></a>

KCL 3.x를 사용하여 시작하기 전에 다음이 있는지 확인합니다.
+ Java Development Kit(JDK) 8 이상
+ AWS SDK for Java 2.x
+ 종속성 관리를 위한 Maven 또는 Gradle

**중요**  
KCL 3.x에서는 AWS SDK for Java 버전 2.27.19\$12.27.23을 사용하지 마십시오. 이러한 버전에는 KCL의 DynamoDB 사용과 관련된 예외 오류가 발생하는 문제가 포함되어 있습니다. 이 문제를 방지하려면 AWS SDK for Java 버전 2.28.0 이상을 사용하는 것이 좋습니다.

## 2단계: 종속성 추가
<a name="kcl-migration-from-2-3-dependencies"></a>

Maven을 사용하는 경우 `pom.xml` 파일에 다음 종속성을 추가합니다. 3.x.x를 최신 KCL 버전으로 교체했는지 확인합니다.

```
<dependency>
    <groupId>software.amazon.kinesis</groupId>
    <artifactId>amazon-kinesis-client</artifactId>
    <version>3.x.x</version> <!-- Use the latest version -->
</dependency>
```

Gradle을 사용하는 경우 `build.gradle` 파일에 다음을 추가합니다. 3.x.x를 최신 KCL 버전으로 교체했는지 확인합니다.

```
implementation 'software.amazon.kinesis:amazon-kinesis-client:3.x.x'
```

[Maven Central Repository](https://search.maven.org/artifact/software.amazon.kinesis/amazon-kinesis-client)에서 KCL의 최신 버전을 확인할 수 있습니다.

## 3단계: 마이그레이션 관련 구성 설정
<a name="kcl-migration-from-2-3-configuration"></a>

KCL 2.x에서 KCL 3.x로 마이그레이션하려면 다음 구성 파라미터를 설정해야 합니다.
+ CoordinatorConfig.clientVersionConfig: 이 구성은 애플리케이션을 실행할 KCL 버전 호환성 모드를 결정합니다. KCL 2.x에서 3.x로 마이그레이션할 때는 이 구성을 `CLIENT_VERSION_CONFIG_COMPATIBLE_WITH_2X`로 설정해야 합니다. 이 구성을 설정하려면 스케줄러 객체를 생성할 때 다음 줄을 추가합니다.

```
configsBuilder.coordiantorConfig().clientVersionConfig(ClientVersionConfig.CLIENT_VERSION_CONFIG_COMPLATIBLE_WITH_2X)
```

다음은 KCL 2.x에서 3.x로 마이그레이션하기 위해 `CoordinatorConfig.clientVersionConfig`를 설정하는 방법을 보여주는 예제입니다. 특정 요구 사항을 바탕으로 필요에 따라 다른 구성을 조정할 수 있습니다.

```
Scheduler scheduler = new Scheduler(
    configsBuilder.checkpointConfig(),
    configsBuilder.coordiantorConfig().clientVersionConfig(ClientVersionConfig.CLIENT_VERSION_CONFIG_COMPLATIBLE_WITH_2X),
    configsBuilder.leaseManagementConfig(),
    configsBuilder.lifecycleConfig(),
    configsBuilder.metricsConfig(),
    configsBuilder.processorConfig(),
    configsBuilder.retrievalConfig()
);
```

소비자 애플리케이션의 모든 워커가 특정 시점에 동일한 로드 밸런싱 알고리즘을 사용해야 합니다. KCL 2.x 및 3.x가 서로 다른 로드 밸런싱 알고리즘을 사용하기 때문입니다. 서로 다른 로드 밸런싱 알고리즘으로 워커를 실행하면 두 알고리즘이 독립적으로 작동하므로 로드 분산이 최적화되지 않을 수 있습니다.

이 KCL 2.x 호환성 설정을 사용하면 KCL 3.x 애플리케이션이 KCL 2.x와 호환되는 모드에서 실행되고, 소비자 애플리케이션의 모든 워커가 KCL 3.x로 업그레이드될 때까지 KCL 2.x에서 로드 밸런싱 알고리즘을 사용할 수 있습니다. 마이그레이션이 완료되면 KCL이 자동으로 전체 KCL 3.x 기능 모드로 전환하고 실행 중인 모든 워커에 대해 새 KCL 3.x 로드 밸런싱 알고리즘을 사용하기 시작합니다.

**중요**  
`ConfigsBuilder`를 사용하지 않고 `LeaseManagementConfig` 객체를 생성하여 구성을 설정하는 경우 KCL 버전 3.x 이상에서 `applicationName`이라는 파라미터를 하나 더 추가해야 합니다. 자세한 내용은 [Compilation error with the LeaseManagementConfig constructor](https://docs.aws.amazon.com/streams/latest/dev/troubleshooting-consumers.html#compiliation-error-leasemanagementconfig) 섹션을 참조하세요. `ConfigsBuilder`를 사용하여 KCL 구성을 설정하는 것이 좋습니다. `ConfigsBuilder`는 KCL 애플리케이션을 구성하는 더 유연하고 유지 관리 가능한 방법을 제공합니다.

## 4단계: shutdownRequested() 메서드 구현 모범 사례 준수
<a name="kcl-migration-from-2-3-best-practice"></a>

KCL 3.x는 리스가 리스 재할당 프로세스의 일부로 다른 워커에게 인계될 때 데이터의 재처리를 최소화하기 위해 *정상적인 리스 핸드오프*라는 기능을 도입합니다. 이는 리스 핸드오프 전에 리스 테이블에서 마지막으로 처리된 시퀀스 번호를 체크포인트하여 달성됩니다. 정상적인 리스 핸드오프가 제대로 작동하려면 `RecordProcessor` 클래스의 `shutdownRequested` 메서드 내에서 `checkpointer` 객체를 간접 호출해야 합니다. `shutdownRequested` 메서드 내에서 `checkpointer` 객체를 간접 호출하지 않는 경우 다음 예제와 같이 구현할 수 있습니다.

**중요**  
다음 구현 예제는 정상적인 리스 핸드오프를 위한 최소 요구 사항입니다. 필요한 경우 체크포인트와 관련된 추가 로직을 포함하도록 확장할 수 있습니다. 비동기 처리를 수행하는 경우 체크포인트를 간접 호출하기 전에 다운스트림으로 전송된 모든 레코드가 처리되었는지 확인합니다.
정상적인 리스 핸드오프는 리스 전송 중 데이터 재처리 가능성을 대폭 줄여주지만 이러한 가능성을 완전히 제거하지는 않습니다. 데이터 무결성과 일관성을 유지하려면 다운스트림 소비자 애플리케이션을 멱등성이 있도록 설계합니다. 즉, 전체 시스템에 부정적인 영향을 주지 않으면서 잠재적인 중복 레코드 처리 문제를 처리할 수 있어야 합니다.

```
/**
 * Invoked when either Scheduler has been requested to gracefully shutdown
 * or lease ownership is being transferred gracefully so the current owner
 * gets one last chance to checkpoint.
 *
 * Checkpoints and logs the data a final time.
 *
 * @param shutdownRequestedInput Provides access to a checkpointer, allowing a record processor to checkpoint
 *                               before the shutdown is completed.
 */
public void shutdownRequested(ShutdownRequestedInput shutdownRequestedInput) {
    try {
       // Ensure that all delivered records are processed 
       // and has been successfully flushed to the downstream before calling 
       // checkpoint
       // If you are performing any asynchronous processing or flushing to
       // downstream, you must wait for its completion before invoking
       // the below checkpoint method.
        log.info("Scheduler is shutting down, checkpointing.");
        shutdownRequestedInput.checkpointer().checkpoint();
    } catch (ShutdownException | InvalidStateException e) {
        log.error("Exception while checkpointing at requested shutdown. Giving up.", e);
    } 
}
```

## 5단계: 워커 지표 수집을 위한 KCL 3.x 사전 조건 확인
<a name="kcl-migration-from-2-3-worker-metrics"></a>

KCL 3.x는 워커의 CPU 사용률과 같은 CPU 사용률 지표를 수집하여 워커 간에 로드를 균등하게 분산합니다. 소비자 애플리케이션 워커는 Amazon EC2, Amazon ECS, Amazon EKS 또는 AWS Fargate에서 실행할 수 있습니다. KCL 3.x는 다음 사전 조건이 충족되는 경우에만 워커로부터 CPU 사용률 지표를 수집할 수 있습니다.

 **Amazon Elastic Compute Cloud(Amazon EC2)**
+ 운영 체제는 Linux OS여야 합니다.
+ EC2 인스턴스에서 [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)를 활성화해야 합니다.

 **Amazon EC2의 Amazon Elastic Container Service(Amazon ECS)**
+ 운영 체제는 Linux OS여야 합니다.
+ [ECS 작업 메타데이터 엔드포인트 버전 4](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ec2-metadata.html)를 활성화해야 합니다.
+ Amazon ECS 컨테이너 에이전트 버전은 1.39.0 이상이어야 합니다.

 **의 Amazon ECS AWS Fargate**
+ [Fargate 작업 메타데이터 엔드포인트 버전 4](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v4-fargate.html)를 활성화해야 합니다. Fargate 플랫폼 버전 1.4.0 이상을 사용하는 경우 기본적으로 활성화됩니다.
+ Fargate 플랫폼 버전 1.4.0 이상.

 **Amazon EC2의 Amazon Elastic Kubernetes Service(Amazon EKS)** 
+ 운영 체제는 Linux OS여야 합니다.

 **의 Amazon EKS AWS Fargate**
+ Fargate 플랫폼 버전 1.3.0 이상.

**중요**  
사전 조건이 충족되지 않아 KCL 3.x가 워커로부터 CPU 사용률 지표를 수집할 수 없는 경우, 리스당 처리량 수준의 로드가 재조정됩니다. 이 폴백 리밸런싱 메커니즘을 사용하면 모든 워커가 각 워커에게 할당된 리스에서 유사한 총 처리량 수준을 얻게 됩니다. 자세한 내용은 [KCL이 워커에게 리스를 할당하고 로드의 균형을 조정하는 방법](kcl-dynamoDB.md#kcl-assign-leases) 단원을 참조하십시오.

## 6단계: KCL 3.x에 대한 IAM 권한 업데이트
<a name="kcl-migration-from-2-3-IAM-permissions"></a>

KCL 3.x 소비자 애플리케이션과 연결된 IAM 역할 또는 정책에 다음 권한을 추가해야 합니다. 여기에는 KCL 애플리케이션에서 사용하는 기존 IAM 정책 업데이트가 포함됩니다. 자세한 내용은 [KCL 소비자 애플리케이션에 필요한 IAM 권한](kcl-iam-permissions.md) 단원을 참조하십시오.

**중요**  
기존 KCL 애플리케이션의 경우 KCL 2.x에서는 필요하지 않았기 때문에 IAM 정책에 다음 IAM 작업 및 리소스가 추가되지 않았을 수 있습니다. KCL 3.x 애플리케이션을 실행하기 전에 다음 항목을 추가했는지 확인합니다.  
작업: `UpdateTable`  
리소스(ARN): `arn:aws:dynamodb:region:account:table/KCLApplicationName`
작업: `Query`  
리소스(ARN): `arn:aws:dynamodb:region:account:table/KCLApplicationName/index/*`
작업: `CreateTable`, `DescribeTable`, `Scan`, `GetItem`, `PutItem`, `UpdateItem`, `DeleteItem`   
리소스(ARN): `arn:aws:dynamodb:region:account:table/KCLApplicationName-WorkerMetricStats`, `arn:aws:dynamodb:region:account:table/KCLApplicationName-CoordinatorState` 
ARNs의 "리전", "계정" 및 "KCLApplicationName"을 각각 자체, AWS 리전 AWS 계정 숫자 및 KCL 애플리케이션 이름으로 바꿉니다. 구성을 사용하여 KCL에서 생성한 메타데이터 테이블의 이름을 사용자 지정하는 경우 KCL 애플리케이션 이름 대신 지정된 테이블 이름을 사용합니다.

## 7단계: 워커에 KCL 3.x 코드 배포
<a name="kcl-migration-from-2-3-IAM-deploy"></a>

마이그레이션에 필요한 구성을 설정하고 이전 마이그레이션 체크리스트를 모두 완료한 후 코드를 빌드하여 워커에게 배포할 수 있습니다.

**참고**  
`LeaseManagementConfig` 생성자에 컴파일 오류가 표시되는 경우 문제 해결 정보는 [ Compilation error with the LeaseManagementConfig constructor](https://docs.aws.amazon.com/streams/latest/dev/troubleshooting-consumers.html#compilation-error-leasemanagementconfig) 섹션을 참조하세요.

## 8단계: 마이그레이션 완료
<a name="kcl-migration-from-2-3-finish"></a>

KCL 3.x 코드를 배포하는 동안 KCL은 KCL 2.x의 리스 할당 알고리즘을 계속 사용합니다. 모든 워커에게 KCL 3.x 코드를 성공적으로 배포하면 KCL에서 이를 자동으로 감지하고 워커의 리소스 사용률을 기반으로 새 리스 할당 알고리즘으로 전환합니다. 새 리스 할당 알고리즘에 대한 자세한 내용은 [KCL이 워커에게 리스를 할당하고 로드의 균형을 조정하는 방법](kcl-dynamoDB.md#kcl-assign-leases) 섹션을 참조하세요.

배포 중에 CloudWatch에 내보낸 다음 지표를 사용하여 마이그레이션 프로세스를 모니터링할 수 있습니다. `Migration` 작업에서 지표를 모니터링할 수 있습니다. 모든 지표는 KCL 애플리케이션별 지표이며 `SUMMARY` 지표 수준으로 설정됩니다. `CurrentState:3xWorker` 지표의 `Sum` 통계가 KCL 애플리케이션의 총 워커 수와 일치하면 KCL 3.x로의 마이그레이션이 성공적으로 완료된 것입니다.

**중요**  
 모든 워커가 새 리스 할당 알고리즘을 실행할 준비가 된 후, KCL이 새 리스 할당 알고리즘으로 전환하는 데 최소 10분이 걸립니다.


**KCL 마이그레이션 프로세스에 대한 CloudWatch 지표**  

| Metrics | 설명 | 
| --- | --- | 
| CurrentState:3xWorker |  성공적으로 KCL 3.x로 마이그레이션되고 새 리스 할당 알고리즘을 실행하는 KCL 워커 수입니다. 이 지표의 `Sum` 수가 총 워커 수와 일치하면 KCL 3.x로의 마이그레이션이 성공적으로 완료된 것입니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/kcl-migration-from-2-3.html)  | 
| CurrentState:2xCompatibleWorker |  마이그레이션 프로세스 중에 KCL 2.x 호환 모드에서 실행되는 KCL 워커 수입니다. 이 지표의 값이 0이 아니면 마이그레이션이 아직 진행 중임을 나타냅니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/kcl-migration-from-2-3.html)  | 
| Fault |  마이그레이션 프로세스 중에 발생한 예외 수입니다. 이러한 예외의 대부분은 일시적인 오류이며 KCL 3.x는 마이그레이션을 완료하기 위해 자동으로 재시도합니다. 영구 `Fault` 지표 값이 관찰되면 추가 문제 해결을 위해 마이그레이션 기간의 로그를 검토합니다. 문제가 계속되면에 문의하십시오 지원. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/kcl-migration-from-2-3.html)  | 
| GsiStatusReady |  리스 테이블에서 글로벌 보조 인덱스(GSI) 생성의 상태입니다. 이 지표는 KCL 3.x를 실행하기 위한 사전 조건인 리스 테이블의 GSI 생성 여부를 나타냅니다. 값은 0 또는 1이며, 1은 생성 성공을 의미합니다. 롤백 상태에서는 이 지표가 내보내지지 않습니다. 다시 롤포워드한 후 이 지표의 모니터링을 재개할 수 있습니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/kcl-migration-from-2-3.html)  | 
| workerMetricsReady |  모든 워커의 워커 지표 내보내기 상태입니다. 지표는 모든 워커가 CPU 사용률과 같은 지표를 내보내고 있는지 여부를 나타냅니다. 값은 0 또는 1이며, 1은 모든 워커가 지표를 성공적으로 내보내고 새 리스 할당 알고리즘을 사용할 준비가 되었음을 의미합니다. 롤백 상태에서는 이 지표가 내보내지지 않습니다. 다시 롤포워드한 후 이 지표의 모니터링을 재개할 수 있습니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/kcl-migration-from-2-3.html)  | 

KCL은 마이그레이션 중에 2.x 호환 모드로 롤백 기능을 제공합니다. KCL 3.x로 성공적으로 마이그레이션한 후에는 롤백이 더 이상 필요하지 않은 경우, `CLIENT_VERSION_CONFIG_COMPATIBLE_WITH_2X`의 `CoordinatorConfig.clientVersionConfig` 설정을 제거하는 것이 좋습니다. 이 구성을 제거하면 KCL 애플리케이션에서 마이그레이션 관련 지표의 내보내기가 중지됩니다.

**참고**  
마이그레이션 중 및 마이그레이션 완료 후 일정 기간 동안 애플리케이션의 성능과 안정성을 모니터링하는 것이 좋습니다. 문제가 발견되면 [KCL 마이그레이션 도구](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/scripts/KclMigrationTool.py)를 사용하여 워커를 롤백하고 KCL 2.x 호환 기능을 사용할 수 있습니다.

# 이전 KCL 버전으로 롤백
<a name="kcl-migration-rollback"></a>

이 주제에서는 소비자를 이전 버전으로 롤백하는 단계를 설명합니다. 롤백해야 하는 경우 2단계 프로세스는 다음과 같습니다.

1. [KCL 마이그레이션 도구](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/scripts/KclMigrationTool.py)를 실행합니다.

1. 이전 KCL 버전 코드를 재배포합니다(선택 사항).

## 1단계: KCL 마이그레이션 도구 실행
<a name="kcl-migration-rollback-tool"></a>

이전 KCL 버전으로 롤백해야 하는 경우 KCL 마이그레이션 도구를 실행해야 합니다. KCL 마이그레이션 도구는 두 가지 중요한 작업을 수행합니다.
+ DynamoDB의 리스 테이블에서 워커 지표 테이블이라고 하는 메타데이터 테이블과 글로벌 보조 인덱스를 제거합니다. 이러한 두 아티팩트는 KCL 3.x에서 생성되지만 이전 버전으로 롤백하는 경우 필요하지 않습니다.
+ 따라서 모든 작업자가 KCL 2.x와 호환되는 모드에서 실행되고 이전 KCL 버전에서 사용되는 로드 밸런싱 알고리즘을 사용하기 시작합니다. KCL 3.x의 새 로드 밸런싱 알고리즘에 문제가 있는 경우 해당 문제를 즉시 완화합니다.

**중요**  
DynamoDB의 조정자 상태 테이블은 반드시 존재해야 하며 마이그레이션, 롤백, 롤포워드 프로세스 중에 삭제되어서는 안 됩니다.

**참고**  
소비자 애플리케이션의 모든 워커가 지정된 시간에 동일한 로드 밸런싱 알고리즘을 사용하는 것이 중요합니다. KCL 마이그레이션 도구를 사용하면 KCL 3.x 소비자 애플리케이션의 모든 워커가 KCL 2.x 호환 모드로 전환되므로 이전 KCL 버전으로 배포를 롤백하는 동안 모든 워커가 동일한 로드 밸런싱 알고리즘을 실행하게 됩니다.

[KCL GitHub 리포지토리](https://github.com/awslabs/amazon-kinesis-client/tree/master)의 스크립트 디렉터리에서 [KCL 마이그레이션 도구](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/scripts/KclMigrationTool.py)를 다운로드할 수 있습니다. 스크립트는 조정자 상태 테이블에 쓰고, 워커 지표 테이블을 삭제하고, 리스 테이블을 업데이트하는 데 필요한 권한이 있는 모든 워커 또는 호스트에서 실행할 수 있습니다. 스크립트를 실행하는 데 필요한 IAM 권한은 [KCL 소비자 애플리케이션에 필요한 IAM 권한](kcl-iam-permissions.md) 섹션을 참조하세요. KCL 애플리케이션당 한 번만 스크립트를 실행해야 합니다. 다음 명령을 사용하여 KCL 마이그레이션 도구를 실행할 수 있습니다.

```
python3 ./KclMigrationTool.py --region <region> --mode rollback [--application_name <applicationName>] [--lease_table_name <leaseTableName>] [--coordinator_state_table_name <coordinatorStateTableName>] [--worker_metrics_table_name <workerMetricsTableName>]
```

**파라미터**
+ --region:를 `<region>`로 바꿉니다 AWS 리전.
+ --application\$1name: 이 파라미터는 DynamoDB 메타데이터 테이블(리스 테이블, 조정자 상태 테이블, 워커 지표 테이블)의 기본 이름을 사용하는 경우 필요합니다. 이러한 테이블에 사용자 지정 이름을 지정한 경우 이 파라미터를 생략할 수 있습니다. `<applicationName>`을 실제 KCL 애플리케이션 이름으로 바꿉니다. 이 도구는 사용자 지정 이름이 제공되지 않은 경우 이 이름을 사용하여 기본 테이블 이름을 파생합니다.
+ --lease\$1table\$1name(선택 사항): 이 파라미터는 KCL 구성에서 리스 테이블에 사용자 지정 이름을 설정한 경우에 필요합니다. 기본 테이블 이름을 사용하는 경우 이 파라미터를 생략할 수 있습니다. `leaseTableName`을 리스 테이블에 지정한 사용자 지정 테이블 이름으로 바꿉니다.
+ --coordinator\$1state\$1table\$1name(선택 사항): 이 파라미터는 KCL 구성에서 조정자 상태 테이블에 사용자 지정 이름을 설정한 경우에 필요합니다. 기본 테이블 이름을 사용하는 경우 이 파라미터를 생략할 수 있습니다. `<coordinatorStateTableName>`을 조정자 상태 테이블에 지정한 사용자 지정 테이블 이름으로 바꿉니다.
+ --worker\$1metrics\$1table\$1name(선택 사항): 이 파라미터는 KCL 구성에서 워커 지표 테이블에 사용자 지정 이름을 설정한 경우에 필요합니다. 기본 테이블 이름을 사용하는 경우 이 파라미터를 생략할 수 있습니다. `<workerMetricsTableName>`을 워커 지표 테이블에 지정한 사용자 지정 테이블 이름으로 바꿉니다.

## 2단계: 이전 KCL 버전으로 코드 재배포(선택 사항)
<a name="kcl-migration-rollback-redeploy"></a>

 롤백을 위해 KCL 마이그레이션 도구를 실행하면 다음 메시지 중 하나가 표시됩니다.
+ **메시지 1:** “롤백이 완료되었습니다. KCL 애플리케이션이 KCL 2.x 호환 모드로 실행되고 있었습니다. 회귀 문제가 완화되지 않는다면 이전 KCL 버전의 코드를 재배포하여 이전 애플리케이션 바이너리로 롤백하세요.”
  + **필수 작업: **이는 작업자가 KCL 2.x 호환 모드에서 실행 중이었음을 의미합니다. 문제가 지속되면 이전 KCL 버전으로 워커에 코드를 재배포합니다.
+ **메시지 2:** “롤백이 완료되었습니다. KCL 애플리케이션이 KCL 3.x 기능 모드로 실행되고 있었습니다. 문제가 5분 이내에 완화되지 않는 경우를 제외하고 이전 애플리케이션 바이너리로 롤백할 필요가 없습니다. 문제가 지속되면 이전 KCL 버전의 코드를 재배포하여 이전 애플리케이션 바이너리로 롤백하세요.”
  + **필요한 작업: **작업자가 KCL 3.x 모드에서 실행 중이었고 KCL 마이그레이션 도구가 모든 작업자를 KCL 2.x 호환 모드로 전환했음을 의미합니다. 문제가 해결되면 이전 KCL 버전으로 코드를 재배포할 필요가 없습니다. 문제가 지속되면 이전 KCL 버전으로 워커에 코드를 재배포합니다.

 

# 롤백 후 KCL 3.x로 롤포워드
<a name="kcl-migration-rollforward"></a>

이 주제에서는 롤백 후 소비자를 KCL 3.x로 롤포워드하는 단계를 설명합니다. 롤포워드가 필요한 경우 2단계 프로세스를 진행해야 합니다.

1. [KCL 마이그레이션 도구](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/scripts/KclMigrationTool.py)를 실행합니다.

1. KCL 3.x로 코드를 배포합니다.

## 1단계: KCL 마이그레이션 도구 실행
<a name="kcl-migration-rollback-tool"></a>

KCL 마이그레이션 도구를 실행합니다. 다음 명령으로 KCL 마이그레이션 도구를 사용하여 KCL 3.x로 롤포워드합니다.

```
python3 ./KclMigrationTool.py --region <region> --mode rollforward [--application_name <applicationName>] [--coordinator_state_table_name <coordinatorStateTableName>]
```

**파라미터**
+ --region:를 `<region>`로 바꿉니다 AWS 리전.
+ --application\$1name: 조정자 상태 테이블에 기본 이름을 사용하는 경우 이 파라미터가 필요합니다. 조정자 상태 테이블에 사용자 지정 이름을 지정한 경우 이 파라미터를 생략할 수 있습니다. `<applicationName>`을 실제 KCL 애플리케이션 이름으로 바꿉니다. 이 도구는 사용자 지정 이름이 제공되지 않은 경우 이 이름을 사용하여 기본 테이블 이름을 파생합니다.
+ --coordinator\$1state\$1table\$1name(선택 사항): 이 파라미터는 KCL 구성에서 조정자 상태 테이블에 사용자 지정 이름을 설정한 경우에 필요합니다. 기본 테이블 이름을 사용하는 경우 이 파라미터를 생략할 수 있습니다. `<coordinatorStateTableName>`을 조정자 상태 테이블에 지정한 사용자 지정 테이블 이름으로 바꿉니다.

롤포워드 모드로 마이그레이션 도구를 실행한 후 KCL은 KCL 3.x에 필요한 다음과 같은 DynamoDB 리소스를 생성합니다.
+ 리스 테이블의 글로벌 보조 인덱스
+ 워커 지표 테이블

## 2단계: KCL 3.x로 코드 배포
<a name="kcl-migration-rollback-redeploy"></a>

롤포워드를 위해 KCL 마이그레이션 도구를 실행한 후 KCL 3.x로 워커에 코드를 배포합니다. [8단계: 마이그레이션 완료](kcl-migration-from-2-3.md#kcl-migration-from-2-3-finish)에 따라 마이그레이션을 완료합니다.

# 프로비저닝된 용량 모드가 있는 리스 테이블 모범 사례
<a name="kcl-migration-lease-table"></a>

KCL 애플리케이션의 리스 테이블이 프로비저닝된 용량 모드로 전환된 경우, KCL 3.x는 프로비저닝된 결제 모드와 기본 리스 테이블과 동일한 읽기 용량 단위(RCU) 및 쓰기 용량 단위(WCU)를 사용하여 리스 테이블에 글로벌 보조 인덱스를 생성합니다. 글로벌 보조 인덱스가 생성되면 DynamoDB 콘솔에서 글로벌 보조 인덱스의 실제 사용량을 모니터링하고 필요에 따라 용량 단위를 조정하는 것이 좋습니다. KCL에서 생성한 DynamoDB 메타데이터 테이블의 용량 모드 전환에 대한 자세한 가이드는 [KCL에서 생성한 메타데이터 테이블의 DynamoDB 용량 모드](kcl-dynamoDB.md#kcl-capacity-mode) 섹션을 참조하세요.

**참고**  
기본적으로 KCL은 온디맨드 용량 모드를 사용하여 리스 테이블, 워커 지표 테이블, 조정자 상태 테이블, 리스 테이블의 글로벌 보조 인덱스와 같은 메타데이터 테이블을 생성합니다. 사용량의 변화에 따라 용량을 자동으로 조정하려면 온디맨드 용량 모드를 사용하는 것이 좋습니다.

# KCL 1.x에서 KCL 3.x로 마이그레이션
<a name="kcl-migration-1-3"></a>

이 주제에서는 소비자를 KCL 1.x에서 KCL 3.x로 마이그레이션하는 지침을 설명합니다. KCL 1.x는 KCL 2.x 및 KCL 3.x와 다른 클래스와 인터페이스를 사용합니다. 먼저 레코드 프로세서, 레코드 프로세서 팩토리, 워커 클래스를 KCL 2.x/3.x 호환 형식으로 마이그레이션하고 KCL 2.x에서 KCL 3.x로 마이그레이션하는 단계를 따라야 합니다. 바로 KCL 1.x에서 KCL 3.x로 업그레이드할 수 있습니다.
+ **1단계: 레코드 프로세서 마이그레이션**

  [Migrate consumers from KCL 1.x to KCL 2.x](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-migration) 페이지의 [Migrate the record processor](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-migration) 섹션을 따릅니다.
+ **2단계: 레코드 프로세서 팩토리 마이그레이션**

  [Migrate consumers from KCL 1.x to KCL 2.x](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-migration) 페이지의 [Migrate the record processor factory](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-factory-migration) 섹션을 따릅니다.
+ **3단계: 작업자 마이그레이션**

  [Migrate consumers from KCL 1.x to KCL 2.x](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-migration) 페이지의 [Migrate the worker](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#worker-migration) 섹션을 따릅니다.
+ **4단계: KCL 1.x 구성 마이그레이션**

  [Migrate consumers from KCL 1.x to KCL 2.x](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-migration) 페이지의 [Configure the Amazon Kinesis client](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#client-configuration) 섹션을 따릅니다.
+ **5단계: 유휴 시간 제거 및 클라이언트 구성 제거 확인**

  [Migrate consumers from KCL 1.x to KCL 2.x](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#recrod-processor-migration) 페이지의 [Idle time removal](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#idle-time-removal) 및 [Client configuration removals](https://docs.aws.amazon.com/streams/latest/dev/kcl-migration.html#client-configuration-removals) 섹션을 따릅니다.
+ **6단계: KCL 2.x에서 KCL 3.x로 마이그레이션 가이드의 단계별 지침 수행**

  [KCL 2.x에서 KCL 3.x로 마이그레이션](kcl-migration-from-2-3.md) 페이지의 지침에 따라 마이그레이션을 완료합니다. 롤백 후 이전 KCL 버전으로 롤백하거나 KCL 3.x로 롤포워드해야 하는 경우 [이전 KCL 버전으로 롤백](kcl-migration-rollback.md) 및 [롤백 후 KCL 3.x로 롤포워드](kcl-migration-rollforward.md) 섹션을 참조하세요.

**중요**  
KCL 3.x에서는 AWS SDK for Java 버전 2.27.19\$12.27.23을 사용하지 마십시오. 이러한 버전에는 KCL의 DynamoDB 사용과 관련된 예외 오류가 발생하는 문제가 포함되어 있습니다. 이 문제를 방지하려면 AWS SDK for Java 버전 2.28.0 이상을 사용하는 것이 좋습니다.

# 이전 KCL 버전 설명서
<a name="kcl-archive"></a>

다음 주제가 아카이브되었습니다. 최신 Kinesis Client Library 설명서는 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요.

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

**Topics**
+ [KCL 1.x 및 2.x 정보](shared-throughput-kcl-consumers.md)
+ [공유 처리량으로 사용자 지정 소비자 개발](shared-throughput-consumers.md)
+ [KCL 1.x에서 KCL 2.x로 소비자 마이그레이션](kcl-migration.md)

# KCL 1.x 및 2.x 정보
<a name="shared-throughput-kcl-consumers"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

KDS 데이터 스트림의 데이터를 처리할 수 있는 사용자 지정 소비자 애플리케이션을 개발하는 방법 중 하나는 Kinesis Client Library(KCL)를 사용하는 것입니다.

**Topics**
+ [KCL 정보(이전 버전)](#shared-throughput-kcl-consumers-overview)
+ [KCL 이전 버전](#shared-throughput-kcl-consumers-versions)
+ [KCL 개념(이전 버전)](#shared-throughput-kcl-consumers-concepts)
+ [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](#shared-throughput-kcl-consumers-leasetable)
+ [동일한 KCL 2.x for Java 소비자 애플리케이션으로 여러 데이터 스트림 처리](#shared-throughput-kcl-multistream)
+ [AWS Glue 스키마 레지스트리와 함께 KCL 사용](#shared-throughput-kcl-consumers-glue-schema-registry)

**참고**  
KCL 1.x와 KCL 2.x 모두 사용 시나리오에 따라 최신 KCL 1.x 버전 또는 KCL 2.x 버전으로 업그레이드하는 것이 좋습니다. KCL 1.x와 KCL 2.x 모두 최신 종속성 및 보안 패치, 버그 수정, 이전 버전과 호환되는 새 기능이 포함된 최신 릴리스로 정기적으로 업데이트됩니다. 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/releases](https://github.com/awslabs/amazon-kinesis-client/releases)를 참조하세요.

## KCL 정보(이전 버전)
<a name="shared-throughput-kcl-consumers-overview"></a>

KCL을 사용하면 분산 컴퓨팅과 관련된 많은 복잡한 작업을 처리하여 Kinesis 데이터 스트림의 데이터를 사용하고 처리할 수 있습니다. 여기에는 여러 소비자 애플리케이션 인스턴스 간의 로드 밸런싱, 소비자 애플리케이션 인스턴스 장애 대응, 처리된 레코드 체크포인트 및 리샤딩 대응이 포함됩니다. 사용자가 사용자 지정 레코드 처리 로직을 작성하는 데 집중할 수 있도록 KCL이 이러한 하위 작업을 모두 처리합니다.

KCL은 AWS SDK에서 사용할 수 있는 Kinesis Data Streams API와 다릅니다. Kinesis Data Streams API는 스트림 생성, 리샤딩, 레코드 넣기 및 가져오기를 비롯한 Kinesis Data Streams의 여러 측면을 관리하는 데 도움이 됩니다. 특히 사용자가 소비자 애플리케이션의 사용자 지정 데이터 처리 로직에 집중할 수 있도록 KCL은 이러한 모든 하위 작업에 대한 추상화 계층을 제공합니다. Kinesis Data Streams API에 대한 자세한 내용은 [Amazon Kinesis API 참조](https://docs.aws.amazon.com/kinesis/latest/APIReference/Welcome.html)를 확인하세요.

**중요**  
KCL은 Java 라이브러리입니다. MultiLangDaemon이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 데몬은 Java 기반이며, Java 이외의 KCL 언어를 사용하는 경우 배경에서 실행됩니다. 예를 들어, Python용 KCL을 설치하고 Python으로만 소비자 애플리케이션을 작성한 경우에도 MultiLangDaemon 때문에 시스템에 Java를 설치해야 합니다. 또한 MultiLangDaemon에는 연결된 AWS 리전과 같이 사용 사례에 맞게 사용자 지정해야 할 몇 가지 기본 설정이 있습니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang)를 참조하세요.

KCL은 레코드 처리 로직과 Kinesis Data Streams 간에 중간 역할을 합니다.

## KCL 이전 버전
<a name="shared-throughput-kcl-consumers-versions"></a>

현재 지원되는 다음 KCL 버전 중 하나를 사용하여 사용자 지정 소비자 애플리케이션을 구축할 수 있습니다.
+ **KCL 1.x**

  자세한 내용은 [KCL 1.x 소비자 개발](developing-consumers-with-kcl.md) 섹션을 참조하세요.
+ **KCL 2.x**

  자세한 내용은 [KCL 2.x 소비자 개발](developing-consumers-with-kcl-v2.md) 섹션을 참조하세요.

KCL 1.x 또는 KCL 2.x를 사용하여 공유 처리량을 사용하는 소비자 애플리케이션을 구축할 수 있습니다. 자세한 내용은 [KCL를 사용하여 공유 처리량으로 사용자 지정 소비자 개발](custom-kcl-consumers.md) 단원을 참조하십시오.

전용 처리량을 사용하는 소비자 애플리케이션(향상된 팬아웃 소비자)을 구축하려면 KCL 2.x만 사용할 수 있습니다. 자세한 내용은 [전용 처리량으로 향상된 팬아웃 소비자 개발](enhanced-consumers.md) 단원을 참조하십시오.

KCL 1.x와 KCL 2.x의 차이점에 대한 자세한 내용과 KCL 1.x에서 KCL 2.x로 마이그레이션하는 방법에 대한 지침은 [KCL 1.x에서 KCL 2.x로 소비자 마이그레이션](kcl-migration.md) 섹션을 참조하세요.

## KCL 개념(이전 버전)
<a name="shared-throughput-kcl-consumers-concepts"></a>
+ **KCL 소비자 애플리케이션** - KCL을 사용하여 맞춤 구축되고 데이터 스트림에서 레코드를 읽고 처리하도록 설계된 애플리케이션입니다.
+ **소비자 애플리케이션 인스턴스** - KCL 소비자 애플리케이션은 일반적으로 장애를 조정하고 데이터 레코드 처리를 동적으로 로드 밸런싱하기 위해 하나 이상의 애플리케이션 인스턴스가 동시에 실행되는 분산형입니다.
+ **워커** - KCL 소비자 애플리케이션 인스턴스가 데이터 처리를 시작하는 데 사용하는 상위 수준 클래스입니다.
**중요**  
KCL 소비자 애플리케이션 인스턴스마다 워커가 하나씩 있습니다.

  워커는 샤드 및 리스 정보 동기화, 샤드 할당 추적, 샤드의 데이터 처리 등 다양한 작업을 초기화하고 감독합니다. 작업자는이 KCL 소비자 애플리케이션이 처리할 데이터를 기록하는 데이터 스트림의 이름과이 데이터 스트림에 액세스하는 데 필요한 AWS 자격 증명과 같은 소비자 애플리케이션에 대한 구성 정보를 KCL에 제공합니다. 또한 워커는 데이터 스트림에서 레코드 프로세서로 데이터 레코드를 전송하기 위해 특정 KCL 소비자 애플리케이션 인스턴스를 시작합니다.
**중요**  
KCL 1.x에서는 이 클래스를 **워커**라고 합니다. 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/v1.x/src/main/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/Worker.java](https://github.com/awslabs/amazon-kinesis-client/blob/v1.x/src/main/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/Worker.java)(Java KCL 리포지토리)를 참조하세요. KCL 2.x에서는 이 클래스를 **스케줄러**라고 합니다. KCL 2.x에서 스케줄러의 용도는 KCL 1.x에서 워커의 용도와 동일합니다. KCL 2.x의 스케줄러 클래스에 대한 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/src/main/java/software/amazon/kinesis/coordinator/Scheduler.java](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/src/main/java/software/amazon/kinesis/coordinator/Scheduler.java)를 참조하세요.
+ **리스** - 워커와 샤드 간의 바인딩을 정의하는 데이터입니다. 분산된 KCL 소비자 애플리케이션은 리스를 사용하여 워커 플릿의 데이터 레코드 처리를 분할합니다. 언제든지 각 데이터 레코드 샤드는 **leaseKey** 변수로 식별되는 리스를 통해 특정 워커에게 바인딩됩니다.

  기본적으로 워커는 **maxLeasesForWorker** 변수 값에 따라 하나 이상의 리스를 동시에 보유할 수 있습니다.
**중요**  
모든 워커는 데이터 스트림에서 사용 가능한 모든 샤드에 대해 사용 가능한 모든 리스를 보유하고자 경쟁합니다. 하지만 한 번에 하나의 워커만 각 리스를 성공적으로 보유할 수 있습니다.

  예를 들어, 소비자 애플리케이션 인스턴스 A에 워커 A가 있고 이 인스턴스가 4개의 샤드로 구성된 데이터 스트림을 처리하는 경우 워커 A는 샤드 1, 2, 3, 4에 대한 리스를 동시에 보유할 수 있습니다. 그러나 A와 B라는 2개의 소비자 애플리케이션 인스턴스에 각각 워커 A와 워커 B가 있고 이들 인스턴스가 4개의 샤드로 구성된 데이터 스트림을 처리하는 경우 워커 A와 워커 B는 샤드 1에 대한 리스를 동시에 보유할 수 없습니다. 한 워커가 특정 샤드의 데이터 레코드 처리를 중지할 준비가 되거나 실패할 때까지 이 샤드에 대한 리스를 보유합니다. 한 워커가 리스 보유를 중지하면 다른 워커가 리스를 인수하여 보유합니다.

  자세한 내용은 Java KCL 리포지토리 [https://github.com/awslabs/amazon-kinesis-client/blob/v1.x/src/main/java/com/amazonaws/services/kinesis/leases/impl/Lease.java](https://github.com/awslabs/amazon-kinesis-client/blob/v1.x/src/main/java/com/amazonaws/services/kinesis/leases/impl/Lease.java)(KCL 1.x의 경우) 및 [https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/src/main/java/software/amazon/kinesis/leases/Lease.java](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/src/main/java/software/amazon/kinesis/leases/Lease.java)(KCL 2.x의 경우)를 참조하세요.
+ **리스 테이블** - KCL 소비자 애플리케이션의 워커가 리스하고 처리하고 있는 KDS 데이터 스트림의 샤드를 추적하는 데 사용되는 고유한 Amazon DynamoDB 테이블입니다. KCL 소비자 애플리케이션이 실행되는 동안 리스 테이블은 데이터 스트림의 최신 샤드 정보와 동기화된 상태를 유지해야 합니다(워커 내 및 모든 워커 간). 자세한 내용은 [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](#shared-throughput-kcl-consumers-leasetable) 단원을 참조하십시오.
+ **레코드 프로세서** - KCL 소비자 애플리케이션이 데이터 스트림에서 가져온 데이터를 처리하는 방법을 정의하는 로직입니다. 런타임 시 KCL 소비자 애플리케이션 인스턴스는 워커를 인스턴스화하고 이 워커는 리스를 보유한 모든 샤드에 대해 하나의 레코드 프로세서를 인스턴스화합니다.

## 리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적
<a name="shared-throughput-kcl-consumers-leasetable"></a>

**Topics**
+ [리스 테이블이란?](#shared-throughput-kcl-consumers-what-is-leasetable)
+ [처리량](#shared-throughput-kcl-leasetable-throughput)
+ [리스 테이블이 KDS 데이터 스트림의 샤드와 동기화되는 방법](#shared-throughput-kcl-consumers-leasetable-sync)

### 리스 테이블이란?
<a name="shared-throughput-kcl-consumers-what-is-leasetable"></a>

각 Amazon Kinesis Data Streams 애플리케이션에 대해 KCL은 Amazon DynamoDB 테이블에 저장되는 고유한 리스 테이블을 사용하여 KCL 소비자 애플리케이션의 워커가 리스하고 처리하고 있는 KDS 데이터 스트림의 샤드를 추적합니다.

**중요**  
KCL은 소비자 애플리케이션의 이름을 사용하여 이 소비자 애플리케이션이 사용하는 리스 테이블의 이름을 생성하므로 각 소비자 애플리케이션 이름은 고유해야 합니다.

소비자 애플리케이션이 실행되는 동안 [Amazon DynamoDB 콘솔](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ConsoleDynamoDB.html)을 사용하여 리스 테이블을 볼 수 있습니다.

애플리케이션이 시작될 때 KCL 소비자 애플리케이션에 대한 리스 테이블이 없는 경우 워커 중 하나가 이 애플리케이션에 대한 리스 테이블을 생성합니다.

**중요**  
 Kinesis Data Streams 자체와 관련된 비용 외에도 DynamoDB 테이블 관련 비용이 계정에 청구됩니다.

리스 테이블의 각 행은 소비자 애플리케이션의 워커가 처리 중인 샤드를 나타냅니다. KCL 소비자 애플리케이션이 하나의 데이터 스트림만 처리하는 경우 리스 테이블의 해시 키인 `leaseKey`가 샤드 ID입니다. [동일한 KCL 2.x for Java 소비자 애플리케이션으로 여러 데이터 스트림 처리](#shared-throughput-kcl-multistream)를 수행하는 경우 leaseKey의 구조는 `account-id:StreamName:streamCreationTimestamp:ShardId`와 같습니다. 예를 들어 `111111111:multiStreamTest-1:12345:shardId-000000000336`입니다.

각 행에는 샤드 ID 외에도 다음 데이터가 포함됩니다.
+ **checkpoint:** 샤드의 가장 최근 체크포인트 시퀀스 번호입니다. 이 값은 데이터 스트림의 모든 샤드에서 고유합니다.
+ **checkpointSubSequenceNumber:** Kinesis Producer Library의 집계 기능을 사용할 때 이는 Kinesis 레코드 내의 개별 사용자 레코드를 추적하는 **체크포인트**에 대한 확장입니다.
+ **leaseCounter:** 다른 작업자가 리스를 받았다는 것을 작업자가 감지할 수 있도록 리스 버전 관리에 사용됩니다.
+ **leaseKey:** 임대의 고유 식별자입니다. 각 리스는 데이터 스트림의 샤드에 특정적이며 한 번에 한 워커가 리스를 보유합니다.
+ **leaseOwner:** 이 임대를 보유하는 작업자입니다.
+ **ownerSwitchesSinceCheckpoint:** 마지막으로 체크포인트가 쓰여진 이후 이 임대가 작업자를 변경한 횟수입니다.
+ **parentShardId:** 하위 샤드 처리를 시작하기 전에 상위 처리를 완전히 처리하기 위해 사용합니다. 그러면 스트림에 입력된 순서대로 레코드가 처리됩니다.
+ **hashrange:** `PeriodicShardSyncManager`에서 주기적 동기화를 실행하여 리스 테이블에서 누락된 샤드를 찾고 필요한 경우 리스를 생성하는 데 사용됩니다.
**참고**  
이 데이터는 KCL 1.14 및 KCL 2.3부터 시작하는 모든 샤드의 리스 테이블에 있습니다. `PeriodicShardSyncManager` 및 리스와 샤드 간의 주기적 동기화에 대한 자세한 내용은 [리스 테이블이 KDS 데이터 스트림의 샤드와 동기화되는 방법](#shared-throughput-kcl-consumers-leasetable-sync) 섹션을 참조하세요.
+ **childshards:** `LeaseCleanupManager`에서 하위 샤드의 처리 상태를 검토하고 리스 테이블에서 상위 샤드를 삭제할 수 있는지 여부를 결정하는 데 사용됩니다.
**참고**  
이 데이터는 KCL 1.14 및 KCL 2.3부터 시작하는 모든 샤드의 리스 테이블에 있습니다.
+ **shardID:** 샤드의 ID입니다.
**참고**  
이 데이터는 사용자가 [동일한 KCL 2.x for Java 소비자 애플리케이션으로 여러 데이터 스트림 처리](#shared-throughput-kcl-multistream)를 수행하는 경우에만 리스 테이블에 있습니다. 이는 KCL 2.x for Java(KCL 2.3 for Java 이상부터)에서만 지원됩니다.
+ **stream name** `account-id:StreamName:streamCreationTimestamp` 형식의 데이터 스트림 식별자입니다.
**참고**  
이 데이터는 사용자가 [동일한 KCL 2.x for Java 소비자 애플리케이션으로 여러 데이터 스트림 처리](#shared-throughput-kcl-multistream)를 수행하는 경우에만 리스 테이블에 있습니다. 이는 KCL 2.x for Java(KCL 2.3 for Java 이상부터)에서만 지원됩니다.

### 처리량
<a name="shared-throughput-kcl-leasetable-throughput"></a>

Amazon Kinesis Data Streams 애플리케이션이 프로비저닝된 처리량을 예외를 수신하는 경우 DynamoDB 테이블의 프로비저닝된 처리량을 늘려야 합니다. KCL은 프로비저닝된 처리량이 초당 읽기 10개, 초당 쓰기 10개인 테이블을 생성하지만 애플리케이션에 충분하지 않을 수도 있습니다. 예를 들어, Amazon Kinesis Data Streams 애플리케이션이 체크포인트를 자주 수행하거나 여러 샤드로 구성된 스트림에서 작동하는 경우 처리량이 더 필요할 수 있습니다.

DynamoDB의 프로비저닝된 처리량에 대한 자세한 내용은 **Amazon DynamoDB 개발자 안내서의 [읽기/쓰기 용량 모드](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html) 및 [DynamoDB의 테이블 및 데이터 작업](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithDDTables.html)을 참조하세요.

### 리스 테이블이 KDS 데이터 스트림의 샤드와 동기화되는 방법
<a name="shared-throughput-kcl-consumers-leasetable-sync"></a>

KCL 소비자 애플리케이션의 워커는 리스를 사용하여 지정된 데이터 스트림의 샤드를 처리합니다. 특정 시간에 어떤 워커가 어떤 샤드를 리스하는지에 대한 정보는 리스 테이블에 저장됩니다. KCL 소비자 애플리케이션이 실행되는 동안 리스 테이블은 데이터 스트림의 최신 샤드 정보와 동기화된 상태를 유지해야 합니다. KCL은 소비자 애플리케이션 부트스트래핑(소비자 애플리케이션 초기화 또는 재시작 시) 동안 그리고 처리 중인 샤드가 종료(리샤딩)에 도달할 때마다 Kinesis Data Streams 서비스에서 획득한 샤드 정보와 리스 테이블을 동기화합니다. 즉, 워커 또는 KCL 소비자 애플리케이션은 초기 소비자 애플리케이션 부트스트랩 동안 그리고 소비자 애플리케이션에서 데이터 스트림 리샤딩 이벤트가 발생할 때마다 처리 중인 데이터 스트림과 동기화됩니다.

**Topics**
+ [KCL 1.0\$11.13 및 KCL 2.0\$12.2에서의 동기화](#shared-throughput-kcl-consumers-leasetable-sync-old)
+ [KCL 2.x에서의 동기화(KCL 2.3 이상부터)](#shared-throughput-kcl-consumers-leasetable-sync-new-kcl2)
+ [KCL 1.x에서의 동기화(KCL 1.14 이상부터)](#shared-throughput-kcl-consumers-leasetable-sync-new-kcl1)

#### KCL 1.0\$11.13 및 KCL 2.0\$12.2에서의 동기화
<a name="shared-throughput-kcl-consumers-leasetable-sync-old"></a>

KCL 1.0\$11.13 및 KCL 2.0\$12.2에서 KCL은 소비자 애플리케이션의 부트스트래핑 및 각 데이터 스트림 리샤딩 이벤트 중에 `ListShards` 또는 `DescribeStream` 검색 API를 간접적으로 호출하여 Kinesis Data Streams 서비스에서 획득한 샤드 정보와 리스 테이블을 동기화합니다. 위에 나열된 모든 KCL 버전에서 KCL 소비자 애플리케이션의 각 워커는 소비자 애플리케이션의 부트스트래핑 중 및 각 스트림 리샤드 이벤트에서 다음 단계를 완료하여 리스/샤드 동기화 프로세스를 수행합니다.
+ 처리 중인 데이터 스트림에 대한 모든 샤드를 가져옵니다.
+ 리스 테이블에서 모든 샤드 리스를 가져옵니다.
+ 리스 테이블에 리스가 없는 각 열린 샤드를 필터링합니다.
+ 발견된 모든 열린 샤드와 열린 상위 항목이 없는 각 열린 샤드를 반복합니다.
  + 상위 항목 경로를 통해 계층 트리를 탐색하여 샤드가 하위 항목인지 확인합니다. 상위 샤드가 처리 중이거나(상위 샤드에 대한 리스 항목이 리스 테이블에 있음) 상위 샤드를 처리해야 하는 경우(예: 초기 위치가 `TRIM_HORIZON` 또는 `AT_TIMESTAMP`인 경우) 샤드는 하위 항목으로 간주됩니다.
  + 컨텍스트의 열린 샤드가 하위 항목인 경우 KCL은 초기 위치를 기준으로 샤드 체크포인트를 수행하고 필요한 경우 상위 항목에 대한 리스를 생성합니다.

#### KCL 2.x에서의 동기화(KCL 2.3 이상부터)
<a name="shared-throughput-kcl-consumers-leasetable-sync-new-kcl2"></a>

지원되는 최신 버전의 KCL 2.x(KCL 2.3) 이상부터 라이브러리는 이제 다음과 같은 동기화 프로세스 변경 사항을 지원합니다. 이러한 리스/샤드 동기화 변경은 KCL 소비자 애플리케이션에서 Kinesis Data Streams 서비스에 대한 API 호출 수를 크게 줄이고 KCL 소비자 애플리케이션의 리스 관리를 최적화합니다.
+ 애플리케이션 부트스트래핑 중 리스 테이블이 비어 있으면 KCL은 `ListShard` API의 필터링 옵션(`ShardFilter` 선택적 요청 파라미터)을 활용하여 `ShardFilter` 파라미터로 지정된 시간에 열려 있는 샤드의 스냅샷에 대해서만 리스를 검색하고 생성합니다. `ShardFilter` 파라미터를 사용하면 `ListShards` API의 응답을 필터링할 수 있습니다. `ShardFilter` 파라미터의 유일한 필수 속성은 `Type`입니다. KCL은 `Type` 필터 속성과 다음과 같은 유효한 값을 사용하여 새 리스가 필요할 수 있는 열린 샤드의 스냅샷을 식별하고 반환합니다.
  + `AT_TRIM_HORIZON` - `TRIM_HORIZON`에서 열려 있던 모든 샤드가 응답에 포함됩니다.
  + `AT_LATEST` - 데이터 스트림의 현재 열려 있는 샤드만 응답에 포함됩니다.
  + `AT_TIMESTAMP` - 시작 타임스탬프가 지정된 타임스탬프보다 작거나 같고 종료 타임스탬프가 지정된 타임스탬프보다 크거나 같거나 여전히 열려 있는 모든 샤드가 응답에 포함됩니다.

  `ShardFilter`는 `RetrievalConfig#initialPositionInStreamExtended`에 지정된 샤드의 스냅샷에 대한 리스를 초기화하기 위해 빈 리스 테이블에 대한 리스를 생성할 때 사용됩니다.

  `ShardFilter`에 대한 자세한 정보는 [https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ShardFilter.html](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ShardFilter.html) 섹션을 참조하세요.
+ 모든 워커가 리스/하드 동기화를 수행하여 데이터 스트림의 최신 샤드로 리스 테이블을 최신 상태로 유지하는 대신 선출된 단일 워커 리더가 리스/샤드 동기화를 수행합니다.
+ KCL 2.3은 `GetRecords` 및 `SubscribeToShard` API의 `ChildShards` 반환 파라미터를 사용하여 닫힌 샤드에 대해 `SHARD_END`에서 발생하는 리스/샤드 동기화를 수행하므로 KCL 워커는 처리가 완료된 샤드의 하위 샤드에 대해서만 리스를 생성할 수 있습니다. 공유 처리량 소비자 애플리케이션의 경우 리스/하드 동기화의 이 최적화는 `GetRecords` API의 `ChildShards` 파라미터를 사용합니다. 전용 처리량(향상된 팬아웃) 소비자 애플리케이션의 경우 리스/하드 동기화의 이 최적화는 `SubscribeToShard` API의 `ChildShards` 파라미터를 사용합니다. 자세한 내용은 [GetRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html), [SubscribeToShards](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SubscribeToShard.html) 및 [ChildShard](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ChildShard.html)를 참조하세요.
+ 위의 변경으로 인해 KCL의 동작은 모든 기존 샤드에 대해 학습하는 모든 워커 모델에서 각 워커가 소유한 샤드의 하위 샤드에 대해서만 학습하는 워커 모델로 바뀌고 있습니다. 따라서 소비자 애플리케이션 부트스트래핑 및 리샤드 이벤트 중 발생하는 동기화 외에도 KCL은 이제 리스 테이블의 잠재적 구멍을 식별하기 위해 즉, 모든 새로운 샤드에 대해 알아보기 위해 추가로 주기적 샤드/리스 스캔도 수행하여 데이터 스트림의 전체 해시 범위가 처리되고 있는지 확인하고 필요한 경우 리스를 생성합니다. `PeriodicShardSyncManager`는 주기적 리스/샤드 스캔 실행을 담당하는 구성 요소입니다.

  KCL 2.3의 `PeriodicShardSyncManager`에 대한 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/src/main/java/software/amazon/kinesis/leases/LeaseManagementConfig.java\$1L201-L213](https://github.com/awslabs/amazon-kinesis-client/blob/master/amazon-kinesis-client/src/main/java/software/amazon/kinesis/leases/LeaseManagementConfig.java#L201-L213)을 참조하세요.

  KCL 2.3에서는 새로운 구성 옵션을 사용하여 `LeaseManagementConfig`에서 `PeriodicShardSyncManager`를 구성할 수 있습니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/shared-throughput-kcl-consumers.html)

  이제 `PeriodicShardSyncManager`의 상태를 모니터링하기 위해 새로운 CloudWatch 지표도 제공됩니다. 자세한 내용은 [PeriodicShardSyncManager](monitoring-with-kcl.md#periodic-task) 단원을 참조하십시오.
+ 하나의 샤드 계층에 대해서만 리스를 생성하도록 `HierarchicalShardSyncer`에 대한 최적화를 포함합니다.

#### KCL 1.x에서의 동기화(KCL 1.14 이상부터)
<a name="shared-throughput-kcl-consumers-leasetable-sync-new-kcl1"></a>

지원되는 최신 버전의 KCL 1.x(KCL 1.14) 이상부터 라이브러리는 이제 다음과 같은 동기화 프로세스 변경 사항을 지원합니다. 이러한 리스/샤드 동기화 변경은 KCL 소비자 애플리케이션에서 Kinesis Data Streams 서비스에 대한 API 호출 수를 크게 줄이고 KCL 소비자 애플리케이션의 리스 관리를 최적화합니다.
+ 애플리케이션 부트스트래핑 중 리스 테이블이 비어 있으면 KCL은 `ListShard` API의 필터링 옵션(`ShardFilter` 선택적 요청 파라미터)을 활용하여 `ShardFilter` 파라미터로 지정된 시간에 열려 있는 샤드의 스냅샷에 대해서만 리스를 검색하고 생성합니다. `ShardFilter` 파라미터를 사용하면 `ListShards` API의 응답을 필터링할 수 있습니다. `ShardFilter` 파라미터의 유일한 필수 속성은 `Type`입니다. KCL은 `Type` 필터 속성과 다음과 같은 유효한 값을 사용하여 새 리스가 필요할 수 있는 열린 샤드의 스냅샷을 식별하고 반환합니다.
  + `AT_TRIM_HORIZON` - `TRIM_HORIZON`에서 열려 있던 모든 샤드가 응답에 포함됩니다.
  + `AT_LATEST` - 데이터 스트림의 현재 열려 있는 샤드만 응답에 포함됩니다.
  + `AT_TIMESTAMP` - 시작 타임스탬프가 지정된 타임스탬프보다 작거나 같고 종료 타임스탬프가 지정된 타임스탬프보다 크거나 같거나 여전히 열려 있는 모든 샤드가 응답에 포함됩니다.

  `ShardFilter`는 `KinesisClientLibConfiguration#initialPositionInStreamExtended`에 지정된 샤드의 스냅샷에 대한 리스를 초기화하기 위해 빈 리스 테이블에 대한 리스를 생성할 때 사용됩니다.

  `ShardFilter`에 대한 자세한 정보는 [https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ShardFilter.html](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ShardFilter.html) 섹션을 참조하세요.
+ 모든 워커가 리스/하드 동기화를 수행하여 데이터 스트림의 최신 샤드로 리스 테이블을 최신 상태로 유지하는 대신 선출된 단일 워커 리더가 리스/샤드 동기화를 수행합니다.
+ KCL 1.14는 `GetRecords` 및 `SubscribeToShard` API의 `ChildShards` 반환 파라미터를 사용하여 닫힌 샤드에 대해 `SHARD_END`에서 발생하는 리스/샤드 동기화를 수행하므로 KCL 워커는 처리가 완료된 샤드의 하위 샤드에 대해서만 리스를 생성할 수 있습니다. 자세한 내용은 [GetRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html)와 [ChildShard](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ChildShard.html)를 참조하세요.
+ 위의 변경으로 인해 KCL의 동작은 모든 기존 샤드에 대해 학습하는 모든 워커 모델에서 각 워커가 소유한 샤드의 하위 샤드에 대해서만 학습하는 워커 모델로 바뀌고 있습니다. 따라서 소비자 애플리케이션 부트스트래핑 및 리샤드 이벤트 중 발생하는 동기화 외에도 KCL은 이제 리스 테이블의 잠재적 구멍을 식별하기 위해 즉, 모든 새로운 샤드에 대해 알아보기 위해 추가로 주기적 샤드/리스 스캔도 수행하여 데이터 스트림의 전체 해시 범위가 처리되고 있는지 확인하고 필요한 경우 리스를 생성합니다. `PeriodicShardSyncManager`는 주기적 리스/샤드 스캔 실행을 담당하는 구성 요소입니다.

  `KinesisClientLibConfiguration#shardSyncStrategyType`이 `ShardSyncStrategyType.SHARD_END`로 설정된 경우 `PeriodicShardSync leasesRecoveryAuditorInconsistencyConfidenceThreshold`는 샤드 동기화 시행을 위한 리스 테이블에 구멍이 포함된 연속 스캔 수에 대한 임곗값을 결정하는 데 사용됩니다. `KinesisClientLibConfiguration#shardSyncStrategyType`이 `ShardSyncStrategyType.PERIODIC`으로 설정된 경우 `leasesRecoveryAuditorInconsistencyConfidenceThreshold`은 무시됩니다.

  KCL 1.14의 `PeriodicShardSyncManager`에 대한 자세한 내용 [https://github.com/awslabs/amazon-kinesis-client/blob/v1.x/src/main/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/KinesisClientLibConfiguration.java\$1L987-L999](https://github.com/awslabs/amazon-kinesis-client/blob/v1.x/src/main/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/KinesisClientLibConfiguration.java#L987-L999)를 참조하세요.

  KCL 1.14에서는 새로운 구성 옵션을 사용하여 `LeaseManagementConfig`에서 `PeriodicShardSyncManager`를 구성할 수 있습니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/shared-throughput-kcl-consumers.html)

  이제 `PeriodicShardSyncManager`의 상태를 모니터링하기 위해 새로운 CloudWatch 지표도 제공됩니다. 자세한 내용은 [PeriodicShardSyncManager](monitoring-with-kcl.md#periodic-task) 단원을 참조하십시오.
+ KCL 1.14는 이제 지연된 리스 정리도 지원합니다. 샤드가 데이터 스트림의 보존 기간을 지나 만료되었거나 리샤딩 작업의 결과로 닫힌 경우 `SHARD_END`에 도달하면 `LeaseCleanupManager`가 리스를 비동기식으로 삭제합니다.

  새로운 구성 옵션을 사용하여 `LeaseCleanupManager`를 구성할 수 있습니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/streams/latest/dev/shared-throughput-kcl-consumers.html)
+ 하나의 샤드 계층에 대해서만 리스를 생성하도록 `KinesisShardSyncer`에 대한 최적화를 포함합니다.

## 동일한 KCL 2.x for Java 소비자 애플리케이션으로 여러 데이터 스트림 처리
<a name="shared-throughput-kcl-multistream"></a>

이 섹션에서는 2개 이상의 데이터 스트림을 동시에 처리할 수 있는 KCL 소비자 애플리케이션을 생성할 수 있게 하는 KCL 2.x for Java의 다음과 같은 변경 사항을 설명합니다.

**중요**  
멀티스트림 처리는 KCL 2.x for Java(KCL 2.3 for Java 이상부터)에서만 지원됩니다.  
KCL 2.x를 구현할 수 있는 다른 언어에 대해 멀티스트림 처리가 지원되지 않습니다.  
KCL 1.x의 모든 버전에서 멀티스트림 처리가 지원되지 않습니다.
+ **MultistreamTracker 인터페이스**

  여러 스트림을 동시에 처리할 수 있는 소비자 애플리케이션을 구축하려면 [MultistreamTracker](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/processor/MultiStreamTracker.java)라는 새 인터페이스를 구현해야 합니다. 이 인터페이스에는 KCL 소비자 애플리케이션에서 처리할 데이터 스트림 및 해당 구성 목록을 반환하는 `streamConfigList` 메서드가 포함되어 있습니다. 처리 중인 데이터 스트림은 소비자 애플리케이션 런타임 중에 변경될 수 있습니다. `streamConfigList`는 처리할 데이터 스트림의 변경 사항을 알아보기 위해 KCL에서 주기적으로 직접적으로 호출됩니다.

  `streamConfigList` 메서드는 [StreamConfig](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/StreamConfig.java#L23) 목록을 채웁니다.

  ```
  package software.amazon.kinesis.common;
  
  import lombok.Data;
  import lombok.experimental.Accessors;
  
  @Data
  @Accessors(fluent = true)
  public class StreamConfig {
      private final StreamIdentifier streamIdentifier;
      private final InitialPositionInStreamExtended initialPositionInStreamExtended;
      private String consumerArn;
  }
  ```

  `StreamIdentifier` 및 `InitialPositionInStreamExtended`는 필수 필드이고 `consumerArn`은 선택 사항입니다. KCL 2.x를 사용하여 향상된 팬아웃 소비자 애플리케이션을 구현하는 경우에만 `consumerArn`을 제공해야 합니다.

  에 대한 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/v2.5.8/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/StreamIdentifier.java\$1L129](https://github.com/awslabs/amazon-kinesis-client/blob/v2.5.8/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/StreamIdentifier.java#L129) `StreamIdentifier`참조하십시오. `StreamIdentifier`를 생성하려면 v2.5.0 이상에서 사용할 수 있는 `streamArn` 및 `streamCreationEpoch`에서 멀티스트림 인스턴스를 생성하는 것이 좋습니다. `streamArm`를 지원하지 않는 KCL v2.3 및 v2.4에서는 `account-id:StreamName:streamCreationTimestamp` 형식을 사용하여 멀티스트림 인스턴스를 생성하세요. 이 형식은 사용되지 않으며 다음 메이저 릴리스부터 더 이상 지원되지 않습니다.

  `MultistreamTracker`에는 리스 테이블(`formerStreamsLeasesDeletionStrategy`)에서 오래된 스트림의 리스를 삭제하기 위한 전략도 포함되어 있습니다. 소비자 애플리케이션 런타임 중에는 전략을 변경할 수 없다는 점에 유의하세요. 자세한 내용은 [https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/processor/FormerStreamsLeasesDeletionStrategy.java](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/processor/FormerStreamsLeasesDeletionStrategy.java)를 참조하세요.
+ [ConfigsBuilder](https://github.com/awslabs/amazon-kinesis-client/blob/0c5042dadf794fe988438436252a5a8fe70b6b0b/amazon-kinesis-client/src/main/java/software/amazon/kinesis/common/ConfigsBuilder.java)는 KCL 소비자 애플리케이션을 구축할 때 사용할 모든 KCL 2.x 구성 설정을 지정하는 데 사용할 수 있는 애플리케이션 전체 클래스입니다. `ConfigsBuilder` 클래스는 이제 `MultistreamTracker` 인터페이스를 지원합니다. 하나의 데이터 스트림 이름으로 ConfigsBuilder를 초기화하여 레코드를 소비할 수 있습니다.

  ```
   /**
       * Constructor to initialize ConfigsBuilder with StreamName
       * @param streamName
       * @param applicationName
       * @param kinesisClient
       * @param dynamoDBClient
       * @param cloudWatchClient
       * @param workerIdentifier
       * @param shardRecordProcessorFactory
       */
      public ConfigsBuilder(@NonNull String streamName, @NonNull String applicationName,
              @NonNull KinesisAsyncClient kinesisClient, @NonNull DynamoDbAsyncClient dynamoDBClient,
              @NonNull CloudWatchAsyncClient cloudWatchClient, @NonNull String workerIdentifier,
              @NonNull ShardRecordProcessorFactory shardRecordProcessorFactory) {
          this.appStreamTracker = Either.right(streamName);
          this.applicationName = applicationName;
          this.kinesisClient = kinesisClient;
          this.dynamoDBClient = dynamoDBClient;
          this.cloudWatchClient = cloudWatchClient;
          this.workerIdentifier = workerIdentifier;
          this.shardRecordProcessorFactory = shardRecordProcessorFactory;
      }
  ```

  또는 동시에 여러 스트림을 처리하는 KCL 소비자 애플리케이션을 구현하려는 경우 `MultiStreamTracker`로 ConfigsBuilder를 초기화할 수 있습니다.

  ```
  * Constructor to initialize ConfigsBuilder with MultiStreamTracker
       * @param multiStreamTracker
       * @param applicationName
       * @param kinesisClient
       * @param dynamoDBClient
       * @param cloudWatchClient
       * @param workerIdentifier
       * @param shardRecordProcessorFactory
       */
      public ConfigsBuilder(@NonNull MultiStreamTracker multiStreamTracker, @NonNull String applicationName,
              @NonNull KinesisAsyncClient kinesisClient, @NonNull DynamoDbAsyncClient dynamoDBClient,
              @NonNull CloudWatchAsyncClient cloudWatchClient, @NonNull String workerIdentifier,
              @NonNull ShardRecordProcessorFactory shardRecordProcessorFactory) {
          this.appStreamTracker = Either.left(multiStreamTracker);
          this.applicationName = applicationName;
          this.kinesisClient = kinesisClient;
          this.dynamoDBClient = dynamoDBClient;
          this.cloudWatchClient = cloudWatchClient;
          this.workerIdentifier = workerIdentifier;
          this.shardRecordProcessorFactory = shardRecordProcessorFactory;
      }
  ```
+ KCL 소비자 애플리케이션에 대해 멀티스트림 지원이 구현됨에 따라 이제 애플리케이션 리스 테이블의 각 행에는 이 애플리케이션이 처리하는 여러 데이터 스트림의 샤드 ID와 스트림 이름이 포함됩니다.
+ KCL 소비자 애플리케이션에 대한 멀티스트림 지원이 구현되면 leaseKey는 `account-id:StreamName:streamCreationTimestamp:ShardId` 구조를 취합니다. 예를 들어 `111111111:multiStreamTest-1:12345:shardId-000000000336`입니다.
**중요**  
기존 KCL 소비자 애플리케이션이 하나의 데이터 스트림만 처리하도록 구성된 경우 leaseKey(리스 테이블의 해시 키)는 샤드 ID입니다. 여러 데이터 스트림을 처리하도록 이 기존 KCL 소비자 애플리케이션을 재구성하면 리스 테이블이 손상됩니다. 멀티스트림 지원을 사용할 경우 leaseKey 구조는 `account-id:StreamName:StreamCreationTimestamp:ShardId`와 같아야 하기 때문입니다.

## AWS Glue 스키마 레지스트리와 함께 KCL 사용
<a name="shared-throughput-kcl-consumers-glue-schema-registry"></a>

Kinesis 데이터 스트림을 AWS Glue 스키마 레지스트리와 통합할 수 있습니다. AWS Glue 스키마 레지스트리를 사용하면 스키마를 중앙에서 검색, 제어 및 발전시키는 동시에 생성된 데이터가 등록된 스키마에 의해 지속적으로 검증되도록 할 수 있습니다. 스키마는 데이터 레코드의 구조와 포맷을 정의합니다. 스키마는 신뢰할 수 있는 데이터 게시, 소비 또는 저장을 위한 버전 지정 사양입니다. AWS Glue스키마 레지스트리를 사용하면 스트리밍 애플리케이션 내에서 end-to-end 데이터 품질 및 데이터 거버넌스를 개선할 수 있습니다. 자세한 내용은 [AWS Glue Schema Registry](https://docs.aws.amazon.com/glue/latest/dg/schema-registry.html)를 참조하세요. 이 통합을 설정하는 방법 중 하나는 Java에서 KCL을 사용하는 것입니다.

**중요**  
현재 Kinesis Data Streams 및 AWS Glue Schema Registry 통합은 Java로 구현된 KCL 2.3 소비자를 사용하는 Kinesis 데이터 스트림에만 지원됩니다. 다국어 지원은 제공되지 않습니다. KCL 1.0 소비자는 지원되지 않습니다. KCL 2.3 이전의 KCL 2.x 소비자는 지원되지 않습니다.

KCL을 사용하여 Kinesis Data Streams와 Schema Registry의 통합을 설정하는 방법에 대한 자세한 지침은 [사용 사례: Amazon Kinesis Data Streams와 AWS Glue Schema Registry 통합의 "KPL/KCL 라이브러리를 사용하여 데이터와](https://docs.aws.amazon.com/glue/latest/dg/schema-registry-integrations.html#schema-registry-integrations-kds) 상호 작용" 섹션을 참조하세요.

# 공유 처리량으로 사용자 지정 소비자 개발
<a name="shared-throughput-consumers"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Data Streams로부터 데이터를 수신할 때 전용 처리량이 필요하지 않은 경우 그리고 200ms 미만의 읽기 전파 지연이 필요하지 않은 경우에는 다음 섹션에서 설명한 대로 소비자 애플리케이션을 구축하면 됩니다. Kinesis Client Library(KCL) 또는 AWS SDK for Java를 사용할 수 있습니다.

**Topics**
+ [KCL를 사용하여 공유 처리량으로 사용자 지정 소비자 개발](custom-kcl-consumers.md)

전용 처리량으로 Kinesis 데이터 스트림에서 레코드를 수신할 수 있는 소비자를 구축하는 방법에 대한 자세한 내용은 [전용 처리량으로 향상된 팬아웃 소비자 개발](enhanced-consumers.md) 섹션을 참조하세요.

# KCL를 사용하여 공유 처리량으로 사용자 지정 소비자 개발
<a name="custom-kcl-consumers"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

공유 처리량으로 사용자 지정 소비자 애플리케이션을 개발하는 방법 중 하나는 Kinesis Client Library(KCL)를 사용하는 것입니다.

사용 중인 KCL 버전에 대한 다음 주제 중에서 선택하세요.

**Topics**
+ [KCL 1.x 소비자 개발](developing-consumers-with-kcl.md)
+ [KCL 2.x 소비자 개발](developing-consumers-with-kcl-v2.md)

# KCL 1.x 소비자 개발
<a name="developing-consumers-with-kcl"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Amazon Kinesis Data Streams의 소비자 애플리케이션을 개발할 수 있습니다.

KCL에 대한 자세한 내용은 [KCL 정보(이전 버전)](shared-throughput-kcl-consumers.md#shared-throughput-kcl-consumers-overview) 단원을 참조하십시오.

사용하려는 옵션에 따라 다음 주제 중에서 선택하세요.

**Topics**
+ [Java로 Kinesis Client Library 소비자 개발](kinesis-record-processor-implementation-app-java.md)
+ [Node.js로 Kinesis Client Library 소비자 개발](kinesis-record-processor-implementation-app-nodejs.md)
+ [.NET으로 Kinesis Client Library 소비자 개발](kinesis-record-processor-implementation-app-dotnet.md)
+ [Python으로 Kinesis Client Library 소비자 개발](kinesis-record-processor-implementation-app-py.md)
+ [Ruby로 Kinesis Client Library 소비자 개발](kinesis-record-processor-implementation-app-ruby.md)

# Java로 Kinesis Client Library 소비자 개발
<a name="kinesis-record-processor-implementation-app-java"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Kinesis 데이터 스트림의 데이터를 처리하는 애플리케이션을 빌드합니다. Kinesis Client Library는 여러 언어로 제공됩니다. 이 주제에서는 Java에 대해 설명합니다. Javadoc 참조를 보려면 [Class AmazonKinesisClient의AWS Javadoc 항목](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/kinesis/AmazonKinesisClient.html)으로 이동하세요.

GitHub에서 Java KCL을 다운로드하려면 [Kinesis Client Library(Java)](https://github.com/awslabs/amazon-kinesis-client)로 이동하세요. Apache Maven에서 Java KCL을 찾으려면 [KCL 검색 결과](https://search.maven.org/#search|ga|1|amazon-kinesis-client) 페이지로 이동하세요. GitHub에서 Java KCL 소비자 애플리케이션용 샘플 코드를 다운로드하려면 GitHub의 [KCL for Java 샘플 프로젝트](https://github.com/aws/aws-sdk-java/tree/master/src/samples/AmazonKinesis) 페이지로 이동하세요.

샘플 애플리케이션에 [Apache Commons Logging](http://commons.apache.org/proper/commons-logging/guide.html)이 사용됩니다. `configure` 파일에 정의된 정적 `AmazonKinesisApplicationSample.java` 메서드에서 로깅 구성을 변경할 수 있습니다. Log4j 및 AWS Java 애플리케이션에서 Apache Commons Logging을 사용하는 방법에 대한 자세한 내용은 *AWS SDK for Java 개발자 안내서*의 [Logging with Log4j](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/java-dg-logging.html)를 참조하세요.

Java로 KCL 소비자 애플리케이션을 구현할 때 다음 작업을 완료해야 합니다.

**Topics**
+ [IRecordProcessor 메서드 구현](#kinesis-record-processor-implementation-interface-java)
+ [IRecordProcessor 인터페이스를 위한 클래스 팩토리 구현](#kinesis-record-processor-implementation-factory-java)
+ [작업자 생성](#kcl-java-worker)
+ [구성 속성 수정](#kinesis-record-processor-initialization-java)
+ [레코드 프로세서 인터페이스 버전 2로 마이그레이션](#kcl-java-v2-migration)

## IRecordProcessor 메서드 구현
<a name="kinesis-record-processor-implementation-interface-java"></a>

KCL은 현재 두 버전의 `IRecordProcessor` 인터페이스를 지원합니다. KCL의 첫 번째 버전에 제공되는 원래 인터페이스와 KCL 버전 1.5.0부터 사용할 수 있는 버전 2입니다. 두 인터페이스 모두 완벽하게 지원되며, 특정 시나리오 요구 사항에 따라 선택할 수 있습니다. 모든 차이점을 보려면 로컬로 빌드된 Javadoc 또는 소스 코드를 참조하십시오. 다음 단원에서는 시작에 필요한 최소한의 구현을 설명합니다.

**Topics**
+ [원래의 인터페이스(버전 1)](#kcl-java-interface-original)
+ [업데이트된 인터페이스(버전 2)](#kcl-java-interface-v2)

### 원래의 인터페이스(버전 1)
<a name="kcl-java-interface-original"></a>

원래의 `IRecordProcessor` 인터페이스(`package com.amazonaws.services.kinesis.clientlibrary.interfaces`)는 소비자가 구현할 다음과 같은 레코드 프로세서 메서드를 노출합니다. 이 샘플에서는 시작점으로 사용할 수 있는 구현을 제공합니다(`AmazonKinesisApplicationSampleRecordProcessor.java` 참조).

```
public void initialize(String shardId)
public void processRecords(List<Record> records, IRecordProcessorCheckpointer checkpointer)
public void shutdown(IRecordProcessorCheckpointer checkpointer, ShutdownReason reason)
```

**초기화**  
KCL은 레코드 프로세서가 인스턴스화될 때 특정 샤드 ID를 파라미터로 전달하여 `initialize` 메서드를 직접적으로 호출합니다. 이 레코드 프로세서는 해당 샤드만 처리하고 일반적으로 반대의 경우도 마찬가지입니다. 이 샤드는 해당 레코드 프로세서로만 처리됩니다. 하지만 소비자는 데이터 레코드가 두 번 이상 처리될 가능성을 고려해야 합니다. Kinesis Data Streams에서는 소비자의 워커가 샤드의 모든 데이터 레코드를 적어도 한 번은 처리한다는 *적어도 한 번* 의미론이 통용됩니다. 둘 이상의 작업자가 특정 샤드를 처리할 수 있는 경우에 대한 자세한 내용은 [리샤딩, 규모 조정 및 병렬 처리를 사용하여 샤드 수 변경](kinesis-record-processor-scaling.md)를 참조하십시오.

```
public void initialize(String shardId)
```

**processRecords**  
KCL은 `processRecords` 메서드에 지정된 샤드의 데이터 레코드 목록을 전달하여 `initialize(shardId)` 메서드를 직접적으로 호출합니다. 레코드 프로세서는 소비자의 의미론에 따라 이 레코드의 데이터를 처리합니다. 예를 들어, 워커가 데이터를 전환한 후 그 결과를 Amazon Simple Storage Service(S3) 버킷에 저장할 수 있습니다.

```
public void processRecords(List<Record> records, IRecordProcessorCheckpointer checkpointer) 
```

데이터 자체뿐 아니라 시퀀스 번호와 파티션 키도 데이터 레코드에 포함됩니다. 작업자가 데이터를 처리할 때 이 값을 사용할 수 있습니다. 예를 들어, 작업자는 파티션 키의 값을 기반으로 데이터를 저장할 S3 버킷을 선택할 수 있습니다. `Record` 클래스는 레코드의 데이터, 시퀀스 번호 및 파티션 키에 대한 액세스를 제공하는 다음 메서드를 노출합니다.

```
record.getData()  
record.getSequenceNumber() 
record.getPartitionKey()
```

이 샘플의 프라이빗 메서드 `processRecordsWithRetries`에는 작업자가 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하는 방법을 보여주는 코드가 있습니다.

Kinesis Data Streams는 샤드에서 이미 처리된 레코드를 추적하도록 레코드 프로세서에 요구합니다. KCL은 체크포인터(`IRecordProcessorCheckpointer`)를 `processRecords`에 전달하여 이 추적을 처리합니다. 레코드 프로세서는 해당 인터페이스에서 `checkpoint` 메서드를 직접적으로 호출하여 샤드의 레코드 처리가 얼마나 진행되었는지 KCL에 알려줍니다. 워커가 실패할 경우 KCL은 이 정보를 사용하여 마지막으로 처리된 레코드에서 샤드 처리를 다시 시작합니다.

분할 또는 병합 작업의 경우 소스 샤드의 프로세서가 `checkpoint`를 직접적으로 호출하여 소스 샤드의 모든 처리가 완료되었다고 표시할 때까지 KCL은 새 샤드의 처리를 시작하지 않습니다.

파라미터를 전달하지 않으면 KCL은 `checkpoint`에 대한 호출이 레코드 프로세서에 전달된 마지막 레코드까지 모두 처리되었다는 의미로 간주합니다. 따라서 레코드 프로세서는 전달된 목록에 있는 모든 레코드를 반드시 처리한 후에 `checkpoint`를 호출해야 합니다. 레코드 프로세서는 `checkpoint`를 호출할 때마다 `processRecords`를 호출할 필요가 없습니다. 예를 들어, 프로세서는 `checkpoint`를 세 번째 호출할 때마다 `processRecords`를 호출할 수 있습니다. 선택적으로 레코드의 정확한 시퀀스 번호를 `checkpoint`의 파라미터로 지정할 수도 있습니다. 이 경우 KCL은 모든 레코드가 해당 레코드까지만 처리되었다고 간주합니다.

이 샘플에서는 프라이빗 메서드 `checkpoint`가 적절한 예외 처리 및 재시도 로직을 사용하여 `IRecordProcessorCheckpointer.checkpoint`를 호출하는 방법을 보여줍니다.

KCL은 `processRecords`를 사용하여 데이터 레코드를 처리할 때 발생하는 모든 예외를 처리합니다. `processRecords`에서 예외가 발생하면 KCL은 예외 이전에 전달된 데이터 레코드를 건너뜁니다. 이러한 레코드는 예외가 발생한 프로세서 또는 소비자의 다른 레코드 프로세서로 다시 전송되지 않습니다.

**종료**  
처리가 종료될 때(종료 이유가 `TERMINATE`) 또는 워커가 더 이상 응답하지 않을 때(종료 이유가 `ZOMBIE`) KCL은 `shutdown` 메서드를 직접적으로 호출합니다.

```
public void shutdown(IRecordProcessorCheckpointer checkpointer, ShutdownReason reason)
```

샤드 분할이나 병합 또는 스트림 삭제로 인해 레코드 프로세서가 샤드에서 추가 레코드를 수신하지 않으면 처리가 종료됩니다.

또한 KCL은 `IRecordProcessorCheckpointer` 인터페이스를 `shutdown`에 전달합니다. 종료 이유가 `TERMINATE`이면 레코드 프로세서가 데이터 레코드 처리를 완료하고 이 인터페이스의 `checkpoint` 메서드를 호출해야 합니다.

### 업데이트된 인터페이스(버전 2)
<a name="kcl-java-interface-v2"></a>

업데이트된 `IRecordProcessor` 인터페이스(`package com.amazonaws.services.kinesis.clientlibrary.interfaces.v2`)는 소비자가 구현할 다음과 같은 레코드 프로세서 메서드를 노출합니다.

```
void initialize(InitializationInput initializationInput)
void processRecords(ProcessRecordsInput processRecordsInput)
void shutdown(ShutdownInput shutdownInput)
```

원래 인터페이스 버전의 모든 인수는 컨테이너 객체에서 get 메서드를 통해 액세스할 수 있습니다. 예를 들어, `processRecords()`를 사용하여 `processRecordsInput.getRecords()`의 레코드 목록을 검색할 수 있습니다.

이 인터페이스 버전 2에서(KCL 1.5.0 이상) 원래의 인터페이스가 제공하는 입력 외에도 다음과 같은 새 입력을 사용할 수 있습니다.

시작 시퀀스 번호  
`InitializationInput` 작업에 전달된 `initialize()` 객체에서 레코드가 레코드 프로세서 인스턴스에 제공될 시작 시퀀스 번호이며, 전에 같은 샤드를 처리하는 레코드 프로세서가 마지막으로 검사한 시퀀스 번호입니다. 애플리케이션에 이 정보가 필요할 경우 제공됩니다.

보류 중인 체크포인트 시퀀스 번호  
`initialize()` 작업에 전달된 `InitializationInput` 객체에서 이전 레코드 프로세서 인스턴스가 중단되기 전에 커밋되지 못한 보류 중인 체크포인트 시퀀스 번호(있는 경우)입니다.

## IRecordProcessor 인터페이스를 위한 클래스 팩토리 구현
<a name="kinesis-record-processor-implementation-factory-java"></a>

레코드 프로세서 메서드를 구현하는 클래스 팩토리도 구현해야 합니다. 소비자가 작업자를 인스턴스화할 때 이 팩토리에 참조를 전달합니다.

이 샘플은 원래의 레코드 프로세서 인터페이스를 사용하여 `AmazonKinesisApplicationSampleRecordProcessorFactory.java` 파일에서 팩토리 클래스를 구현합니다. 클래스 팩토리에서 레코드 프로세서 버전 2를 만들려면 패키지 이름 `com.amazonaws.services.kinesis.clientlibrary.interfaces.v2`를 사용하십시오.

```
  public class SampleRecordProcessorFactory implements IRecordProcessorFactory { 
      /**
      * Constructor.
      */
      public SampleRecordProcessorFactory() {
          super();
      }
      /**
      * {@inheritDoc}
      */
      @Override
      public IRecordProcessor createProcessor() {
          return new SampleRecordProcessor();
      }
  }
```

## 작업자 생성
<a name="kcl-java-worker"></a>

[IRecordProcessor 메서드 구현](#kinesis-record-processor-implementation-interface-java)에서 설명한 대로 두 가지 KCL 레코드 프로세서 인터페이스 버전 중에서 선택할 수 있으며 이 선택은 워커 생성 방법에 영향을 줍니다. 원래의 레코드 프로세서 인터페이스는 다음 코드 구조를 사용하여 작업자를 생성합니다.

```
final KinesisClientLibConfiguration config = new KinesisClientLibConfiguration(...)
final IRecordProcessorFactory recordProcessorFactory = new RecordProcessorFactory();
final Worker worker = new Worker(recordProcessorFactory, config);
```

레코드 프로세서 인터페이스 버전 2를 통해 인수의 순서와 사용할 생성자를 고민할 필요 없이 `Worker.Builder`를 사용하여 작업자를 만들 수 있습니다. 업데이트된 레코드 프로세서 인터페이스는 다음 코드 구조를 사용하여 작업자를 생성합니다.

```
final KinesisClientLibConfiguration config = new KinesisClientLibConfiguration(...)
final IRecordProcessorFactory recordProcessorFactory = new RecordProcessorFactory();
final Worker worker = new Worker.Builder()
    .recordProcessorFactory(recordProcessorFactory)
    .config(config)
    .build();
```

## 구성 속성 수정
<a name="kinesis-record-processor-initialization-java"></a>

이 샘플은 구성 속성의 기본값을 제공합니다. 그러면 작업자의 이 구성 데이터가 `KinesisClientLibConfiguration` 객체에 통합됩니다. `IRecordProcessor`의 클래스 팩토리에 대한 참조와 이 객체는 작업자를 인스턴스화하는 호출에서 전달됩니다. Java 속성 파일을 사용하여 이 속성을 사용자의 값으로 재정의할 수 있습니다(`AmazonKinesisApplicationSample.java` 참조).

### 애플리케이션 이름
<a name="configuration-property-application-name"></a>

KCL에는 애플리케이션 및 같은 리전의 Amazon DynamoDB 테이블에서 고유한 애플리케이션 이름이 필요합니다. 다음과 같이 애플리케이션 이름 구성 값이 사용됩니다.
+ 이 애플리케이션 이름과 관련된 모든 작업자는 동일한 스트림에서 함께 작업한다고 간주됩니다. 이 작업자는 여러 인스턴스에 분산되어 있을 수 있습니다. 동일한 애플리케이션 코드의 추가 인스턴스를 다른 애플리케이션 이름으로 실행하는 경우 KCL은 두 번째 인스턴스를 동일한 스트림에서 작동하는 완전히 별개의 애플리케이션으로 취급합니다.
+ KCL은 애플리케이션 이름이 있는 DynamoDB 테이블을 생성하고 테이블을 사용하여 애플리케이션의 상태 정보(예: 체크포인트 및 워커와 샤드의 매핑)를 보관합니다. 각각의 애플리케이션에는 자체 DynamoDB 테이블이 있습니다. 자세한 내용은 [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](shared-throughput-kcl-consumers.md#shared-throughput-kcl-consumers-leasetable) 단원을 참조하십시오.

### 보안 인증 설정
<a name="kinesis-record-processor-cred-java"></a>

기본 AWS 자격 증명 공급자 체인의 자격 증명 공급자 중 하나가 자격 증명을 사용할 수 있도록 해야 합니다. 예를 들어, EC2 인스턴스에서 소비자를 실행하는 경우 IAM 역할로 인스턴스를 시작하는 것이 좋습니다. 이 IAM 역할과 연결된 권한을 반영하는 AWS 보안 인증은 인스턴스 메타데이터를 통해 인스턴스의 애플리케이션에 제공됩니다. 이것이 EC2 인스턴스에서 실행되는 소비자의 자격 증명을 관리하는 가장 안전한 방법입니다.

먼저 샘플 애플리케이션이 인스턴스 메타데이터에서 IAM 보안 인증 검색을 시도합니다.

```
credentialsProvider = new InstanceProfileCredentialsProvider(); 
```

샘플 애플리케이션이 인스턴스 메타데이터에서 자격 증명을 가져오지 못하면 속성 파일에서 자격 증명 검색을 시도합니다.

```
credentialsProvider = new ClasspathPropertiesFileCredentialsProvider();
```

인스턴스 메타데이터에 대한 자세한 내용은 **Amazon EC2 사용 설명서의 [인스턴스 메타데이터](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)를 참조하세요.

### 여러 인스턴스에 작업자 ID 사용
<a name="kinesis-record-processor-workerid-java"></a>

샘플 초기화 코드는 로컬 컴퓨터 이름을 사용하고 다음 코드 조각과 같이 전역적으로 고유한 식별자를 추가하여 작업자의 ID인 `workerId`를 만듭니다. 이 방법은 단일 컴퓨터에서 소비자 애플리케이션의 여러 인스턴스가 실행되는 시나리오를 지원합니다.

```
String workerId = InetAddress.getLocalHost().getCanonicalHostName() + ":" + UUID.randomUUID();
```

## 레코드 프로세서 인터페이스 버전 2로 마이그레이션
<a name="kcl-java-v2-migration"></a>

위에서 설명한 단계 외에도 원래의 인터페이스를 사용하는 코드를 마이그레이션하려면 다음 단계가 필요합니다.

1. 버전 2 레코드 프로세서 인터페이스를 가져오도록 레코드 프로세서 클래스를 변경합니다.

   ```
   import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor;
   ```

1. 컨테이너 객체에서 `get` 메서드를 사용하도록 참조를 변경합니다. 예를 들어, `shutdown()` 작업에서 "`checkpointer`"를 "`shutdownInput.getCheckpointer()`"로 변경합니다.

1. 버전 2 레코드 프로세서 팩토리 인터페이스를 가져오도록 레코드 프로세서 팩토리 클래스를 변경합니다.

   ```
   import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessorFactory;
   ```

1. `Worker.Builder`를 사용하도록 작업자의 구성을 변경합니다. 예제:

   ```
   final Worker worker = new Worker.Builder()
       .recordProcessorFactory(recordProcessorFactory)
       .config(config)
       .build();
   ```

# Node.js로 Kinesis Client Library 소비자 개발
<a name="kinesis-record-processor-implementation-app-nodejs"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Kinesis 데이터 스트림의 데이터를 처리하는 애플리케이션을 빌드합니다. Kinesis Client Library는 여러 언어로 제공됩니다. 이 주제에서는 Node.js에 대해 설명합니다.

KCL은 Java 라이브러리이며, *MultiLangDaemon*이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 데몬은 Java 기반이며, Java 이외의 KCL 언어를 사용하는 경우 배경에서 실행됩니다. 따라서 Node.js용 KCL을 설치하고 Node.js로만 소비자 앱을 작성한 경우에도 MultiLangDaemon 때문에 시스템에 Java를 설치해야 합니다. 또한 MultiLangDaemon에는 연결한 AWS 리전과 같이 사용 사례에 맞게 사용자 지정해야 할 몇 가지 기본 설정이 있습니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang) 페이지를 참조하세요.

GitHub에서 Node.js KCL을 다운로드하려면 [Kinesis Client Library(Node.js)](https://github.com/awslabs/amazon-kinesis-client-nodejs)로 이동하세요.

**샘플 코드 다운로드**

Node.js KCL에 두 가지 코드 샘플을 사용할 수 있습니다.
+ [basic-sample](https://github.com/awslabs/amazon-kinesis-client-nodejs/tree/master/samples/basic_sample)

  Node.js로 KCL 소비자 애플리케이션을 빌드하기 위한 기초를 설명하기 위해 다음 섹션에서 사용됩니다.
+ [click-stream-sample](https://github.com/awslabs/amazon-kinesis-client-nodejs/tree/master/samples/click_stream_sample)

   기본 샘플 코드에 익숙해진 후에 실제 시나리오를 사용할 수 있는 약간 높은 수준의 코드입니다. 여기서는 이 샘플을 설명하지 않으며 자세한 내용은 README 파일에 있습니다.

Node.js로 KCL 소비자 애플리케이션을 구현할 때 다음 작업을 완료해야 합니다.

**Topics**
+ [레코드 프로세서 구현](#kinesis-record-processor-implementation-interface-nodejs)
+ [구성 속성 수정](#kinesis-record-processor-initialization-nodejs)

## 레코드 프로세서 구현
<a name="kinesis-record-processor-implementation-interface-nodejs"></a>

Node.js용 KCL을 사용하는 가능한 한 가장 단순한 소비자는 `initialize`, `processRecords` 및 `shutdown` 함수를 차례로 포함하는 `recordProcessor` 함수를 구현해야 합니다. 이 샘플에서는 시작점으로 사용할 수 있는 구현을 제공합니다(`sample_kcl_app.js` 참조).

```
function recordProcessor() {
  // return an object that implements initialize, processRecords and shutdown functions.}
```

**초기화**  
레코드 프로세서가 시작되면 KCL은 `initialize` 함수를 직접적으로 호출합니다. 이 레코드 프로세서는 `initializeInput.shardId`로 전달된 샤드 ID만 처리하고 일반적으로 반대의 경우도 마찬가지입니다. 이 샤드는 해당 레코드 프로세서로만 처리됩니다. 하지만 소비자는 데이터 레코드가 두 번 이상 처리될 가능성을 고려해야 합니다. Kinesis Data Streams에서는 소비자의 워커가 샤드의 모든 데이터 레코드를 적어도 한 번은 처리한다는 *적어도 한 번* 의미론이 통용되기 때문입니다. 둘 이상의 작업자가 특정 샤드를 처리할 수 있는 경우에 대한 자세한 내용은 [리샤딩, 규모 조정 및 병렬 처리를 사용하여 샤드 수 변경](kinesis-record-processor-scaling.md)를 참조하십시오.

```
initialize: function(initializeInput, completeCallback)
```

**processRecords**  
 KCL은 지정된 샤드에서 `initialize` 함수까지 데이터 레코드 목록을 포함하는 입력으로 이 함수를 직접적으로 호출합니다. 구현하는 레코드 프로세서가 소비자의 의미론에 따라 이 레코드의 데이터를 처리합니다. 예를 들어, 워커가 데이터를 전환한 후 그 결과를 Amazon Simple Storage Service(S3) 버킷에 저장할 수 있습니다.

```
processRecords: function(processRecordsInput, completeCallback)
```

데이터 자체뿐 아니라 작업자가 데이터를 처리할 때 사용할 수 있는 시퀀스 번호와 파티션 키도 데이터 레코드에 포함됩니다. 예를 들어, 작업자는 파티션 키의 값을 기반으로 데이터를 저장할 S3 버킷을 선택할 수 있습니다. `record` 딕셔너리가 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하기 위해 다음 키-값 페어를 노출합니다.

```
record.data
record.sequenceNumber
record.partitionKey
```

데이터가 Base64로 인코딩됩니다.

기본 샘플에서 `processRecords` 함수에는 작업자가 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하는 방법을 보여주는 코드가 있습니다.

Kinesis Data Streams는 샤드에서 이미 처리된 레코드를 추적하도록 레코드 프로세서에 요구합니다. KCL은 `processRecordsInput.checkpointer`로 전달된 `checkpointer` 객체를 통해 이 추적을 처리합니다. 레코드 프로세서는 `checkpointer.checkpoint` 함수를 직접적으로 호출하여 샤드의 레코드 처리가 얼마나 진행되었는지 KCL에 알려줍니다. 워커가 실패할 경우 KCL은 샤드 처리를 다시 시작할 때 마지막으로 처리된 레코드에서 계속되도록 이 정보를 사용합니다.

분할 또는 병합 작업의 경우 소스 샤드의 프로세서가 `checkpoint`를 직접적으로 호출하여 소스 샤드의 모든 처리가 완료되었다고 표시할 때까지 KCL은 새 샤드의 처리를 시작하지 않습니다.

`checkpoint` 함수에 시퀀스 번호를 전달하지 않으면 KCL은 `checkpoint`에 대한 호출이 레코드 프로세서에 전달된 마지막 레코드까지 모두 처리되었다는 의미로 간주합니다. 따라서 레코드 프로세서는 전달된 목록의 모든 레코드를 처리한 후에**만** `checkpoint`를 직접적으로 호출해야 합니다. 레코드 프로세서는 `checkpoint`를 호출할 때마다 `processRecords`를 호출할 필요가 없습니다. 예를 들어, 프로세서는 세 번째 호출마다 `checkpoint` 또는 구현된 사용자 지정 검증/확인 서비스와 같은 레코드 프로세서 외부의 이벤트를 호출할 수 있습니다.

선택적으로 레코드의 정확한 시퀀스 번호를 `checkpoint`의 파라미터로 지정할 수도 있습니다. 이 경우 KCL은 모든 레코드가 해당 레코드까지만 처리되었다고 간주합니다.

기본 샘플 애플리케이션은 `checkpointer.checkpoint` 함수의 가장 단순하고 가능한 호출을 보여줍니다. 소비자에 필요한 다른 검사 로직을 함수의 이 지점에 추가할 수 있습니다.

**종료**  
처리가 종료될 때(`shutdownInput.reason`이 `TERMINATE`) 또는 워커가 더 이상 응답하지 않을 때(`shutdownInput.reason`이 `ZOMBIE`) KCL은 `shutdown` 함수를 직접적으로 호출합니다.

```
shutdown: function(shutdownInput, completeCallback)
```

샤드 분할이나 병합 또는 스트림 삭제로 인해 레코드 프로세서가 샤드에서 추가 레코드를 수신하지 않으면 처리가 종료됩니다.

또한 KCL은 `shutdownInput.checkpointer` 객체를 `shutdown`에 전달합니다. 종료 이유가 `TERMINATE`이면 레코드 프로세서가 모든 데이터 레코드 처리를 완료했는지 확인하고 이 인터페이스의 `checkpoint` 함수를 호출해야 합니다.

## 구성 속성 수정
<a name="kinesis-record-processor-initialization-nodejs"></a>

이 샘플은 구성 속성의 기본값을 제공합니다. 이 속성을 사용자의 값으로 재정의할 수 있습니다(기본 샘플의 `sample.properties` 참조).

### 애플리케이션 이름
<a name="kinesis-record-processor-application-name-nodejs"></a>

KCL에는 애플리케이션 및 같은 리전의 Amazon DynamoDB 테이블에서 고유한 애플리케이션이 필요합니다. 다음과 같이 애플리케이션 이름 구성 값이 사용됩니다.
+ 이 애플리케이션 이름과 관련된 모든 작업자는 동일한 스트림에서 함께 작업한다고 간주됩니다. 이 작업자는 여러 인스턴스에 분산되어 있을 수 있습니다. 동일한 애플리케이션 코드의 추가 인스턴스를 다른 애플리케이션 이름으로 실행하는 경우 KCL은 두 번째 인스턴스를 동일한 스트림에서 작동하는 완전히 별개의 애플리케이션으로 취급합니다.
+ KCL은 애플리케이션 이름이 있는 DynamoDB 테이블을 생성하고 테이블을 사용하여 애플리케이션의 상태 정보(예: 체크포인트 및 워커와 샤드의 매핑)를 보관합니다. 각각의 애플리케이션에는 자체 DynamoDB 테이블이 있습니다. 자세한 내용은 [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](shared-throughput-kcl-consumers.md#shared-throughput-kcl-consumers-leasetable) 단원을 참조하십시오.

### 보안 인증 설정
<a name="kinesis-record-processor-credentials-nodejs"></a>

기본 AWS 자격 증명 공급자 체인의 자격 증명 공급자 중 하나가 자격 증명을 사용할 수 있도록 해야 합니다. `AWSCredentialsProvider` 속성을 사용하여 자격 증명 공급자를 설정할 수 있습니다. `sample.properties` 파일에서 [기본 자격 증명 공급자 체인](https://docs.aws.amazon.com/sdk-for-java/latest/reference/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html)의 자격 증명 공급자 중 하나에 자격 증명을 사용할 수 있도록 해야 합니다. Amazon EC2 인스턴스에서 소비자를 실행하는 경우 IAM 역할로 인스턴스를 구성하는 것이 좋습니다.이 IAM 역할과 연결된 권한을 반영하는 AWS 자격 증명은 인스턴스 메타데이터를 통해 인스턴스의 애플리케이션에 제공됩니다. 이것이 EC2 인스턴스에서 실행되는 소비자 애플리케이션의 자격 증명을 관리하는 가장 안전한 방법입니다.

다음 예제는 `sample_kcl_app.js`에 제공된 레코드 프로세서를 사용하여 `kclnodejssample`이라는 Kinesis 데이터 스트림을 처리하도록 KCL을 구성합니다.

```
# The Node.js executable script
executableName = node sample_kcl_app.js
# The name of an Amazon Kinesis stream to process
streamName = kclnodejssample
# Unique KCL application name
applicationName = kclnodejssample
# Use default AWS credentials provider chain
AWSCredentialsProvider = DefaultAWSCredentialsProviderChain
# Read from the beginning of the stream
initialPositionInStream = TRIM_HORIZON
```

# .NET으로 Kinesis Client Library 소비자 개발
<a name="kinesis-record-processor-implementation-app-dotnet"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Kinesis 데이터 스트림의 데이터를 처리하는 애플리케이션을 빌드합니다. Kinesis Client Library는 여러 언어로 제공됩니다. 이 주제에서는 .NET에 대해 설명합니다.

KCL은 Java 라이브러리이며, *MultiLangDaemon*이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 데몬은 Java 기반이며, Java 이외의 KCL 언어를 사용하는 경우 배경에서 실행됩니다. 따라서 .NET용 KCL을 설치하고 .NET으로만 소비자 앱을 작성한 경우에도 MultiLangDaemon 때문에 시스템에 Java를 설치해야 합니다. 또한 MultiLangDaemon에는 연결한 AWS 리전과 같이 사용 사례에 맞게 사용자 지정해야 할 몇 가지 기본 설정이 있습니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang) 페이지를 참조하세요.

GitHub에서 .NET KCL을 다운로드하려면 [Kinesis Client Library(.NET)](https://github.com/awslabs/amazon-kinesis-client-net)로 이동하세요. .NET KCL 소비자 애플리케이션용 샘플 코드를 다운로드하려면 GitHub의 [.NET용 KCL 샘플 소비자 프로젝트](https://github.com/awslabs/amazon-kinesis-client-net/tree/master/SampleConsumer) 페이지로 이동하세요.

.NET으로 KCL 소비자 애플리케이션을 구현할 때 다음 작업을 완료해야 합니다.

**Topics**
+ [IRecordProcessor 클래스 메서드 구현](#kinesis-record-processor-implementation-interface-dotnet)
+ [구성 속성 수정](#kinesis-record-processor-initialization-dotnet)

## IRecordProcessor 클래스 메서드 구현
<a name="kinesis-record-processor-implementation-interface-dotnet"></a>

소비자는 `IRecordProcessor`를 위해 다음의 메서드를 구현해야 합니다. 이 샘플 소비자는 시작점으로 사용할 수 있는 구현을 제공합니다(`SampleRecordProcessor`의 `SampleConsumer/AmazonKinesisSampleConsumer.cs` 클래스 참조).

```
public void Initialize(InitializationInput input)
public void ProcessRecords(ProcessRecordsInput input)
public void Shutdown(ShutdownInput input)
```

**초기화**  
KCL은 레코드 프로세서가 인스턴스화될 때 `input` 파라미터(`input.ShardId`)에서 특정 샤드 ID를 전달하여 이 메서드를 직접적으로 호출합니다. 이 레코드 프로세서는 해당 샤드만 처리하고 일반적으로 반대의 경우도 마찬가지입니다. 이 샤드는 해당 레코드 프로세서로만 처리됩니다. 하지만 소비자는 데이터 레코드가 두 번 이상 처리될 가능성을 고려해야 합니다. Kinesis Data Streams에서는 소비자의 워커가 샤드의 모든 데이터 레코드를 적어도 한 번은 처리한다는 *적어도 한 번* 의미론이 통용되기 때문입니다. 둘 이상의 작업자가 특정 샤드를 처리할 수 있는 경우에 대한 자세한 내용은 [리샤딩, 규모 조정 및 병렬 처리를 사용하여 샤드 수 변경](kinesis-record-processor-scaling.md)를 참조하십시오.

```
public void Initialize(InitializationInput input)
```

**ProcessRecords**  
KCL은 `Initialize` 메서드를 통해 지정된 샤드에서 `input` 파라미터(`input.Records`)의 데이터 레코드 목록을 전달하여 이 메서드를 직접적으로 호출합니다. 구현하는 레코드 프로세서가 소비자의 의미론에 따라 이 레코드의 데이터를 처리합니다. 예를 들어, 워커가 데이터를 전환한 후 그 결과를 Amazon Simple Storage Service(S3) 버킷에 저장할 수 있습니다.

```
public void ProcessRecords(ProcessRecordsInput input)
```

데이터 자체뿐 아니라 시퀀스 번호와 파티션 키도 데이터 레코드에 포함됩니다. 작업자가 데이터를 처리할 때 이 값을 사용할 수 있습니다. 예를 들어, 작업자는 파티션 키의 값을 기반으로 데이터를 저장할 S3 버킷을 선택할 수 있습니다. `Record` 클래스는 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하기 위해 다음 항목을 노출합니다.

```
byte[] Record.Data 
string Record.SequenceNumber
string Record.PartitionKey
```

이 샘플의 메서드 `ProcessRecordsWithRetries`에는 작업자가 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하는 방법을 보여주는 코드가 있습니다.

Kinesis Data Streams는 샤드에서 이미 처리된 레코드를 추적하도록 레코드 프로세서에 요구합니다. KCL은 `Checkpointer` 객체를 `ProcessRecords`(`input.Checkpointer`)에 전달하여 이 추적을 처리합니다. 레코드 프로세서는 `Checkpointer.Checkpoint` 메서드를 직접적으로 호출하여 샤드의 레코드 처리가 얼마나 진행되었는지를 KCL에 알려줍니다. 워커가 실패할 경우 KCL은 이 정보를 사용하여 마지막으로 처리된 레코드에서 샤드 처리를 다시 시작합니다.

분할 또는 병합 작업의 경우 소스 샤드의 프로세서가 `Checkpointer.Checkpoint`를 직접적으로 호출하여 소스 샤드의 모든 처리가 완료되었다고 표시할 때까지 KCL은 새 샤드의 처리를 시작하지 않습니다.

파라미터를 전달하지 않으면 KCL은 `Checkpointer.Checkpoint`에 대한 호출이 레코드 프로세서에 전달된 마지막 레코드까지 모두 처리되었다는 의미로 간주합니다. 따라서 레코드 프로세서는 전달된 목록에 있는 모든 레코드를 반드시 처리한 후에 `Checkpointer.Checkpoint`를 호출해야 합니다. 레코드 프로세서는 `Checkpointer.Checkpoint`를 호출할 때마다 `ProcessRecords`를 호출할 필요가 없습니다. 예를 들어, 프로세서는 세 번째 또는 네 번째 호출마다 `Checkpointer.Checkpoint`를 호출할 수 있습니다. 선택적으로 레코드의 정확한 시퀀스 번호를 `Checkpointer.Checkpoint`의 파라미터로 지정할 수도 있습니다. 이 경우 KCL은 레코드가 해당 레코드까지만 처리되었다고 간주합니다.

이 샘플에서는 프라이빗 메서드 `Checkpoint(Checkpointer checkpointer)`가 적절한 예외 처리 및 재시도 로직을 사영하여 `Checkpointer.Checkpoint` 메서드를 호출하는 방법을 보여줍니다.

.NET용 KCL은 데이터 레코드를 처리할 때 발생하는 예외를 처리하지 않는다는 점에서 다른 KCL 언어 라이브러리와는 다르게 예외를 처리합니다. 사용자 코드에서 확인할 수 없는 예외가 발생하면 프로그램이 중단됩니다.

**Shutdown**  
처리가 종료될 때(종료 이유가 `TERMINATE`) 또는 워커가 더 이상 응답하지 않을 때(종료 `input.Reason` 값이 `ZOMBIE`) KCL은 `Shutdown` 메서드를 직접적으로 호출합니다.

```
public void Shutdown(ShutdownInput input)
```

샤드 분할이나 병합 또는 스트림 삭제로 인해 레코드 프로세서가 샤드에서 추가 레코드를 수신하지 않으면 처리가 종료됩니다.

또한 KCL은 `Checkpointer` 객체를 `shutdown`에 전달합니다. 종료 이유가 `TERMINATE`이면 레코드 프로세서가 데이터 레코드 처리를 완료하고 이 인터페이스의 `checkpoint` 메서드를 호출해야 합니다.

## 구성 속성 수정
<a name="kinesis-record-processor-initialization-dotnet"></a>

이 샘플 소비자는 구성 속성의 기본값을 제공합니다. 속성을 사용자의 값으로 재정의할 수 있습니다(`SampleConsumer/kcl.properties` 참조).

### 애플리케이션 이름
<a name="modify-kinesis-record-processor-application-name"></a>

KCL에는 애플리케이션 및 같은 리전의 Amazon DynamoDB 테이블에서 고유한 애플리케이션이 필요합니다. 다음과 같이 애플리케이션 이름 구성 값이 사용됩니다.
+ 이 애플리케이션 이름과 관련된 모든 작업자는 동일한 스트림에서 함께 작업한다고 간주됩니다. 이 작업자는 여러 인스턴스에 분산되어 있을 수 있습니다. 동일한 애플리케이션 코드의 추가 인스턴스를 다른 애플리케이션 이름으로 실행하는 경우 KCL은 두 번째 인스턴스를 동일한 스트림에서 작동하는 완전히 별개의 애플리케이션으로 취급합니다.
+ KCL은 애플리케이션 이름이 있는 DynamoDB 테이블을 생성하고 테이블을 사용하여 애플리케이션의 상태 정보(예: 체크포인트 및 워커와 샤드의 매핑)를 보관합니다. 각각의 애플리케이션에는 자체 DynamoDB 테이블이 있습니다. 자세한 내용은 [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](shared-throughput-kcl-consumers.md#shared-throughput-kcl-consumers-leasetable) 단원을 참조하십시오.

### 보안 인증 설정
<a name="kinesis-record-processor-creds-dotnet"></a>

기본 AWS 자격 증명 공급자 체인의 자격 증명 공급자 중 하나가 자격 증명을 사용할 수 있도록 해야 합니다. `AWSCredentialsProvider` 속성을 사용하여 자격 증명 공급자를 설정할 수 있습니다. [sample.properties](https://github.com/awslabs/amazon-kinesis-client-python/blob/master/samples/sample.properties)에서 [기본 자격 증명 공급자 체인](https://docs.aws.amazon.com/sdk-for-java/latest/reference/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html)의 자격 증명 공급자 중 하나에 대해 자격 증명을 사용할 수 있도록 해야 합니다. EC2 인스턴스에서 소비자 애플리케이션을 실행하는 경우 IAM 역할로 인스턴스를 구성하는 것이 좋습니다. 이 IAM 역할과 연결된 권한을 반영하는 AWS 보안 인증은 인스턴스 메타데이터를 통해 인스턴스의 애플리케이션에 제공됩니다. 이것이 EC2 인스턴스에서 실행되는 소비자의 자격 증명을 관리하는 가장 안전한 방법입니다.

샘플의 속성 파일에서는 `AmazonKinesisSampleConsumer.cs`에 제공된 레코드 프로세서를 사용하여 'words'라는 Kinesis 데이터 스트림을 처리하도록 KCL을 구성합니다.

# Python으로 Kinesis Client Library 소비자 개발
<a name="kinesis-record-processor-implementation-app-py"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Kinesis 데이터 스트림의 데이터를 처리하는 애플리케이션을 빌드합니다. Kinesis Client Library는 여러 언어로 제공됩니다. 이 주제에서는 Python에 대해 설명합니다.

KCL은 Java 라이브러리이며, *MultiLangDaemon*이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 데몬은 Java 기반이며, Java 이외의 KCL 언어를 사용하는 경우 배경에서 실행됩니다. 따라서 Python용 KCL을 설치하고 Python으로만 소비자 앱을 작성한 경우에도 MultiLangDaemon 때문에 시스템에 Java를 설치해야 합니다. 또한 MultiLangDaemon에는 연결한 AWS 리전과 같이 사용 사례에 맞게 사용자 지정해야 할 몇 가지 기본 설정이 있습니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang) 페이지를 참조하세요.

GitHub에서 Python KCL을 다운로드하려면 [Kinesis Client Library(Python)](https://github.com/awslabs/amazon-kinesis-client-python)로 이동하세요. Python KCL 소비자 애플리케이션용 샘플 코드를 다운로드하려면 GitHub의 [Python용 KCL 샘플 프로젝트](https://github.com/awslabs/amazon-kinesis-client-python/tree/master/samples) 페이지로 이동하세요.

Python으로 KCL 소비자 애플리케이션을 구현할 때 다음 작업을 완료해야 합니다.

**Topics**
+ [RecordProcessor 클래스 메서드 구현](#kinesis-record-processor-implementation-interface-py)
+ [구성 속성 수정](#kinesis-record-processor-initialization-py)

## RecordProcessor 클래스 메서드 구현
<a name="kinesis-record-processor-implementation-interface-py"></a>

`RecordProcess` 클래스가 `RecordProcessorBase`를 확장하여 다음 메서드를 구현해야 합니다. 이 샘플에서는 시작점으로 사용할 수 있는 구현을 제공합니다(`sample_kclpy_app.py` 참조).

```
def initialize(self, shard_id)
def process_records(self, records, checkpointer)
def shutdown(self, checkpointer, reason)
```

**초기화**  
KCL은 레코드 프로세서가 인스턴스화될 때 특정 샤드 ID를 파라미터로 전달하여 `initialize` 메서드를 직접적으로 호출합니다. 이 레코드 프로세서는 해당 샤드만 처리하고 일반적으로 반대의 경우도 마찬가지입니다. 이 샤드는 해당 레코드 프로세서로만 처리됩니다. 하지만 소비자는 데이터 레코드가 두 번 이상 처리될 가능성을 고려해야 합니다. Kinesis Data Streams에서는 소비자의 워커가 샤드의 모든 데이터 레코드를 적어도 한 번은 처리한다는 *적어도 한 번* 의미론이 통용되기 때문입니다. 둘 이상의 작업자가 특정 샤드를 처리할 수 있는 경우에 대한 자세한 내용은 [리샤딩, 규모 조정 및 병렬 처리를 사용하여 샤드 수 변경](kinesis-record-processor-scaling.md)를 참조하십시오.

```
def initialize(self, shard_id)
```

**process\$1records**  
 KCL은 `initialize` 메서드에 지정된 샤드의 데이터 레코드 목록을 전달하여 이 메서드를 직접적으로 호출합니다. 구현하는 레코드 프로세서가 소비자의 의미론에 따라 이 레코드의 데이터를 처리합니다. 예를 들어, 워커가 데이터를 전환한 후 그 결과를 Amazon Simple Storage Service(S3) 버킷에 저장할 수 있습니다.

```
def process_records(self, records, checkpointer) 
```

데이터 자체뿐 아니라 시퀀스 번호와 파티션 키도 데이터 레코드에 포함됩니다. 작업자가 데이터를 처리할 때 이 값을 사용할 수 있습니다. 예를 들어, 작업자는 파티션 키의 값을 기반으로 데이터를 저장할 S3 버킷을 선택할 수 있습니다. `record` 딕셔너리가 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하기 위해 다음 키-값 페어를 노출합니다.

```
record.get('data')
record.get('sequenceNumber')
record.get('partitionKey')
```

데이터가 Base64로 인코딩됩니다.

이 샘플의 메서드 `process_records`에는 작업자가 레코드의 데이터, 시퀀스 번호 및 파티션 키에 액세스하는 방법을 보여주는 코드가 있습니다.

Kinesis Data Streams는 샤드에서 이미 처리된 레코드를 추적하도록 레코드 프로세서에 요구합니다. KCL은 `Checkpointer` 객체를 `process_records`에 전달하여 이 추적을 처리합니다. 레코드 프로세서는 해당 객체에서 `checkpoint` 메서드를 직접적으로 호출하여 샤드의 레코드 처리가 얼마나 진행되었는지를 KCL에 알려줍니다. 워커가 실패할 경우 KCL은 이 정보를 사용하여 마지막으로 처리된 레코드에서 샤드 처리를 다시 시작합니다.

분할 또는 병합 작업의 경우 소스 샤드의 프로세서가 `checkpoint`를 직접적으로 호출하여 소스 샤드의 모든 처리가 완료되었다고 표시할 때까지 KCL은 새 샤드의 처리를 시작하지 않습니다.

파라미터를 전달하지 않으면 KCL은 `checkpoint`에 대한 호출이 레코드 프로세서에 전달된 마지막 레코드까지 모두 처리되었다는 의미로 간주합니다. 따라서 레코드 프로세서는 전달된 목록에 있는 모든 레코드를 반드시 처리한 후에 `checkpoint`를 호출해야 합니다. 레코드 프로세서는 `checkpoint`를 호출할 때마다 `process_records`를 호출할 필요가 없습니다. 예를 들어, 프로세서는 세 번째 호출할 때마다 `checkpoint`를 호출할 수 있습니다. 선택적으로 레코드의 정확한 시퀀스 번호를 `checkpoint`의 파라미터로 지정할 수도 있습니다. 이 경우 KCL은 모든 레코드가 해당 레코드까지만 처리되었다고 간주합니다.

이 샘플에서는 프라이빗 메서드 `checkpoint`가 적절한 예외 처리 및 재시도 로직을 사영하여 `Checkpointer.checkpoint` 메서드를 호출하는 방법을 보여줍니다.

KCL은 `process_records`를 사용하여 데이터 레코드를 처리할 때 발생하는 모든 예외를 처리합니다. `process_records`에서 예외가 발생하면 KCL은 예외 이전에 `process_records`에 전달된 데이터 레코드를 건너뜁니다. 이러한 레코드는 예외가 발생한 프로세서 또는 소비자의 다른 레코드 프로세서로 다시 전송되지 않습니다.

**종료**  
 처리가 종료될 때(종료 이유가 `TERMINATE`) 또는 워커가 더 이상 응답하지 않을 때(종료 `reason`이 `ZOMBIE`) KCL은 `shutdown` 메서드를 직접적으로 호출합니다.

```
def shutdown(self, checkpointer, reason)
```

샤드 분할이나 병합 또는 스트림 삭제로 인해 레코드 프로세서가 샤드에서 추가 레코드를 수신하지 않으면 처리가 종료됩니다.

 또한 KCL은 `Checkpointer` 객체를 `shutdown`에 전달합니다. 종료 `reason`이 `TERMINATE`이면 레코드 프로세서가 데이터 레코드 처리를 완료하고 이 인터페이스의 `checkpoint` 메서드를 호출해야 합니다.

## 구성 속성 수정
<a name="kinesis-record-processor-initialization-py"></a>

이 샘플은 구성 속성의 기본값을 제공합니다. 속성을 사용자의 값으로 재정의할 수 있습니다(`sample.properties` 참조).

### 애플리케이션 이름
<a name="kinesis-record-processor-application-name-py"></a>

에는 다른 애플리케이션과 다르고 동일한 리전의 Amazon DynamoDB 테이블에서도 고유한 애플리케이션 이름이 필요합니다. 다음과 같이 애플리케이션 이름 구성 값이 사용됩니다.
+ 이 애플리케이션 이름과 관련된 모든 작업자는 동일한 스트림에서 함께 작업한다고 간주됩니다. 이 작업자는 여러 인스턴스에 분산되어 있을 수 있습니다. 동일한 애플리케이션 코드의 추가 인스턴스를 다른 애플리케이션 이름으로 실행하는 경우 KCL은 두 번째 인스턴스를 동일한 스트림에서 작동하는 완전히 별개의 애플리케이션으로 취급합니다.
+ KCL은 애플리케이션 이름이 있는 DynamoDB 테이블을 생성하고 테이블을 사용하여 애플리케이션의 상태 정보(예: 체크포인트 및 워커와 샤드의 매핑)를 보관합니다. 각각의 애플리케이션에는 자체 DynamoDB 테이블이 있습니다. 자세한 내용은 [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](shared-throughput-kcl-consumers.md#shared-throughput-kcl-consumers-leasetable) 단원을 참조하십시오.

### 보안 인증 설정
<a name="kinesis-record-processor-creds-py"></a>

기본 AWS 자격 증명 공급자 체인의 자격 증명 공급자 중 하나가 자격 증명을 사용할 수 있도록 해야 합니다. `AWSCredentialsProvider` 속성을 사용하여 자격 증명 공급자를 설정할 수 있습니다. [sample.properties](https://github.com/awslabs/amazon-kinesis-client-python/blob/master/samples/sample.properties)에서 [기본 자격 증명 공급자 체인](https://docs.aws.amazon.com/sdk-for-java/latest/reference/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html)의 자격 증명 공급자 중 하나에 대해 자격 증명을 사용할 수 있도록 해야 합니다. Amazon EC2 인스턴스에서 소비자 애플리케이션을 실행하는 경우 IAM 역할로 인스턴스를 구성하는 것이 좋습니다. 이 IAM 역할과 연결된 권한을 반영하는 AWS 보안 인증은 인스턴스 메타데이터를 통해 인스턴스의 애플리케이션에 제공됩니다. 이것이 EC2 인스턴스에서 실행되는 소비자 애플리케이션의 자격 증명을 관리하는 가장 안전한 방법입니다.

샘플의 속성 파일에서는 `sample_kclpy_app.py`에 제공된 레코드 프로세서를 사용하여 'words'라는 Kinesis 데이터 스트림을 처리하도록 KCL을 구성합니다.

# Ruby로 Kinesis Client Library 소비자 개발
<a name="kinesis-record-processor-implementation-app-ruby"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Kinesis 데이터 스트림의 데이터를 처리하는 애플리케이션을 빌드합니다. Kinesis Client Library는 여러 언어로 제공됩니다. 이 주제에서는 Ruby에 대해 설명합니다.

KCL은 Java 라이브러리이며, *MultiLangDaemon*이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 데몬은 Java 기반이며, Java 이외의 KCL 언어를 사용하는 경우 배경에서 실행됩니다. 따라서 Ruby용 KCL을 설치하고 Ruby로만 소비자 앱을 작성한 경우에도 MultiLangDaemon 때문에 시스템에 Java를 설치해야 합니다. 또한 MultiLangDaemon에는 연결한 AWS 리전과 같이 사용 사례에 맞게 사용자 지정해야 할 몇 가지 기본 설정이 있습니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang) 페이지를 참조하세요.

GitHub에서 Ruby KCL을 다운로드하려면 [Kinesis Client Library(Ruby)](https://github.com/awslabs/amazon-kinesis-client-ruby)로 이동하세요. Ruby KCL 소비자 애플리케이션용 샘플 코드를 다운로드하려면 GitHub의 [Ruby용 KCL 샘플 프로젝트](https://github.com/awslabs/amazon-kinesis-client-ruby/tree/master/samples) 페이지로 이동하세요.

KCL Ruby 지원 라이브러리에 대한 자세한 내용은 [KCL Ruby Gems 설명서](http://www.rubydoc.info/gems/aws-kclrb)를 참조하세요.

# KCL 2.x 소비자 개발
<a name="developing-consumers-with-kcl-v2"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

이 주제에서는 Kinesis Client Library(KCL) 버전 2.0을 사용하는 방법을 설명합니다.

KCL에 대한 자세한 내용은 [Kinesis Client Library 1.x를 사용하여 소비자 개발](https://docs.aws.amazon.com/streams/latest/dev/developing-consumers-with-kcl.html)에 나와 있는 개요를 참조하세요.

사용하려는 옵션에 따라 다음 주제 중에서 선택하세요.

**Topics**
+ [Java로 Kinesis Client Library 소비자 개발](kcl2-standard-consumer-java-example.md)
+ [Python으로 Kinesis Client Library 소비자 개발](kcl2-standard-consumer-python-example.md)
+ [KCL 2.x를 사용하여 향상된 팬아웃 소비자 개발](building-enhanced-consumers-kcl-retired.md)

# Java로 Kinesis Client Library 소비자 개발
<a name="kcl2-standard-consumer-java-example"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

다음 코드는 Java에서 `ProcessorFactory` 및 `RecordProcessor`의 구현 예를 보여 줍니다. 향상된 팬아웃 기능을 활용하고 싶다면 [향상된 팬아웃을 사용하는 소비자 만들기](https://docs.aws.amazon.com/streams/latest/dev/building-enhanced-consumers-kcl-java.html)를 참조하십시오.

```
/*
 *  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 *  Licensed under the Amazon Software License (the "License").
 *  You may not use this file except in compliance with the License.
 *  A copy of the License is located at
 *
 *  http://aws.amazon.com/asl/
 *
 *  or in the "license" file accompanying this file. This file is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 *  express or implied. See the License for the specific language governing
 *  permissions and limitations under the License.
 */


/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.kinesis.KinesisAsyncClient;
import software.amazon.awssdk.services.kinesis.model.PutRecordRequest;
import software.amazon.kinesis.common.ConfigsBuilder;
import software.amazon.kinesis.common.KinesisClientUtil;
import software.amazon.kinesis.coordinator.Scheduler;
import software.amazon.kinesis.exceptions.InvalidStateException;
import software.amazon.kinesis.exceptions.ShutdownException;
import software.amazon.kinesis.lifecycle.events.InitializationInput;
import software.amazon.kinesis.lifecycle.events.LeaseLostInput;
import software.amazon.kinesis.lifecycle.events.ProcessRecordsInput;
import software.amazon.kinesis.lifecycle.events.ShardEndedInput;
import software.amazon.kinesis.lifecycle.events.ShutdownRequestedInput;

import software.amazon.kinesis.processor.ShardRecordProcessor;
import software.amazon.kinesis.processor.ShardRecordProcessorFactory;
import software.amazon.kinesis.retrieval.polling.PollingConfig;

/**
 * This class will run a simple app that uses the KCL to read data and uses the AWS SDK to publish data.
 * Before running this program you must first create a Kinesis stream through the AWS console or AWS SDK.
 */
public class SampleSingle {

    private static final Logger log = LoggerFactory.getLogger(SampleSingle.class);

    /**
     * Invoke the main method with 2 args: the stream name and (optionally) the region.
     * Verifies valid inputs and then starts running the app.
     */
    public static void main(String... args) {
        if (args.length < 1) {
            log.error("At a minimum, the stream name is required as the first argument. The Region may be specified as the second argument.");
            System.exit(1);
        }

        String streamName = args[0];
        String region = null;
        if (args.length > 1) {
            region = args[1];
        }

        new SampleSingle(streamName, region).run();
    }

    private final String streamName;
    private final Region region;
    private final KinesisAsyncClient kinesisClient;

    /**
     * Constructor sets streamName and region. It also creates a KinesisClient object to send data to Kinesis.
     * This KinesisClient is used to send dummy data so that the consumer has something to read; it is also used
     * indirectly by the KCL to handle the consumption of the data.
     */
    private SampleSingle(String streamName, String region) {
        this.streamName = streamName;
        this.region = Region.of(ObjectUtils.firstNonNull(region, "us-east-2"));
        this.kinesisClient = KinesisClientUtil.createKinesisAsyncClient(KinesisAsyncClient.builder().region(this.region));
    }

    private void run() {

        /**
         * Sends dummy data to Kinesis. Not relevant to consuming the data with the KCL
         */
        ScheduledExecutorService producerExecutor = Executors.newSingleThreadScheduledExecutor();
        ScheduledFuture<?> producerFuture = producerExecutor.scheduleAtFixedRate(this::publishRecord, 10, 1, TimeUnit.SECONDS);

        /**
         * Sets up configuration for the KCL, including DynamoDB and CloudWatch dependencies. The final argument, a
         * ShardRecordProcessorFactory, is where the logic for record processing lives, and is located in a private
         * class below.
         */
        DynamoDbAsyncClient dynamoClient = DynamoDbAsyncClient.builder().region(region).build();
        CloudWatchAsyncClient cloudWatchClient = CloudWatchAsyncClient.builder().region(region).build();
        ConfigsBuilder configsBuilder = new ConfigsBuilder(streamName, streamName, kinesisClient, dynamoClient, cloudWatchClient, UUID.randomUUID().toString(), new SampleRecordProcessorFactory());

        /**
         * The Scheduler (also called Worker in earlier versions of the KCL) is the entry point to the KCL. This
         * instance is configured with defaults provided by the ConfigsBuilder.
         */
        Scheduler scheduler = new Scheduler(
                configsBuilder.checkpointConfig(),
                configsBuilder.coordinatorConfig(),
                configsBuilder.leaseManagementConfig(),
                configsBuilder.lifecycleConfig(),
                configsBuilder.metricsConfig(),
                configsBuilder.processorConfig(),
                configsBuilder.retrievalConfig().retrievalSpecificConfig(new PollingConfig(streamName, kinesisClient))
        );

        /**
         * Kickoff the Scheduler. Record processing of the stream of dummy data will continue indefinitely
         * until an exit is triggered.
         */
        Thread schedulerThread = new Thread(scheduler);
        schedulerThread.setDaemon(true);
        schedulerThread.start();

        /**
         * Allows termination of app by pressing Enter.
         */
        System.out.println("Press enter to shutdown");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            reader.readLine();
        } catch (IOException ioex) {
            log.error("Caught exception while waiting for confirm. Shutting down.", ioex);
        }

        /**
         * Stops sending dummy data.
         */
        log.info("Cancelling producer and shutting down executor.");
        producerFuture.cancel(true);
        producerExecutor.shutdownNow();

        /**
         * Stops consuming data. Finishes processing the current batch of data already received from Kinesis
         * before shutting down.
         */
        Future<Boolean> gracefulShutdownFuture = scheduler.startGracefulShutdown();
        log.info("Waiting up to 20 seconds for shutdown to complete.");
        try {
            gracefulShutdownFuture.get(20, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.info("Interrupted while waiting for graceful shutdown. Continuing.");
        } catch (ExecutionException e) {
            log.error("Exception while executing graceful shutdown.", e);
        } catch (TimeoutException e) {
            log.error("Timeout while waiting for shutdown.  Scheduler may not have exited.");
        }
        log.info("Completed, shutting down now.");
    }

    /**
     * Sends a single record of dummy data to Kinesis.
     */
    private void publishRecord() {
        PutRecordRequest request = PutRecordRequest.builder()
                .partitionKey(RandomStringUtils.randomAlphabetic(5, 20))
                .streamName(streamName)
                .data(SdkBytes.fromByteArray(RandomUtils.nextBytes(10)))
                .build();
        try {
            kinesisClient.putRecord(request).get();
        } catch (InterruptedException e) {
            log.info("Interrupted, assuming shutdown.");
        } catch (ExecutionException e) {
            log.error("Exception while sending data to Kinesis. Will try again next cycle.", e);
        }
    }

    private static class SampleRecordProcessorFactory implements ShardRecordProcessorFactory {
        public ShardRecordProcessor shardRecordProcessor() {
            return new SampleRecordProcessor();
        }
    }

    /**
     * The implementation of the ShardRecordProcessor interface is where the heart of the record processing logic lives.
     * In this example all we do to 'process' is log info about the records.
     */
    private static class SampleRecordProcessor implements ShardRecordProcessor {

        private static final String SHARD_ID_MDC_KEY = "ShardId";

        private static final Logger log = LoggerFactory.getLogger(SampleRecordProcessor.class);

        private String shardId;

        /**
         * Invoked by the KCL before data records are delivered to the ShardRecordProcessor instance (via
         * processRecords). In this example we do nothing except some logging.
         *
         * @param initializationInput Provides information related to initialization.
         */
        public void initialize(InitializationInput initializationInput) {
            shardId = initializationInput.shardId();
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Initializing @ Sequence: {}", initializationInput.extendedSequenceNumber());
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        /**
         * Handles record processing logic. The Amazon Kinesis Client Library will invoke this method to deliver
         * data records to the application. In this example we simply log our records.
         *
         * @param processRecordsInput Provides the records to be processed as well as information and capabilities
         *                            related to them (e.g. checkpointing).
         */
        public void processRecords(ProcessRecordsInput processRecordsInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Processing {} record(s)", processRecordsInput.records().size());
                processRecordsInput.records().forEach(r -> log.info("Processing record pk: {} -- Seq: {}", r.partitionKey(), r.sequenceNumber()));
            } catch (Throwable t) {
                log.error("Caught throwable while processing records. Aborting.");
                Runtime.getRuntime().halt(1);
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        /** Called when the lease tied to this record processor has been lost. Once the lease has been lost,
         * the record processor can no longer checkpoint.
         *
         * @param leaseLostInput Provides access to functions and data related to the loss of the lease.
         */
        public void leaseLost(LeaseLostInput leaseLostInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Lost lease, so terminating.");
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        /**
         * Called when all data on this shard has been processed. Checkpointing must occur in the method for record
         * processing to be considered complete; an exception will be thrown otherwise.
         *
         * @param shardEndedInput Provides access to a checkpointer method for completing processing of the shard.
         */
        public void shardEnded(ShardEndedInput shardEndedInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Reached shard end checkpointing.");
                shardEndedInput.checkpointer().checkpoint();
            } catch (ShutdownException | InvalidStateException e) {
                log.error("Exception while checkpointing at shard end. Giving up.", e);
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        /**
         * Invoked when Scheduler has been requested to shut down (i.e. we decide to stop running the app by pressing
         * Enter). Checkpoints and logs the data a final time.
         *
         * @param shutdownRequestedInput Provides access to a checkpointer, allowing a record processor to checkpoint
         *                               before the shutdown is completed.
         */
        public void shutdownRequested(ShutdownRequestedInput shutdownRequestedInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Scheduler is shutting down, checkpointing.");
                shutdownRequestedInput.checkpointer().checkpoint();
            } catch (ShutdownException | InvalidStateException e) {
                log.error("Exception while checkpointing at requested shutdown. Giving up.", e);
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }
    }

}
```

# Python으로 Kinesis Client Library 소비자 개발
<a name="kcl2-standard-consumer-python-example"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL)를 사용하여 Kinesis 데이터 스트림의 데이터를 처리하는 애플리케이션을 빌드합니다. Kinesis Client Library는 여러 언어로 제공됩니다. 이 주제에서는 Python에 대해 설명합니다.

KCL은 Java 라이브러리이며, *MultiLangDaemon*이라는 다중 언어 인터페이스를 통해 Java 이외의 언어에 대한 지원이 제공됩니다. 이 데몬은 Java 기반이며, Java 이외의 KCL 언어를 사용하는 경우 배경에서 실행됩니다. 따라서 Python용 KCL을 설치하고 Python으로만 소비자 앱을 작성한 경우에도 MultiLangDaemon 때문에 시스템에 Java를 설치해야 합니다. 또한 MultiLangDaemon에는 연결한 AWS 리전과 같이 사용 사례에 맞게 사용자 지정해야 할 몇 가지 기본 설정이 있습니다. GitHub의 MultiLangDaemon에 대한 자세한 내용은 [KCL MultiLangDaemon 프로젝트](https://github.com/awslabs/amazon-kinesis-client/tree/v1.x/src/main/java/com/amazonaws/services/kinesis/multilang) 페이지를 참조하세요.

GitHub에서 Python KCL을 다운로드하려면 [Kinesis Client Library(Python)](https://github.com/awslabs/amazon-kinesis-client-python)로 이동하세요. Python KCL 소비자 애플리케이션용 샘플 코드를 다운로드하려면 GitHub의 [Python용 KCL 샘플 프로젝트](https://github.com/awslabs/amazon-kinesis-client-python/tree/master/samples) 페이지로 이동하세요.

Python으로 KCL 소비자 애플리케이션을 구현할 때 다음 작업을 완료해야 합니다.

**Topics**
+ [RecordProcessor 클래스 메서드 구현](#kinesis-record-processor-implementation-interface-py)
+ [구성 속성 수정](#kinesis-record-processor-initialization-py)

## RecordProcessor 클래스 메서드 구현
<a name="kinesis-record-processor-implementation-interface-py"></a>

`RecordProcess` 클래스가 `RecordProcessorBase` 클래스를 확장하여 다음 메서드를 구현해야 합니다.

```
initialize
process_records
shutdown_requested
```

이 샘플의 구현을 시작점으로 이용할 수 있습니다.

```
#!/usr/bin/env python

# Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Amazon Software License (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/asl/
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

from __future__ import print_function

import sys
import time

from amazon_kclpy import kcl
from amazon_kclpy.v3 import processor


class RecordProcessor(processor.RecordProcessorBase):
    """
    A RecordProcessor processes data from a shard in a stream. Its methods will be called with this pattern:

    * initialize will be called once
    * process_records will be called zero or more times
    * shutdown will be called if this MultiLangDaemon instance loses the lease to this shard, or the shard ends due
        a scaling change.
    """
    def __init__(self):
        self._SLEEP_SECONDS = 5
        self._CHECKPOINT_RETRIES = 5
        self._CHECKPOINT_FREQ_SECONDS = 60
        self._largest_seq = (None, None)
        self._largest_sub_seq = None
        self._last_checkpoint_time = None

    def log(self, message):
        sys.stderr.write(message)

    def initialize(self, initialize_input):
        """
        Called once by a KCLProcess before any calls to process_records

        :param amazon_kclpy.messages.InitializeInput initialize_input: Information about the lease that this record
            processor has been assigned.
        """
        self._largest_seq = (None, None)
        self._last_checkpoint_time = time.time()

    def checkpoint(self, checkpointer, sequence_number=None, sub_sequence_number=None):
        """
        Checkpoints with retries on retryable exceptions.

        :param amazon_kclpy.kcl.Checkpointer checkpointer: the checkpointer provided to either process_records
            or shutdown
        :param str or None sequence_number: the sequence number to checkpoint at.
        :param int or None sub_sequence_number: the sub sequence number to checkpoint at.
        """
        for n in range(0, self._CHECKPOINT_RETRIES):
            try:
                checkpointer.checkpoint(sequence_number, sub_sequence_number)
                return
            except kcl.CheckpointError as e:
                if 'ShutdownException' == e.value:
                    #
                    # A ShutdownException indicates that this record processor should be shutdown. This is due to
                    # some failover event, e.g. another MultiLangDaemon has taken the lease for this shard.
                    #
                    print('Encountered shutdown exception, skipping checkpoint')
                    return
                elif 'ThrottlingException' == e.value:
                    #
                    # A ThrottlingException indicates that one of our dependencies is is over burdened, e.g. too many
                    # dynamo writes. We will sleep temporarily to let it recover.
                    #
                    if self._CHECKPOINT_RETRIES - 1 == n:
                        sys.stderr.write('Failed to checkpoint after {n} attempts, giving up.\n'.format(n=n))
                        return
                    else:
                        print('Was throttled while checkpointing, will attempt again in {s} seconds'
                              .format(s=self._SLEEP_SECONDS))
                elif 'InvalidStateException' == e.value:
                    sys.stderr.write('MultiLangDaemon reported an invalid state while checkpointing.\n')
                else:  # Some other error
                    sys.stderr.write('Encountered an error while checkpointing, error was {e}.\n'.format(e=e))
            time.sleep(self._SLEEP_SECONDS)

    def process_record(self, data, partition_key, sequence_number, sub_sequence_number):
        """
        Called for each record that is passed to process_records.

        :param str data: The blob of data that was contained in the record.
        :param str partition_key: The key associated with this recod.
        :param int sequence_number: The sequence number associated with this record.
        :param int sub_sequence_number: the sub sequence number associated with this record.
        """
        ####################################
        # Insert your processing logic here
        ####################################
        self.log("Record (Partition Key: {pk}, Sequence Number: {seq}, Subsequence Number: {sseq}, Data Size: {ds}"
                 .format(pk=partition_key, seq=sequence_number, sseq=sub_sequence_number, ds=len(data)))

    def should_update_sequence(self, sequence_number, sub_sequence_number):
        """
        Determines whether a new larger sequence number is available

        :param int sequence_number: the sequence number from the current record
        :param int sub_sequence_number: the sub sequence number from the current record
        :return boolean: true if the largest sequence should be updated, false otherwise
        """
        return self._largest_seq == (None, None) or sequence_number > self._largest_seq[0] or \
            (sequence_number == self._largest_seq[0] and sub_sequence_number > self._largest_seq[1])

    def process_records(self, process_records_input):
        """
        Called by a KCLProcess with a list of records to be processed and a checkpointer which accepts sequence numbers
        from the records to indicate where in the stream to checkpoint.

        :param amazon_kclpy.messages.ProcessRecordsInput process_records_input: the records, and metadata about the
            records.
        """
        try:
            for record in process_records_input.records:
                data = record.binary_data
                seq = int(record.sequence_number)
                sub_seq = record.sub_sequence_number
                key = record.partition_key
                self.process_record(data, key, seq, sub_seq)
                if self.should_update_sequence(seq, sub_seq):
                    self._largest_seq = (seq, sub_seq)

            #
            # Checkpoints every self._CHECKPOINT_FREQ_SECONDS seconds
            #
            if time.time() - self._last_checkpoint_time > self._CHECKPOINT_FREQ_SECONDS:
                self.checkpoint(process_records_input.checkpointer, str(self._largest_seq[0]), self._largest_seq[1])
                self._last_checkpoint_time = time.time()

        except Exception as e:
            self.log("Encountered an exception while processing records. Exception was {e}\n".format(e=e))

    def lease_lost(self, lease_lost_input):
        self.log("Lease has been lost")

    def shard_ended(self, shard_ended_input):
        self.log("Shard has ended checkpointing")
        shard_ended_input.checkpointer.checkpoint()

    def shutdown_requested(self, shutdown_requested_input):
        self.log("Shutdown has been requested, checkpointing.")
        shutdown_requested_input.checkpointer.checkpoint()


if __name__ == "__main__":
    kcl_process = kcl.KCLProcess(RecordProcessor())
    kcl_process.run()
```

## 구성 속성 수정
<a name="kinesis-record-processor-initialization-py"></a>

이 샘플은 아래 스크립트에 나와 있는 구성 속성의 기본값을 제공합니다. 속성을 원하는 값으로 재정의할 수 있습니다.

```
# The script that abides by the multi-language protocol. This script will
# be executed by the MultiLangDaemon, which will communicate with this script
# over STDIN and STDOUT according to the multi-language protocol.
executableName = sample_kclpy_app.py

# The name of an Amazon Kinesis stream to process.
streamName = words

# Used by the KCL as the name of this application. Will be used as the name
# of an Amazon DynamoDB table which will store the lease and checkpoint
# information for workers with this application name
applicationName = PythonKCLSample

# Users can change the credentials provider the KCL will use to retrieve credentials.
# The DefaultAWSCredentialsProviderChain checks several other providers, which is
# described here:
# http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html
AWSCredentialsProvider = DefaultAWSCredentialsProviderChain

# Appended to the user agent of the KCL. Does not impact the functionality of the
# KCL in any other way.
processingLanguage = python/2.7

# Valid options at TRIM_HORIZON or LATEST.
# See http://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetShardIterator.html#API_GetShardIterator_RequestSyntax
initialPositionInStream = TRIM_HORIZON

# The following properties are also available for configuring the KCL Worker that is created
# by the MultiLangDaemon.

# The KCL defaults to us-east-1
#regionName = us-east-1

# Fail over time in milliseconds. A worker which does not renew it's lease within this time interval
# will be regarded as having problems and it's shards will be assigned to other workers.
# For applications that have a large number of shards, this msy be set to a higher number to reduce
# the number of DynamoDB IOPS required for tracking leases
#failoverTimeMillis = 10000

# A worker id that uniquely identifies this worker among all workers using the same applicationName
# If this isn't provided a MultiLangDaemon instance will assign a unique workerId to itself.
#workerId = 

# Shard sync interval in milliseconds - e.g. wait for this long between shard sync tasks.
#shardSyncIntervalMillis = 60000

# Max records to fetch from Kinesis in a single GetRecords call.
#maxRecords = 10000

# Idle time between record reads in milliseconds.
#idleTimeBetweenReadsInMillis = 1000

# Enables applications flush/checkpoint (if they have some data "in progress", but don't get new data for while)
#callProcessRecordsEvenForEmptyRecordList = false

# Interval in milliseconds between polling to check for parent shard completion.
# Polling frequently will take up more DynamoDB IOPS (when there are leases for shards waiting on
# completion of parent shards).
#parentShardPollIntervalMillis = 10000

# Cleanup leases upon shards completion (don't wait until they expire in Kinesis).
# Keeping leases takes some tracking/resources (e.g. they need to be renewed, assigned), so by default we try
# to delete the ones we don't need any longer.
#cleanupLeasesUponShardCompletion = true

# Backoff time in milliseconds for Amazon Kinesis Client Library tasks (in the event of failures).
#taskBackoffTimeMillis = 500

# Buffer metrics for at most this long before publishing to CloudWatch.
#metricsBufferTimeMillis = 10000

# Buffer at most this many metrics before publishing to CloudWatch.
#metricsMaxQueueSize = 10000

# KCL will validate client provided sequence numbers with a call to Amazon Kinesis before checkpointing for calls
# to RecordProcessorCheckpointer#checkpoint(String) by default.
#validateSequenceNumberBeforeCheckpointing = true

# The maximum number of active threads for the MultiLangDaemon to permit.
# If a value is provided then a FixedThreadPool is used with the maximum
# active threads set to the provided value. If a non-positive integer or no
# value is provided a CachedThreadPool is used.
#maxActiveThreads = 0
```

### 애플리케이션 이름
<a name="kinesis-record-processor-application-name-py"></a>

KCL에는 다른 애플리케이션과 다르고 동일한 리전의 Amazon DynamoDB 테이블에서도 고유한 애플리케이션 이름이 필요합니다. 다음과 같이 애플리케이션 이름 구성 값이 사용됩니다.
+ 이 애플리케이션 이름과 관련된 모든 작업자는 동일한 스트림에서 함께 작업한다고 간주됩니다. 작업자는 여러 인스턴스에 분산되어 있을 수 있습니다. 동일한 애플리케이션 코드의 추가 인스턴스를 다른 애플리케이션 이름으로 실행하는 경우 KCL은 두 번째 인스턴스를 동일한 스트림에서 작동하는 완전히 별개의 애플리케이션으로 취급합니다.
+ KCL은 애플리케이션 이름이 있는 DynamoDB 테이블을 생성하고 테이블을 사용하여 애플리케이션의 상태 정보(예: 체크포인트 및 워커와 샤드의 매핑)를 보관합니다. 각각의 애플리케이션에는 자체 DynamoDB 테이블이 있습니다. 자세한 내용은 [리스 테이블을 사용하여 KCL 소비자 애플리케이션에서 처리한 샤드 추적](shared-throughput-kcl-consumers.md#shared-throughput-kcl-consumers-leasetable) 단원을 참조하십시오.

### 자격 증명
<a name="kinesis-record-processor-creds-py"></a>

기본 AWS 자격 증명 공급자 [체인의 자격 증명 공급자 중 하나가 자격 증명을](https://docs.aws.amazon.com/sdk-for-java/latest/reference/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html) 사용할 수 있도록 해야 합니다. `AWSCredentialsProvider` 속성을 사용하여 자격 증명 공급자를 설정할 수 있습니다. Amazon EC2 인스턴스에서 소비자 애플리케이션을 실행하는 경우 IAM 역할로 인스턴스를 구성하는 것이 좋습니다.이 IAM 역할과 연결된 권한을 반영하는 AWS 자격 증명은 인스턴스 메타데이터를 통해 인스턴스의 애플리케이션에 제공됩니다. 이것이 EC2 인스턴스에서 실행되는 소비자 애플리케이션의 자격 증명을 관리하는 가장 안전한 방법입니다.

# KCL 2.x를 사용하여 향상된 팬아웃 소비자 개발
<a name="building-enhanced-consumers-kcl-retired"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Amazon Kinesis Data Streams에서 **향상된 팬아웃을 사용하는 소비자는 샤드당 초당 최대 데이터 2MB의 전용 처리량으로 데이터 스트림에서 레코드를 수신할 수 있습니다. 이 유형의 소비자는 스트림으로부터 데이터를 수신하는 다른 소비자와 경쟁할 필요가 없습니다. 자세한 내용은 [전용 처리량으로 향상된 팬아웃 소비자 개발](enhanced-consumers.md) 단원을 참조하십시오.

Kinesis Client Library(KCL) 버전 2.0 이상을 사용하면 향상된 팬아웃을 사용하여 스트림으로부터 데이터를 수신하는 애플리케이션을 개발할 수 있습니다. KCL은 애플리케이션을 스트림의 모든 샤드에 자동으로 등록하므로 소비자 애플리케이션이 샤드당 2MB/sec의 처리 속도로 읽을 수 있습니다. 향상된 팬아웃을 켜지 않고 KCL을 사용하고 싶다면 [Developing Consumers Using the Kinesis Client Library 2.0](https://docs.aws.amazon.com/streams/latest/dev/developing-consumers-with-kcl-v2.html)을 참조하세요.

**Topics**
+ [Java에서 KCL 2.x를 사용하여 향상된 팬아웃 소비자 개발](building-enhanced-consumers-kcl-java.md)

# Java에서 KCL 2.x를 사용하여 향상된 팬아웃 소비자 개발
<a name="building-enhanced-consumers-kcl-java"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

Kinesis Client Library(KCL) 버전 2.0 이상을 사용하면 Amazon Kinesis Data Streams에서 향상된 팬아웃을 통해 스트림에서 데이터를 수신하는 애플리케이션을 개발할 수 있습니다. 다음 코드는 Java에서 `ProcessorFactory` 및 `RecordProcessor`의 구현 예를 보여 줍니다.

`KinesisClientUtil`을 사용하여 `KinesisAsyncClient`를 만들고 `KinesisAsyncClient`에 `maxConcurrency`를 구성하는 것이 좋습니다.

**중요**  
Amazon Kinesis Client는 `KinesisAsyncClient`를 구성하여 `KinesisAsyncClient`의 전체 임대 수에 더해 추가 사용량까지 허용할 수 있을 만큼 `maxConcurrency`를 충분히 높이지 않을 경우 지연 시간이 크게 증가할 수 있습니다.

```
/*
 *  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 *  Licensed under the Amazon Software License (the "License").
 *  You may not use this file except in compliance with the License.
 *  A copy of the License is located at
 *
 *  http://aws.amazon.com/asl/
 *
 *  or in the "license" file accompanying this file. This file is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 *  express or implied. See the License for the specific language governing
 *  permissions and limitations under the License. 
 */

/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.kinesis.KinesisAsyncClient;
import software.amazon.awssdk.services.kinesis.model.PutRecordRequest;
import software.amazon.kinesis.common.ConfigsBuilder;
import software.amazon.kinesis.common.KinesisClientUtil;
import software.amazon.kinesis.coordinator.Scheduler;
import software.amazon.kinesis.exceptions.InvalidStateException;
import software.amazon.kinesis.exceptions.ShutdownException;
import software.amazon.kinesis.lifecycle.events.InitializationInput;
import software.amazon.kinesis.lifecycle.events.LeaseLostInput;
import software.amazon.kinesis.lifecycle.events.ProcessRecordsInput;
import software.amazon.kinesis.lifecycle.events.ShardEndedInput;
import software.amazon.kinesis.lifecycle.events.ShutdownRequestedInput;
import software.amazon.kinesis.processor.ShardRecordProcessor;
import software.amazon.kinesis.processor.ShardRecordProcessorFactory;

public class SampleSingle {

    private static final Logger log = LoggerFactory.getLogger(SampleSingle.class);

    public static void main(String... args) {
        if (args.length < 1) {
            log.error("At a minimum, the stream name is required as the first argument. The Region may be specified as the second argument.");
            System.exit(1);
        }

        String streamName = args[0];
        String region = null;
        if (args.length > 1) {
            region = args[1];
        }

        new SampleSingle(streamName, region).run();
    }

    private final String streamName;
    private final Region region;
    private final KinesisAsyncClient kinesisClient;

    private SampleSingle(String streamName, String region) {
        this.streamName = streamName;
        this.region = Region.of(ObjectUtils.firstNonNull(region, "us-east-2"));
        this.kinesisClient = KinesisClientUtil.createKinesisAsyncClient(KinesisAsyncClient.builder().region(this.region));
    }

    private void run() {
        ScheduledExecutorService producerExecutor = Executors.newSingleThreadScheduledExecutor();
        ScheduledFuture<?> producerFuture = producerExecutor.scheduleAtFixedRate(this::publishRecord, 10, 1, TimeUnit.SECONDS);

        DynamoDbAsyncClient dynamoClient = DynamoDbAsyncClient.builder().region(region).build();
        CloudWatchAsyncClient cloudWatchClient = CloudWatchAsyncClient.builder().region(region).build();
        ConfigsBuilder configsBuilder = new ConfigsBuilder(streamName, streamName, kinesisClient, dynamoClient, cloudWatchClient, UUID.randomUUID().toString(), new SampleRecordProcessorFactory());

        Scheduler scheduler = new Scheduler(
                configsBuilder.checkpointConfig(),
                configsBuilder.coordinatorConfig(),
                configsBuilder.leaseManagementConfig(),
                configsBuilder.lifecycleConfig(),
                configsBuilder.metricsConfig(),
                configsBuilder.processorConfig(),
                configsBuilder.retrievalConfig()
        );

        Thread schedulerThread = new Thread(scheduler);
        schedulerThread.setDaemon(true);
        schedulerThread.start();

        System.out.println("Press enter to shutdown");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            reader.readLine();
        } catch (IOException ioex) {
            log.error("Caught exception while waiting for confirm. Shutting down.", ioex);
        }

        log.info("Cancelling producer, and shutting down executor.");
        producerFuture.cancel(true);
        producerExecutor.shutdownNow();

        Future<Boolean> gracefulShutdownFuture = scheduler.startGracefulShutdown();
        log.info("Waiting up to 20 seconds for shutdown to complete.");
        try {
            gracefulShutdownFuture.get(20, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.info("Interrupted while waiting for graceful shutdown. Continuing.");
        } catch (ExecutionException e) {
            log.error("Exception while executing graceful shutdown.", e);
        } catch (TimeoutException e) {
            log.error("Timeout while waiting for shutdown. Scheduler may not have exited.");
        }
        log.info("Completed, shutting down now.");
    }

    private void publishRecord() {
        PutRecordRequest request = PutRecordRequest.builder()
                .partitionKey(RandomStringUtils.randomAlphabetic(5, 20))
                .streamName(streamName)
                .data(SdkBytes.fromByteArray(RandomUtils.nextBytes(10)))
                .build();
        try {
            kinesisClient.putRecord(request).get();
        } catch (InterruptedException e) {
            log.info("Interrupted, assuming shutdown.");
        } catch (ExecutionException e) {
            log.error("Exception while sending data to Kinesis. Will try again next cycle.", e);
        }
    }

    private static class SampleRecordProcessorFactory implements ShardRecordProcessorFactory {
        public ShardRecordProcessor shardRecordProcessor() {
            return new SampleRecordProcessor();
        }
    }


    private static class SampleRecordProcessor implements ShardRecordProcessor {

        private static final String SHARD_ID_MDC_KEY = "ShardId";

        private static final Logger log = LoggerFactory.getLogger(SampleRecordProcessor.class);

        private String shardId;

        public void initialize(InitializationInput initializationInput) {
            shardId = initializationInput.shardId();
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Initializing @ Sequence: {}", initializationInput.extendedSequenceNumber());
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        public void processRecords(ProcessRecordsInput processRecordsInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Processing {} record(s)", processRecordsInput.records().size());
                processRecordsInput.records().forEach(r -> log.info("Processing record pk: {} -- Seq: {}", r.partitionKey(), r.sequenceNumber()));
            } catch (Throwable t) {
                log.error("Caught throwable while processing records. Aborting.");
                Runtime.getRuntime().halt(1);
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        public void leaseLost(LeaseLostInput leaseLostInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Lost lease, so terminating.");
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        public void shardEnded(ShardEndedInput shardEndedInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Reached shard end checkpointing.");
                shardEndedInput.checkpointer().checkpoint();
            } catch (ShutdownException | InvalidStateException e) {
                log.error("Exception while checkpointing at shard end. Giving up.", e);
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }

        public void shutdownRequested(ShutdownRequestedInput shutdownRequestedInput) {
            MDC.put(SHARD_ID_MDC_KEY, shardId);
            try {
                log.info("Scheduler is shutting down, checkpointing.");
                shutdownRequestedInput.checkpointer().checkpoint();
            } catch (ShutdownException | InvalidStateException e) {
                log.error("Exception while checkpointing at requested shutdown. Giving up.", e);
            } finally {
                MDC.remove(SHARD_ID_MDC_KEY);
            }
        }
    }

}
```

# KCL 1.x에서 KCL 2.x로 소비자 마이그레이션
<a name="kcl-migration"></a>

**중요**  
Amazon Kinesis Client Library(KCL) 버전 1.x 및 2.x는 오래되었습니다. KCL 1.x는 2026년 1월 30일에 지원이 종료됩니다. 버전 1.x를 사용하는 KCL 애플리케이션은 2026년 1월 30일 이전에 최신 KCL 버전으로 마이그레이션할 것을 **적극 권장**합니다. 최신 KCL 버전을 찾으려면 [GitHub의 Amazon Kinesis Client Library 페이지](https://github.com/awslabs/amazon-kinesis-client)를 참조하세요. 최신 KCL 버전에 대한 자세한 내용은 [Kinesis Client Library 사용](kcl.md) 섹션을 참조하세요. KCL 1.x에서 KCL 3.x로 마이그레이션하는 방법에 대한 자세한 내용은 [KCL 1.x에서 KCL 3.x로 마이그레이션](kcl-migration-1-3.md) 섹션을 참조하세요.

이 주제에서는 Kinesis Client Library(KCL) 버전 1.x와 버전 2.x 간의 차이점을 설명합니다. 또한, 소비자를 KCL 버전 1.x에서 버전 2.x로 마이그레이션하는 방법을 알려 드립니다. 클라이언트 마이그레이션 후 마지막 체크포인트 위치에서 처리 기록을 시작합니다.

KCL 버전 2.0에서는 다음과 같은 인터페이스 변경이 이루어졌습니다.


**KCL 인터페이스 변경 사항**  

| KCL 1.x 인터페이스 | KCL 2.0 인터페이스 | 
| --- | --- | 
| com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor | software.amazon.kinesis.processor.ShardRecordProcessor | 
| com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessorFactory | software.amazon.kinesis.processor.ShardRecordProcessorFactory | 
| com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IShutdownNotificationAware | software.amazon.kinesis.processor.ShardRecordProcessor에 포함됨 | 

**Topics**
+ [레코드 프로세서 마이그레이션](#recrod-processor-migration)
+ [레코드 프로세서 팩토리 마이그레이션](#recrod-processor-factory-migration)
+ [작업자 마이그레이션](#worker-migration)
+ [Amazon Kinesis 클라이언트 구성](#client-configuration)
+ [유휴 시간 제거](#idle-time-removal)
+ [클라이언트 구성 제거](#client-configuration-removals)

## 레코드 프로세서 마이그레이션
<a name="recrod-processor-migration"></a>

다음은 KCL 1.x에 구현된 레코드 프로세서를 보여주는 예제입니다.

```
package com.amazonaws.kcl;

import com.amazonaws.services.kinesis.clientlibrary.exceptions.InvalidStateException;
import com.amazonaws.services.kinesis.clientlibrary.exceptions.ShutdownException;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorCheckpointer;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IShutdownNotificationAware;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.ShutdownReason;
import com.amazonaws.services.kinesis.clientlibrary.types.InitializationInput;
import com.amazonaws.services.kinesis.clientlibrary.types.ProcessRecordsInput;
import com.amazonaws.services.kinesis.clientlibrary.types.ShutdownInput;

public class TestRecordProcessor implements IRecordProcessor, IShutdownNotificationAware {
    @Override
    public void initialize(InitializationInput initializationInput) {
        //
        // Setup record processor
        //
    }

    @Override
    public void processRecords(ProcessRecordsInput processRecordsInput) {
        //
        // Process records, and possibly checkpoint
        //
    }

    @Override
    public void shutdown(ShutdownInput shutdownInput) {
        if (shutdownInput.getShutdownReason() == ShutdownReason.TERMINATE) {
            try {
                shutdownInput.getCheckpointer().checkpoint();
            } catch (ShutdownException | InvalidStateException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void shutdownRequested(IRecordProcessorCheckpointer checkpointer) {
        try {
            checkpointer.checkpoint();
        } catch (ShutdownException | InvalidStateException e) {
            //
            // Swallow exception
            //
            e.printStackTrace();
        }
    }
}
```

**레코드 프로세서 클래스를 마이그레이션하려면**

1. 다음과 같이 `com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor` 및 `com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IShutdownNotificationAware`의 인터페이스를 `software.amazon.kinesis.processor.ShardRecordProcessor`로 변경합니다.

   ```
   // import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor;
   // import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IShutdownNotificationAware;
   import software.amazon.kinesis.processor.ShardRecordProcessor;
   
   // public class TestRecordProcessor implements IRecordProcessor, IShutdownNotificationAware {
   public class TestRecordProcessor implements ShardRecordProcessor {
   ```

1. `import` 및 `initialize` 메서드의 `processRecords` 문을 업데이트합니다.

   ```
   // import com.amazonaws.services.kinesis.clientlibrary.types.InitializationInput;
   import software.amazon.kinesis.lifecycle.events.InitializationInput;
   
   //import com.amazonaws.services.kinesis.clientlibrary.types.ProcessRecordsInput;
   import software.amazon.kinesis.lifecycle.events.ProcessRecordsInput;
   ```

1. `shutdown` 메서드를 새 메서드인 `leaseLost`, `shardEnded`, `shutdownRequested`으로 바꿉니다.

   ```
   //    @Override
   //    public void shutdownRequested(IRecordProcessorCheckpointer checkpointer) {
   //        //
   //        // This is moved to shardEnded(...)
   //        //
   //        try {
   //            checkpointer.checkpoint();
   //        } catch (ShutdownException | InvalidStateException e) {
   //            //
   //            // Swallow exception
   //            //
   //            e.printStackTrace();
   //        }
   //    }
   
       @Override
       public void leaseLost(LeaseLostInput leaseLostInput) {
   
       }
   
       @Override
       public void shardEnded(ShardEndedInput shardEndedInput) {
           try {
               shardEndedInput.checkpointer().checkpoint();
           } catch (ShutdownException | InvalidStateException e) {
               //
               // Swallow the exception
               //
               e.printStackTrace();
           }
       }
   
   //    @Override
   //    public void shutdownRequested(IRecordProcessorCheckpointer checkpointer) {
   //        //
   //        // This is moved to shutdownRequested(ShutdownReauestedInput)
   //        //
   //        try {
   //            checkpointer.checkpoint();
   //        } catch (ShutdownException | InvalidStateException e) {
   //            //
   //            // Swallow exception
   //            //
   //            e.printStackTrace();
   //        }
   //    }
   
       @Override
       public void shutdownRequested(ShutdownRequestedInput shutdownRequestedInput) {
           try {
               shutdownRequestedInput.checkpointer().checkpoint();
           } catch (ShutdownException | InvalidStateException e) {
               //
               // Swallow the exception
               //
               e.printStackTrace();
           }
       }
   ```

다음은 업데이트된 버전의 레코드 프로세서 클래스입니다.

```
package com.amazonaws.kcl;

import software.amazon.kinesis.exceptions.InvalidStateException;
import software.amazon.kinesis.exceptions.ShutdownException;
import software.amazon.kinesis.lifecycle.events.InitializationInput;
import software.amazon.kinesis.lifecycle.events.LeaseLostInput;
import software.amazon.kinesis.lifecycle.events.ProcessRecordsInput;
import software.amazon.kinesis.lifecycle.events.ShardEndedInput;
import software.amazon.kinesis.lifecycle.events.ShutdownRequestedInput;
import software.amazon.kinesis.processor.ShardRecordProcessor;

public class TestRecordProcessor implements ShardRecordProcessor {
    @Override
    public void initialize(InitializationInput initializationInput) {
        
    }

    @Override
    public void processRecords(ProcessRecordsInput processRecordsInput) {
        
    }

    @Override
    public void leaseLost(LeaseLostInput leaseLostInput) {
        
    }

    @Override
    public void shardEnded(ShardEndedInput shardEndedInput) {
        try {
            shardEndedInput.checkpointer().checkpoint();
        } catch (ShutdownException | InvalidStateException e) {
            //
            // Swallow the exception
            //
            e.printStackTrace();
        }
    }

    @Override
    public void shutdownRequested(ShutdownRequestedInput shutdownRequestedInput) {
        try {
            shutdownRequestedInput.checkpointer().checkpoint();
        } catch (ShutdownException | InvalidStateException e) {
            //
            // Swallow the exception
            //
            e.printStackTrace();
        }
    }
}
```

## 레코드 프로세서 팩토리 마이그레이션
<a name="recrod-processor-factory-migration"></a>

레코드 프로세스 팩토리는 리스가 필요할 경우 레코드 프로세서 생성을 담당합니다. 다음은 KCL 1.x 팩토리의 예입니다.

```
package com.amazonaws.kcl;

import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessorFactory;

public class TestRecordProcessorFactory implements IRecordProcessorFactory {
    @Override
    public IRecordProcessor createProcessor() {
        return new TestRecordProcessor();
    }
}
```

**레코드 프로세서 팩토리를 마이그레이션하려면**

1. 구현된 인터페이스를 다음과 같이 `com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessorFactory`에서 `software.amazon.kinesis.processor.ShardRecordProcessorFactory`로 변경합니다.

   ```
   // import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessor;
   import software.amazon.kinesis.processor.ShardRecordProcessor;
   
   // import com.amazonaws.services.kinesis.clientlibrary.interfaces.v2.IRecordProcessorFactory;
   import software.amazon.kinesis.processor.ShardRecordProcessorFactory;
   
   // public class TestRecordProcessorFactory implements IRecordProcessorFactory {
   public class TestRecordProcessorFactory implements ShardRecordProcessorFactory {
   ```

1. `createProcessor`에 대한 반환 서명을 변경합니다.

   ```
   // public IRecordProcessor createProcessor() {
   public ShardRecordProcessor shardRecordProcessor() {
   ```

다음은 2.0의 레코드 프로세서 팩토리의 예입니다.

```
package com.amazonaws.kcl;

import software.amazon.kinesis.processor.ShardRecordProcessor;
import software.amazon.kinesis.processor.ShardRecordProcessorFactory;

public class TestRecordProcessorFactory implements ShardRecordProcessorFactory {
    @Override
    public ShardRecordProcessor shardRecordProcessor() {
        return new TestRecordProcessor();
    }
}
```

## 작업자 마이그레이션
<a name="worker-migration"></a>

KCL 버전 2.0에서는 `Scheduler`라는 새로운 클래스가 `Worker` 클래스를 대체합니다. 다음은 KCL 1.x 워커의 예입니다.

```
final KinesisClientLibConfiguration config = new KinesisClientLibConfiguration(...)
final IRecordProcessorFactory recordProcessorFactory = new RecordProcessorFactory();
final Worker worker = new Worker.Builder()
    .recordProcessorFactory(recordProcessorFactory)
    .config(config)
    .build();
```

**작업자를 마이그레이션하려면**

1. `Worker` 클래스에 대한 `import` 문을 `Scheduler` 및 `ConfigsBuilder` 클래스에 대한 가져오기 문으로 변경합니다.

   ```
   // import com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker;
   import software.amazon.kinesis.coordinator.Scheduler;
   import software.amazon.kinesis.common.ConfigsBuilder;
   ```

1. 다음 예와 같이 `ConfigsBuilder` 및 `Scheduler`를 생성합니다.

   `KinesisClientUtil`을 사용하여 `KinesisAsyncClient`를 만들고 `KinesisAsyncClient`에 `maxConcurrency`를 구성하는 것이 좋습니다.
**중요**  
Amazon Kinesis Client는 `KinesisAsyncClient`를 구성하여 `KinesisAsyncClient`의 전체 임대 수에 더해 추가 사용량까지 허용할 수 있을 만큼 `maxConcurrency`를 충분히 높이지 않을 경우 지연 시간이 크게 증가할 수 있습니다.

   ```
   import java.util.UUID;
   
   import software.amazon.awssdk.regions.Region;
   import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
   import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;
   import software.amazon.awssdk.services.kinesis.KinesisAsyncClient;
   import software.amazon.kinesis.common.ConfigsBuilder;
   import software.amazon.kinesis.common.KinesisClientUtil;
   import software.amazon.kinesis.coordinator.Scheduler;
   
   ...
   
   Region region = Region.AP_NORTHEAST_2;
   KinesisAsyncClient kinesisClient = KinesisClientUtil.createKinesisAsyncClient(KinesisAsyncClient.builder().region(region));
   DynamoDbAsyncClient dynamoClient = DynamoDbAsyncClient.builder().region(region).build();
   CloudWatchAsyncClient cloudWatchClient = CloudWatchAsyncClient.builder().region(region).build();
   
   ConfigsBuilder configsBuilder = new ConfigsBuilder(streamName, applicationName, kinesisClient, dynamoClient, cloudWatchClient, UUID.randomUUID().toString(), new SampleRecordProcessorFactory());
   
   Scheduler scheduler = new Scheduler(
       configsBuilder.checkpointConfig(),
       configsBuilder.coordinatorConfig(),
       configsBuilder.leaseManagementConfig(),
       configsBuilder.lifecycleConfig(),
       configsBuilder.metricsConfig(),
       configsBuilder.processorConfig(),
       configsBuilder.retrievalConfig()
       );
   ```

## Amazon Kinesis 클라이언트 구성
<a name="client-configuration"></a>

Kinesis Client Library 2.0 릴리스에서는 클라이언트 구성이 단일 구성 클래스(`KinesisClientLibConfiguration`)에서 6개 구성 클래스로 이동했습니다. 다음 표에 마이그레이션에 대한 설명이 나와 있습니다.


**구성 필드와 새 클래스**  

| 원래 필드 | 새 구성 클래스 | 설명 | 
| --- | --- | --- | 
| applicationName | ConfigsBuilder | 이 KCL 애플리케이션의 이름입니다. tableName 및 consumerName의 기본값으로 사용됩니다. | 
| tableName | ConfigsBuilder | Amazon DynamoDB 리스 테이블에 사용된 테이블 이름 재정의를 허용합니다. | 
| streamName | ConfigsBuilder | 이 애플리케이션이 레코드를 처리하는 스트림의 이름입니다. | 
| kinesisEndpoint | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| dynamoDBEndpoint | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| initialPositionInStreamExtended | RetrievalConfig | KCL의 레코드 가져오기가 시작되는 샤드의 위치입니다(애플리케이션의 초기 실행으로 시작). | 
| kinesisCredentialsProvider | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| dynamoDBCredentialsProvider | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| cloudWatchCredentialsProvider | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| failoverTimeMillis | LeaseManagementConfig | 리스 소유자가 실패했다고 간주하기 전에 전달해야 하는 시간(밀리초)입니다. | 
| workerIdentifier | ConfigsBuilder | 이 애플리케이션 프로세서 인스턴스화를 나타내는 고유 식별자입니다. 고유해야 합니다. | 
| shardSyncIntervalMillis | LeaseManagementConfig | 샤드 sync 호출 사이의 시간. | 
| maxRecords | PollingConfig | Kinesis가 반환하는 최대 레코드 수를 설정할 수 있습니다. | 
| idleTimeBetweenReadsInMillis | CoordinatorConfig | 이 옵션은 제거되었습니다. 유휴 시간 제거를 참조하십시오 | 
| callProcessRecordsEvenForEmptyRecordList | ProcessorConfig | 설정하면, Kinesis에서 제공된 레코드가 없는 경우에도 레코드 프로세서가 직접적으로 호출됩니다. | 
| parentShardPollIntervalMillis | CoordinatorConfig | 상위 샤드가 완료되었는지를 확인하기 위해 레코드 프로세서가 폴링을 수행해야 하는 간격입니다. | 
| cleanupLeasesUponShardCompletion | LeaseManagementConfig | 설정하면, 하위 리스에서 처리를 시작하자마자 리스가 제거됩니다. | 
| ignoreUnexpectedChildShards | LeaseManagementConfig | 설정하면, 진행 중인 샤드가 있는 하위 샤드가 무시됩니다. 이는 주로 DynamoDB Streams용입니다. | 
| kinesisClientConfig | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| dynamoDBClientConfig | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| cloudWatchClientConfig | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| taskBackoffTimeMillis | LifecycleConfig | 실패한 작업을 재시도하기 위한 대기 시간. | 
| metricsBufferTimeMillis | MetricsConfig | CloudWatch 측정치 게시를 제어합니다. | 
| metricsMaxQueueSize | MetricsConfig | CloudWatch 측정치 게시를 제어합니다. | 
| metricsLevel | MetricsConfig | CloudWatch 측정치 게시를 제어합니다. | 
| metricsEnabledDimensions | MetricsConfig | CloudWatch 측정치 게시를 제어합니다. | 
| validateSequenceNumberBeforeCheckpointing | CheckpointConfig | 이 옵션은 제거되었습니다. 체크포인트 시퀀스 번호 검증을 참조하십시오. | 
| regionName | ConfigsBuilder | 이 옵션은 제거되었습니다. 클라이언트 구성 제거를 참조하십시오. | 
| maxLeasesForWorker | LeaseManagementConfig | 애플리케이션의 한 인스턴스가 허용해야 하는 최대 리스 수입니다. | 
| maxLeasesToStealAtOneTime | LeaseManagementConfig | 애플리케이션이 한 번에 스틸을 시도해야 하는 최대 리스 수입니다. | 
| initialLeaseTableReadCapacity | LeaseManagementConfig | Kinesis Client Library에서 DynamoDB 리스 테이블을 새로 생성해야 하는 경우 사용되는 DynamoDB 읽기 IOP입니다. | 
| initialLeaseTableWriteCapacity | LeaseManagementConfig | Kinesis Client Library에서 DynamoDB 리스 테이블을 새로 생성해야 하는 경우 사용되는 DynamoDB 읽기 IOP입니다. | 
| initialPositionInStreamExtended | LeaseManagementConfig | 애플리케이션이 읽기를 시작해야 하는 스트림 내 초기 위치입니다. 최초 리스 생성 시에만 사용됩니다. | 
| skipShardSyncAtWorkerInitializationIfLeasesExist | CoordinatorConfig | 리스 테이블에 기존 리스가 있는 경우 샤드 데이터 동기화를 비활성화합니다. TODO: KinesisEco-438 | 
| shardPrioritization | CoordinatorConfig | 사용할 샤드 우선 순위. | 
| shutdownGraceMillis | 해당 사항 없음 | 이 옵션은 제거되었습니다. MultiLang 제거를 참조하십시오. | 
| timeoutInSeconds | 해당 사항 없음 | 이 옵션은 제거되었습니다. MultiLang 제거를 참조하십시오. | 
| retryGetRecordsInSeconds | PollingConfig | 실패에 대한 GetRecords 시도 사이의 지연을 구성합니다. | 
| maxGetRecordsThreadPool | PollingConfig | GetRecords에 사용되는 스레드 풀 크기. | 
| maxLeaseRenewalThreads | LeaseManagementConfig | 리스 갱신 스레드 풀의 크기를 제어합니다. 애플리케이션에서 사용할 수 있는 리스가 많을수록 이 풀의 크기가 커야 합니다. | 
| recordsFetcherFactory | PollingConfig | 스트림에서 검색하는 페처를 생성하는 데 사용되는 팩토리를 교체할 수 있습니다. | 
| logWarningForTaskAfterMillis | LifecycleConfig | 작업이 완료되지 않은 경우 얼마나 대기한 후 경고가 기록될지를 지정합니다. | 
| listShardsBackoffTimeInMillis | RetrievalConfig | 실패 발생 시 ListShards 호출 간에 대기하는 시간(밀리초)입니다. | 
| maxListShardsRetryAttempts | RetrievalConfig | 포기하기 전에 ListShards가 재시도하는 최대 횟수입니다. | 

## 유휴 시간 제거
<a name="idle-time-removal"></a>

KCL 1.x 버전에서 `idleTimeBetweenReadsInMillis`는 다음 두 가지 수량에 해당합니다.
+ 작업 디스패칭 확인 간의 시간. 작업 간의 이 시간은 이제 `CoordinatorConfig#shardConsumerDispatchPollIntervalMillis`를 설정하여 구성할 수 있습니다.
+ Kinesis Data Streams에서 반환하는 레코드가 없는 경우 절전 모드로 들어가는 시간. 버전 2.0에서는 향상된 팬아웃 레코드가 해당 검색자로부터 푸시됩니다. 샤드 소비자에 대한 작업은 푸시된 요청이 도착한 경우에만 발생합니다.

## 클라이언트 구성 제거
<a name="client-configuration-removals"></a>

버전 2.0에서 KCL은 더 이상 클라이언트를 생성하지 않습니다. 이제 사용자가 유효한 클라이언트를 제공해야 합니다. 따라서 클라이언트 생성을 제어하던 모든 구성 파라미터는 삭제되었습니다. 이러한 파라미터가 필요한 경우 `ConfigsBuilder`에 클라이언트를 제공하기 전에 클라이언트에서 설정할 수 있습니다.


****  

| 제거된 필드 | 동일 구성 | 
| --- | --- | 
| kinesisEndpoint | SDK KinesisAsyncClient를 원하는 엔드포인트 KinesisAsyncClient.builder().endpointOverride(URI.create("https://<kinesis endpoint>")).build()로 구성합니다. | 
| dynamoDBEndpoint | SDK DynamoDbAsyncClient를 원하는 엔드포인트 DynamoDbAsyncClient.builder().endpointOverride(URI.create("https://<dynamodb endpoint>")).build()로 구성합니다. | 
| kinesisClientConfig | SDK KinesisAsyncClient를 필요한 구성 KinesisAsyncClient.builder().overrideConfiguration(<your configuration>).build()로 구성합니다. | 
| dynamoDBClientConfig | SDK DynamoDbAsyncClient를 필요한 구성 DynamoDbAsyncClient.builder().overrideConfiguration(<your configuration>).build()로 구성합니다. | 
| cloudWatchClientConfig | SDK CloudWatchAsyncClient를 필요한 구성 CloudWatchAsyncClient.builder().overrideConfiguration(<your configuration>).build()로 구성합니다. | 
| regionName | SDK를 원하는 리전으로 구성합니다. 모든 SDK 클라이언트에 대해 동일합니다. 예를 들어 KinesisAsyncClient.builder().region(Region.US\$1WEST\$12).build()입니다. | 