Amazon Kinesis Data Streams에서 ReadProvisionedThroughputExceeded 오류가 발생했습니다. 이런 문제가 발생하는 이유는 무엇이며, 이 문제를 해결하려면 어떻게 해야 합니까?
간략한 설명
ReadProvisionedThroughputExceeded 오류는 일정 시간 동안 Kinesis Data Streams가 GetRecords 호출을 제한할 때 발생합니다.
Amazon Kinesis 데이터 스트림은 다음과 같은 한도를 초과하면 제한될 수 있습니다.
- 각 샤드는 초당 최대 5개의 읽기 트랜잭션(또는 각 샤드에 초당 5건의 GetRecords 호출)까지 지원할 수 있습니다.
- 각 샤드는 최고 2MiB/초의 읽기 속도를 지원합니다.
- GetRecords는 한 개의 샤드에서 호출당 최고 10MiB의 데이터, 호출당 최고 10,000개의 레코드를 검색할 수 있습니다. GetRecords에 대한 호출이 10MiB의 데이터를 반환하는 경우, 다음 5초 동안 이후 호출이 있으면 오류가 발생합니다.
ReadProvisionedThroughputExceeded 오류가 발생하는 경우 다음과 같은 접근 방식을 고려하십시오.
- 문제의 근본 원인을 파악합니다.
- 마이크로버스트가 발생했는지 확인합니다.
- Kinesis Data Streams 모범 사례를 따릅니다.
해결 방법
문제의 근본 원인 파악
Data Streams에서 ReadProvisionedThroughputExceeded 오류의 근본 원인을 파악하려면, Amazon CloudWatch를 사용하여 Amazon Kinesis Data Streams 서비스를 모니터링합니다. CloudWatch에서 다음 지표에 주의하십시오.
- GetRecords.Bytes: 정해진 기간에 걸쳐 측정한 Kinesis 데이터 스트림에서 검색된 바이트 수입니다.
- GetRecords.Records: 정해진 기간에 걸쳐 측정한 Kinesis 데이터 스트림에서 검색된 레코드 수입니다.
- ReadProvisionedThroughputExceeded: Kinesis 데이터 스트림을 제한하는 GetRecords 호출입니다.
CloudWatch 대시보드에서 시간을 1분으로 설정하고, 통계를 합계로 표시하도록 설정합니다. 그런 다음 합계를 60초로 나누어 평균 값을 도출합니다.
예를 들어 GetRecords.Records 지표 값을 사용하는 경우, 합계를 60초로 나누면 초당 전송된 레코드의 평균 수를 계산할 수 있습니다. 그런 다음, 이렇게 계산된 평균 값이 Kinesis 데이터 스트림에 설정된 초당 전송되는 레코드 한도보다 적은지 확인합니다. 샤드 한도에 대한 자세한 내용은 Kinesis Data Streams 할당량 및 한도를 참조하십시오.
참고: 강화된 모니터링 기능을 활용하면 샤드 전체에 걸쳐 로드가 골고루 분산되게 할 수 있습니다.
또한 GetRecords.Records 지표와 SampleCount 형태로 확인된 통계를 함께 사용하고 기간을 1분으로 설정하는 방법도 있습니다. SampleCount 값을 60초로 나누면 각 샤드에서 실행된 GetRecords 호출의 초당 평균 수를 계산할 수 있습니다. 평균 값이 초당 GetRecords 호출 5건 안팎이고 ReadProvisionedThroughputExceeded 오류가 발생했다면, 소비자가 샤드 한도를 초과했는지 확인합니다. 소비자가 샤드 한도를 초과한 것이 아니라면, ReadProvisionedThroughputExceeded 오류는 소비자가 초당 5회 이상의 GetRecords 호출을 실행하고 있기 때문에 발생한 것일 수 있습니다.
마지막으로, 샤드마다 ReadProvisionedThroughputExceeded 값이 서로 다른지 확인합니다. 샤드의 분포가 고르지 않거나, 한 샤드가 다른 샤드에 비해 많거나 적은 양의 데이터를 수신하는 경우 분포 불균형 문제가 있을 가능성이 있습니다. 이러한 샤드 분포 불균형 문제를 해결하고 핫 샤드를 방지하려면 putRecords API 호출에서 UUID를 파티션 키로 사용하십시오.
마이크로버스트 발생 여부 확인
드문 일이지만, 지표 값이 샤드 한도 미만이라서 Kinesis 데이터 스트림이 읽기 작업 중에 제한될 수도 있습니다.
예를 들어 GetRecords.Bytes Sum:1min이 1분간 10MiB의 데이터 읽기를 나타내는 상황이라고 가정합니다. GetRecords.Bytes 호출은 1초간 아무 제한 없이 2MiB의 데이터를 읽습니다. 그런 다음 2초에 접어들면 GetRecords.Bytes 호출은 8MiB의 데이터를 읽습니다. 3초가 되면 읽기 작업이나 제한이 없을 수 있습니다. 그 1분에 대한 샤드 한도에 도달하지 않았더라도(2MiB * 60 = 데이터 120MiB), ReadProvisionedThroughputExceeded 오류가 발생할 수 있습니다. 지표 값이 갑자기 치솟은 부분이 있다면 ReadProvisionedThroughputExceeded 예외를 발생시키는 마이크로버스트를 찾아봅니다.
Data Streams 모범 사례 따르기
ReadProvisionedThroughputExceeded 예외를 완화하려면 다음과 같은 모범 사례를 따르십시오.
- 스트림을 리샤딩하여 스트림 내 샤드 수를 늘립니다.
- GetRecords 요청의 크기를 줄입니다. 이렇게 하려면 한도 파라미터를 구성하거나 GetRecords 요청의 빈도를 줄이면 됩니다.
참고: 소비자가 Amazon Kinesis Data Firehose인 경우, Kinesis 데이터 스트림은 실행 중인 GetRecords 호출 빈도에 맞춰 조정됩니다. 소비자가 이벤트 소스 매핑을 포함한 AWS Lambda 함수인 경우, 스트림은 1초에 한 번씩만 폴링됩니다. 폴링 빈도는 수정할 수 없습니다. Amazon Kinesis Client Library(KCL) 애플리케이션이 소비자인 경우 폴링 빈도를 조정합니다. 폴링 빈도를 조정하려면 KinesisClientLibConfiguration 파일에서 DEFAULT_IDLETIME_BETWEEN_READS_MILLIS 파라미터 값을 수정합니다. 코드에서 이 값을 동적으로 설정할 수 있습니다. KCL에서 이 값을 수정하는 방법에 대한 자세한 내용은 GitHub 웹사이트의 Amazon Web Services - Labs를 참조하세요.
- Data Streams 내의 모든 샤드에 걸쳐 읽기 및 쓰기 작업을 최대한 골고루 분포시킵니다.
- 향상된 팬아웃이 있는 소비자를 사용하십시오. 향상된 팬아웃에 대한 자세한 내용은 전용 처리량을 사용한 사용자 지정 소비자 개발(향상된 팬아웃)을 참조하십시오.
참고: Kinesis 데이터 스트림이 사용하는 소비자가 다섯 이상인 경우, 향상된 팬아웃이 있는 소비자를 사용하는 것이 좋습니다.
- ReadProvisionedThroughputExceeded 예외가 발생하는 경우 소비자 로직에서 오류 재시도 및 지수 백오프 메커니즘을 사용하십시오. AWS SDK를 사용하는 소비자 애플리케이션의 경우, 기본적으로 요청을 다시 시도합니다.