이 페이지에서는 Spanner 기한 초과 오류의 개요, 즉 어떤 오류인지, 발생 이유, 문제해결 및 해결 방법에 대해 간략히 설명합니다.
Spanner API에 액세스할 때 DEADLINE_EXCEEDED
오류로 인해 요청이 실패할 수 있습니다. 이 오류는 구성된 제한 시간 내에 응답이 수신되지 않았음을 나타냅니다.
기한 초과 오류는 여러 가지 이유로 발생할 수 있습니다(예: 과부하된 Spanner 인스턴스, 최적화되지 않은 스키마, 최적화되지 않은 쿼리 등). 이 페이지에서는 기한 초과 오류가 발생하는 일반적인 시나리오를 제시하고, 이러한 문제를 조사하고 해결하는 방법을 안내합니다.
Spanner의 기한 및 재시도 원칙
Spanner의 기한 및 재시도 원칙은 다른 많은 시스템과 다릅니다. Spanner에서는 응답이 유용한 최대 시간으로 제한 시간을 지정해야 합니다. 동일한 작업을 즉시 다시 시도하기 위해 인위적으로 짧은 기한을 설정하는 것은 작업이 완료되지 않는 상황을 초래하므로 권장하지 않습니다. 이러한 맥락에서 다음과 같은 전략과 작업은 권장되지 않습니다. 비생산적이며 Spanner의 내부 재시도 동작을 무산시키기 때문입니다.
기한을 너무 짧게 설정. 즉, 작업이 가끔 발생하는 꼬리 지연 시간에 대해 복원력이 우수하지 않으며 타임아웃되기 전에는 완료할 수 없습니다. 대신, 응답이 유용한 최대 시간으로 기한을 설정하세요.
기한을 너무 길게 설정하고 이 기한이 초과되기 전에 작업을 취소합니다. 이 경우 재시도가 발생하고 재시도할 때마다 노력을 낭비하게 됩니다. 이로 인해 인스턴스에 상당한 추가 부하가 발생할 수 있습니다.
기한 초과 오류란 무엇인가요?
Spanner 클라이언트 라이브러리 중 하나를 사용하면 기본 gRPC 레이어가 통신, 마샬링, 언마샬링, 기한 시행을 처리합니다. 기한을 사용하면 애플리케이션에서 기한 초과 오류와 함께 요청이 종료되기 전에 요청이 완료될 때까지 대기할 시간을 지정할 수 있습니다.
제한 시간 구성 가이드는 지원되는 각 Spanner 클라이언트 라이브러리에서 기한(또는 시간 제한)을 지정하는 방법을 보여줍니다. Spanner 클라이언트 라이브러리는 다음 구성 파일에서 정의된 기본 시간 제한 및 재시도 정책 설정을 사용합니다.
- spanner_grpc_service_config.json
- spanner_admin_instance_grpc_service_config.json
- spanner_admin_database_grpc_service_config.json
gRPC 기한에 대한 자세한 내용은 gRPC 및 기한을 참조하세요.
일반적인 기한 초과 오류를 조사하고 해결하는 방법
다음 문제 유형에 대해 DEADLINE_EXCEEDED
오류가 발생할 수 있습니다.
데이터 액세스 API 문제
데이터 액세스 API 문제를 방지하려면 특정 워크로드에 맞게 Spanner 인스턴스를 적절하게 구성해야 합니다. 다음 섹션에서는 여러 데이터 액세스 API 문제를 조사하고 해결하는 방법을 설명합니다.
Spanner 인스턴스 CPU 부하 확인
CPU 사용률이 권장 정상 기준을 초과하면 요청 지연 시간이 크게 증가할 수 있습니다. Google Cloud 콘솔에 제공되는 모니터링 콘솔에서 Spanner CPU 사용률을 확인할 수 있습니다. 인스턴스의 CPU 사용률에 따라 알림을 만들 수도 있습니다.
해결 방법
인스턴스의 CPU 사용률을 줄이는 단계는 CPU 사용률 줄이기를 참조하세요.
요청의 엔드 투 엔드 지연 시간 분석 확인
요청이 클라이언트에서 Spanner 서버로 왕복하는 경우 클라이언트 라이브러리에서 Google 프런트엔드(GFE), GFE에서 Spanner API 프런트엔드, 마지막으로 Spanner API 프런트엔드에서 Spanner 데이터베이스까지 이동할 여러 네트워크 홉이 있어야 합니다. 이 단계에서 네트워크 문제가 발생하면 기한 초과 오류가 표시될 수 있습니다.
각 단계에서 지연 시간을 캡처할 수 있습니다. 자세한 내용은 Spanner 요청의 지연 시간 포인트를 참조하세요. Spanner에서 지연 시간이 발생하는 위치를 찾으려면 Spanner에서 지연 시간이 발생하는 위치 식별을 참조하세요.
해결 방법
지연 시간 분석을 받으면 측정항목을 사용하여 지연 시간을 진단하고 발생하는 원인을 파악하며 솔루션을 찾을 수 있습니다.
데이터 API 문제
Spanner의 데이터 API에 대해 최적화되지 않은 특정 사용 패턴으로 인해 기한 초과 오류가 발생할 수 있습니다. 이 섹션에서는 최적화되지 않은 사용 패턴을 확인하는 방법에 대한 가이드라인을 제공합니다.
고비용 쿼리 확인
클라이언트 라이브러리에서 구성된 제한 시간 이내에 실행되지 않는 고비용 쿼리를 실행하려고 하면 기한 초과 오류가 발생할 수 있습니다. 비용이 많이 드는 쿼리의 예시에는 큰 테이블의 전체 스캔, 여러 대형 테이블에 대한 교차 조인 또는 키 열이 아닌 조건에 대한 조건부 쿼리 실행 등이 포함됩니다(전체 테이블 스캔 포함)
쿼리 통계 테이블 및 트랜잭션 통계 테이블을 사용하여 고비용 쿼리를 검사할 수 있습니다. 이러한 표에는 읽은 평균 행 수, 읽은 평균 바이트 수, 스캔된 평균 행 수 등 느리게 실행되는 쿼리 및 트랜잭션에 대한 정보가 표시됩니다. 또한 쿼리 실행 계획을 생성하여 쿼리가 실행되는 방법을 추가로 검사할 수 있습니다.
해결 방법
쿼리를 최적화하려면 SQL 쿼리 권장사항 가이드를 참조하세요. 또한 앞에서 언급한 통계 표와 실행 계획을 통해 얻은 데이터를 사용하여 쿼리를 최적화하고 데이터베이스에 대한 스키마를 변경할 수 있습니다. 이러한 권장사항은 문 실행 시간을 줄여 기한 초과 오류를 제거하는 데 도움이 될 수 있습니다.
잠금 경합 확인
Spanner 트랜잭션은 커밋하려면 잠금을 획득해야 합니다. 높은 처리량으로 실행되는 애플리케이션은 트랜잭션이 동일한 리소스에 대해 경합하게 하므로 잠금을 얻기 위한 대기 시간이 길어지고 전반적인 성능에 영향을 줄 수 있습니다. 이로 인해 읽기 또는 쓰기 요청의 기한이 초과될 수 있습니다.
잠금 통계 테이블을 사용하고 다음 블로그 게시물을 확인하여 지연 시간이 높은 읽기-쓰기 트랜잭션의 근본 원인을 찾을 수 있습니다. 잠금 통계 테이블에서 잠금 대기 시간이 가장 긴 row key를 찾을 수 있습니다.
이 잠금 충돌 문제 해결 가이드에서는 잠금 충돌과 관련된 열에 액세스하는 트랜잭션을 찾는 방법을 설명합니다. 트랜잭션 태그 문제 해결 가이드를 사용하여 잠금 충돌과 관련된 트랜잭션을 찾을 수도 있습니다.
해결 방법
잠금 경합을 줄이려면 다음 권장사항을 적용합니다. 또한 일반 읽기 사용 사례에 읽기 전용 트랜잭션을 사용하여 쓰기 관련 잠금 충돌을 방지하세요. 읽기-쓰기 트랜잭션 사용은 쓰기 또는 혼합 읽기-쓰기 워크플로에 예약되어야 합니다. 이 단계를 따르면 트랜잭션 실행 시간의 전체 지연 시간이 개선되고 기한 초과 오류가 줄어듭니다.
최적화되지 않은 스키마 확인
Spanner 데이터베이스에 가장 적합한 데이터베이스 스키마를 설계하기 전에 데이터베이스에서 실행되는 쿼리의 종류를 고려해야 합니다. 최적화되지 않은 스키마는 일부 쿼리를 실행할 때 성능 문제를 일으킬 수 있습니다. 이러한 성능 문제로 인해 구성된 기한 내에 요청이 완료되지 않을 수 있습니다.
해결 방법
최적의 스키마 설계는 데이터베이스에 대한 읽기 및 쓰기에 따라 달라집니다. 스키마 설계 권장사항 및 SQL 권장사항 가이드는 스키마 사양에 관계없이 따라야 합니다. 이 가이드를 따르면 가장 일반적인 스키마 설계 문제를 방지할 수 있습니다. 기타 성능 저하의 근본 원인으로는 기본 키 선택, 테이블 레이아웃(더 빠른 액세스를 위해 인터리브 처리된 테이블 사용 참조), 스키마 설계(스키마 성능 최적화 참조), Spanner 인스턴스 내에 구성된 노드의 성능(Spanner 성능 개요 참조)이 있습니다.
핫스팟 확인
Spanner는 분산 데이터베이스이므로 스키마 설계 시 핫스팟 방지를 고려해야 합니다. 예를 들어 단조롭게 증가하는 열을 만들면 Spanner에서 워크로드를 균등하게 분산하기 위해 사용할 수 있는 분할 수가 제한됩니다. 이러한 병목 현상으로 인해 시간 초과가 발생할 수 있습니다. 또한 Key Visualizer를 활용하여 핫스팟으로 인한 성능 문제를 해결할 수 있습니다.
해결 방법
이 문제를 해결하기 위한 첫 번째 단계로 이전 섹션 최적화되지 않은 스키마 확인에서 확인된 해결 방법을 참조하세요. 부하 집중을 일으킬 수 있는 색인을 방지하려면 데이터베이스 스키마를 다시 설계하고 인터리브 처리된 색인을 사용합니다. 이 단계를 수행해도 문제가 해결되지 않으면 핫스팟을 방지하기 위한 기본 키 선택 가이드를 참조하세요. 마지막으로 부하 기반 분할을 방해할 수 있는 대규모 읽기와 같은 최적화되지 않은 트래픽 패턴을 사용하지 마세요.
잘못 구성된 제한 시간 확인
클라이언트 라이브러리는 Spanner의 모든 요청에 대한 적절한 제한 시간 기본값을 제공합니다. 하지만 이러한 기본 구성을 특정 워크로드에 맞게 조정해야 할 수 있습니다. 쿼리 비용을 관찰하고 특정 사용 사례에 맞게 기한을 조정하는 것이 좋습니다.
해결 방법
제한 시간의 기본 설정은 대부분의 사용 사례에 적합합니다. 사용자는 이러한 구성을 재정의할 수 있지만(커스텀 제한 시간 및 재시도 가이드 참조) 기본 구성보다 더 공격적인 제한 시간을 사용하는 것은 권장되지 않습니다. 제한 시간을 변경하기로 결정한 경우 애플리케이션이 결과를 대기할 실제 시간으로 설정합니다. 제한 시간을 더 길게 구성하여 실험할 수 있지만 애플리케이션이 대기하려는 실제 시간보다 짧게 제한 시간을 설정하면 작업이 더 자주 재시도될 수 있습니다.
Admin API 문제
Admin API 요청은 Data API 요청에 비해 비용이 많이 드는 작업입니다.
CreateInstance
, CreateDatabase
또는 CreateBackups
와 같은 관리자 요청은 응답을 반환하기 전에 몇 초 정도 걸릴 수 있습니다. Spanner 클라이언트 라이브러리는 인스턴스 및 데이터베이스 관리자 요청 모두의 기한을 60분으로 설정합니다. 이는 클라이언트가 재시도하거나 실패하기 전에 서버에서 요청을 완료할 기회를 확보할 수 있게 합니다.
해결 방법
Google Spanner 클라이언트 라이브러리를 사용하여 관리자 API에 액세스하는 경우 클라이언트 라이브러리가 업데이트되어 최신 버전을 사용하는지 확인하세요. 생성한 클라이언트 라이브러리를 통해 Spanner API에 직접 액세스하는 경우 인스턴스 및 데이터베이스 관리자 요청의 기본 설정(60분)보다 더 엄격한 기한 설정이 없어야 합니다.
Google Cloud Console 문제
Google Cloud 콘솔 Spanner 스튜디오 페이지에서 실행된 쿼리는 5분을 초과할 수 없습니다. 실행하는 데 5분 넘게 걸리는 고비용 쿼리를 만들면 다음 오류 메시지가 표시됩니다.
백엔드가 실패한 쿼리를 취소하고 필요한 경우 트랜잭션이 롤백될 수 있습니다.
해결 방법
사용자는 SQL 쿼리 권장사항 가이드를 사용하여 쿼리를 다시 작성할 수 있습니다.
Dataflow 문제
Apache Beam에서 기본 제한 시간 구성은 읽기 작업의 경우 2시간, 커밋 작업의 경우 15초입니다. 이러한 구성은 독립형 클라이언트 라이브러리 기한 제한 시간에 비해 더 긴 작업을 허용합니다. 하지만 작업 항목이 너무 크면 제한 시간 및 기한 초과 오류가 발생할 수 있습니다. 필요한 경우 Apache Beam 커밋 제한 시간 구성을 맞춤설정할 수 있습니다.
해결 방법
ReadFromSpanner / Execute
query / Read from Spanner / Read from Partitions
단계에서 기한 초과 오류가 발생하면 쿼리 통계 테이블을 확인하여 어떤 쿼리가 많은 수의 행을 스캔했는지 알아봅니다. 그런 다음 이러한 쿼리 수정을 시도하여 실행 시간을 단축합니다.
Dataflow 기한 초과 오류의 또 다른 예시는 다음 예외 메시지에 나와 있습니다.
exception:
org.apache.beam.sdk.util.UserCodeException:
com.google.cloud.spanner.SpannerException: DEADLINE_EXCEEDED:
io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after
3599.999905380s.
[remote_addr=batch-spanner.googleapis.com/172.217.5.234:443] at
org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowsParDoFn$1.output(GroupAlsoByWindowsParDoFn.java:184)
이 경우에는 작업 항목이 너무 커서 시간 초과가 발생했습니다. 앞의 예시에서는 다음 두 가지 권장사항이 도움이 될 수 있습니다. 먼저 셔플 서비스가 아직 사용 설정되지 않은 경우 설정해 볼 수 있습니다. 두 번째로는 maxPartitions
및 partitionSizeBytes
와 같은 데이터베이스 읽기에서 구성을 조정할 수 있습니다. 자세한 내용은 PartitionOptions
를 참조하여 작업 항목 크기 줄이기를 시도해 보세요. 이를 수행하는 방법에 대한 예시는 Dataflow 템플릿을 참조하세요.
기한 초과 문제 해결 관련 추가 리소스
문제 해결 단계를 완료한 후에도 DEADLINE_EXCEEDED
오류가 표시되면 다음과 같은 시나리오가 발생하면 지원 케이스를 엽니다.
- Google 프런트엔드 지연 시간은 길지만 Spanner API 요청 지연 시간은 짧음
- Spanner API 요청 지연 시간은 길지만 쿼리 지연 시간은 짧음
다음 문제 해결 리소스를 참조할 수도 있습니다.