Redis용 Memorystore는 처리량, CPU 사용률, 메모리 사용량을 모니터링하기 위한 실시간 서버 측 측정항목을 제공하지만, 이 데이터만으로는 복잡한 분산 시스템 내에서 클라이언트 애플리케이션의 지연 시간이 긴 이유를 설명하지 못할 수 있습니다.
클라이언트 측 측정항목은 전체 요청-응답 주기에 대한 투명성을 제공하여 이 문제를 해결합니다. 애플리케이션이 명령어를 시작한 시점부터 애플리케이션이 응답을 처리할 때까지 명령어를 측정합니다. 이러한 데이터 포인트를 캡처하면 지연 시간이 애플리케이션 로직, 네트워크 경로 또는 Redis 서버에서 발생하는지 정확하게 확인할 수 있습니다.
시작하기 전에
클라이언트 애플리케이션이 서비스 계정을 사용하고 다음 Identity and Access Management (IAM) 역할이 할당되어 있는지 확인합니다.
roles/cloudtrace.agent(Cloud Trace 에이전트)roles/monitoring.metricWriter(Monitoring 측정항목 작성자)
역할 부여에 대한 자세한 내용은 콘솔을 사용하여 IAM 역할 부여하기 Google Cloud 빠른 시작을 참조하세요.
Cloud Monitoring API 사용 설정
클라이언트 측 측정항목을 Monitoring으로 내보내려면 애플리케이션에서 Monitoring API를 사용 설정해야 합니다. Monitoring에서 이러한 측정항목을 내보내고 시각화하면 병목 현상의 근본 원인을 파악하여 지연 시간이 발생하는지 확인할 수 있습니다.
Monitoring API를 사용 설정하려면 다음을 수행합니다.
Google Cloud 콘솔에서 API 및 서비스 페이지로 이동합니다.
Memorystore for Redis 인스턴스를 만든 프로젝트를 선택합니다.
API 및 서비스 사용 설정 을 클릭합니다.
monitoring을 검색합니다.검색 결과에서 Cloud Monitoring API 를 클릭합니다.
API 사용 설정됨 이 표시되면 API가 이미 사용 설정된 것입니다. 그렇지 않으면 사용 설정 을 클릭합니다.
Cloud Trace API 사용 설정
Trace에서 분산 trace를 보려면 Trace API를 사용 설정해야 합니다. 그런 다음 Trace 탐색기를 사용하여 이러한 trace를 보고, 병목 현상을 진단하고, 애플리케이션에서 지연 시간의 소스를 격리할 수 있습니다.
Trace API를 사용 설정하려면 다음을 수행합니다.
Google Cloud 콘솔에서 API 및 서비스 페이지로 이동합니다.
Memorystore for Redis 인스턴스를 만든 프로젝트를 선택합니다.
API 및 서비스 사용 설정 을 클릭합니다.
trace를 검색합니다.검색 결과에서 Cloud Trace API 를 클릭합니다.
API 사용 설정됨 이 표시되면 API가 이미 사용 설정된 것입니다. 그렇지 않으면 사용 설정 을 클릭합니다.
클라이언트 측 측정항목 사용 설정
클라이언트 측 측정항목을 사용 설정하려면 OpenTelemetry SDK, Cloud Monitoring 내보내기 도구, Cloud Trace 내보내기 도구를 애플리케이션의 코드에 추가합니다. 애플리케이션의 Redis 클라이언트 라이브러리 내에서 직접 실행되는 OpenTelemetry 계측은 측정항목을 캡처합니다. 이렇게 하면 애플리케이션에서 지연 시간 데이터 포인트를 기록하고 시각화를 위해 Monitoring 및 Trace로 내보낼 수 있습니다.
클라이언트 측 측정항목을 사용 설정하려면 Go, Java, Node.js, 또는 Python을 사용하면 됩니다. 각 언어의 측정항목을 사용 설정하는 방법에 대한 정보는 다음 탭에 표시됩니다.
Go
필요한 OpenTelemetry 및 Google Cloud 내보내기 도구 종속 항목을 설치하려면 터미널에서 다음 명령어를 실행합니다.
go get github.com/gomodule/redigo/redis@latest go get go.opentelemetry.io/otel go get go.opentelemetry.io/otel/sdk/trace go get go.opentelemetry.io/otel/sdk/metric go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric
클라이언트 측 측정항목을 사용 설정하려면
main.go파일을 만들고 다음 코드를 추가합니다.내보내기 도구가 게시된 측정항목을 일괄 처리하고 Monitoring으로 전송할 수 있는 충분한 시간을 제공하려면 애플리케이션을 1분 이상 실행합니다.
Java
필요한 OpenTelemetry 및 Google Cloud 내보내기 도구 종속 항목을 설치하려면 애플리케이션의
pom.xml파일에 다음 코드를 추가합니다.클라이언트 측 측정항목을 사용 설정하려면
RedisTelemetryApp.java파일을 만들고 다음 코드를 추가합니다.내보내기 도구가 게시된 측정항목을 일괄 처리하고 Monitoring으로 전송할 수 있는 충분한 시간을 제공하려면 애플리케이션을 1분 이상 실행합니다.
Node.js
필요한 OpenTelemetry 및 Google Cloud 내보내기 도구 종속 항목을 설치하려면 터미널에서 다음 명령어를 실행합니다.
npm install redis@^4.6.0 @opentelemetry/api@^1.9.0 @opentelemetry/sdk-trace-node@^2.1.0 @opentelemetry/sdk-trace-base@^2.1.0 @opentelemetry/sdk-metrics@^2.1.0 @opentelemetry/instrumentation@^0.205.0 @opentelemetry/instrumentation-redis@^0.67.0 @google-cloud/opentelemetry-cloud-trace-exporter@^3.0.0 @google-cloud/opentelemetry-cloud-monitoring-exporter@^0.21.0 @opentelemetry/resources@^2.1.0
클라이언트 측 측정항목을 사용 설정하려면
server.js파일을 만들고 다음 코드를 추가합니다.내보내기 도구가 게시된 측정항목을 일괄 처리하고 Monitoring으로 전송할 수 있는 충분한 시간을 제공하려면 애플리케이션을 1분 이상 실행합니다.
Python
필요한 OpenTelemetry 및 Google Cloud 내보내기 도구 종속 항목을 설치하려면 터미널에서 다음 명령어를 실행합니다.
pip install redis==7.0.1 opentelemetry-api==1.39.1 opentelemetry-sdk==1.39.1 opentelemetry-instrumentation-redis==0.60b1 opentelemetry-exporter-gcp-trace==1.11.0 opentelemetry-exporter-gcp-monitoring==1.11.0a0
클라이언트 측 측정항목을 사용 설정하려면
main.py파일을 만들고 애플리케이션에 다음 코드를 추가합니다.내보내기 도구가 게시된 측정항목을 일괄 처리하고 Monitoring으로 전송할 수 있는 충분한 시간을 제공하려면 애플리케이션을 1분 이상 실행합니다.
Monitoring에서 측정항목 보기
클라이언트 측 측정항목을 사용 설정하고 내보내기 도구가 측정항목을 일괄 처리하고 Monitoring으로 전송할 수 있는 충분한 시간을 제공하기 위해 애플리케이션을 1분 이상 실행한 후 Monitoring을 사용하여 측정항목을 시각화하고, 작업 또는 인스턴스별로 그룹화하고, 집계기를 적용하여 애플리케이션의 성능을 모니터링합니다.
Monitoring에서 측정항목을 보려면 다음 안내를 따르세요.
콘솔에서 Google Cloud 측정항목 탐색기 페이지로 이동합니다.
Google Cloud 프로젝트를 선택합니다.
측정항목 선택 을 클릭합니다.
workload.googleapis.com/redis를 검색합니다.클라이언트 측 측정항목을 선택합니다. 필요에 따라 데이터를
operation및instance로 그룹화하고 집계기를 선택합니다. 더 많은 옵션을 알아보려면 측정항목 탐색기 사용 시 측정항목 선택을 참조하세요.
Trace에서 분산 trace 보기
애플리케이션이 데이터 내보내기를 시작한 후 Trace를 사용하여 Redis 명령어의 전체 요청-응답 주기를 시각화할 수 있습니다. Trace에서 분산 trace를 보면 병목 현상을 진단하여 애플리케이션에서 지연 시간의 정확한 소스를 빠르게 격리할 수 있습니다.
Trace에서 분산 trace를 보려면 다음 안내를 따르세요.
Google Cloud 콘솔에서 Trace 탐색기 페이지로 이동합니다.
분산형 차트에서 점으로 표시된 최근 trace를 선택합니다.
다음 병목 현상을 식별하여 지연 시간의 소스를 격리하려면 폭포식 뷰를 검사합니다.
총 요청 기간: 최상위 (상위) 막대는 작업이 완료될 때까지 기다려야 하는 총 시간을 보여줍니다.
네트워크 및 서버 지연 시간 (RTT): 하위 막대 (예:
GET또는SET라벨이 지정된 막대)는 명령어가 네트워크를 통해 이동하고 Memorystore for Redis 서버에서 실행되는 데 걸린 시간을 보여줍니다.클라이언트 연결 차단: Redis 하위 스팬이 시작되기 전에 크고 빈 가로 간격이 있으면 애플리케이션 스레드가 연결 풀에서 사용 가능한 TCP 연결을 기다리는 동안 멈춰 있습니다.
애플리케이션 파싱 차단: Redis 하위 스팬이 종료된 후에 크고 빈 가로 간격이 있으면 애플리케이션이 반환된 페이로드를 파싱 하거나 처리하는 데 어려움을 겪습니다. 이 문제는 멀티 메가바이트 JSON 문자열에서 자주 발생합니다.
재시도: 동일한 상위 trace 내에서 동일한 명령어에 대해 여러 개의 짧은 하위 스팬이 순차적으로 발생하면 클라이언트에서 네트워크 패킷 손실이 발생할 수 있으며 지수 백오프 재시도 루프를 트리거해야 합니다.
문제 해결
이 섹션에서는 클라이언트 측 측정항목을 사용하여 식별할 수 있는 일반적인 성능 문제를 나열하고, 근본 원인을 설명하고, 문제를 해결하는 방법에 대한 안내를 제공합니다.
| 문제 | 원인 | 문제 해결 |
|---|---|---|
애플리케이션에 지연 시간이 갑자기 급증하지만 Memorystore for Redis는 완전히 정상인 것으로 보입니다.
|
병목 현상은 애플리케이션 내부에만 있습니다. 스레드가 Redis 명령어를 실행하려고 하지만 연결 풀이 완전히
소진되었습니다. 높은 redis_client_blocking_latency는 명령어가 네트워크로 전송되기 전에 사용 가능한 TCP 소켓을 기다리는 데 코드가 걸리는 시간을 나타냅니다. |
동시 트래픽을 더 많이 처리하려면 Redis 클라이언트 구성에서 연결 풀 크기 한도를 늘립니다 (예: MaxActive for Go, MaxTotal for Java, or max_connections for Node.js and Python). |
요청이 완료되지만 엔드포인트가 예상보다 훨씬 오래 걸립니다. 네트워크 또는 서버의 상태와 관련된 문제는 없습니다.
|
Memorystore for Redis는 명령어를 실행하고 네트워크는 페이로드를 빠르게 전송합니다 (RTT 낮음). 하지만 반환되는 페이로드가 큽니다 (예:
15MB JSON 문자열). 애플리케이션이 메모리를 할당하고 큰 문자열을 객체로 역직렬화하는 동안 과도한 리소스를 사용하므로 애플리케이션에 높은
redis_application_blocking_latency가 발생합니다. |
데이터 모델을 최적화합니다. 단일 키에 대규모 JSON blob을 저장하지 마세요.
Redis 해시 (HSET)를 사용하여 데이터를 세분화하고
HGET 또는 HMGET를 사용하여 필요한 특정 필드만 검색합니다.
|
사용자 대상 애플리케이션 지연 시간이 급증하지만 Redis 측정항목 은 낮은 서버 지연 시간과 일반적인 연결 풀 체크아웃을 보고합니다.
|
redis_client_rtt는 성공한 요청의 RTT만 캡처하므로 실패한 패킷의 제한 시간은 반영하지 않습니다. 애플리케이션에서 일시적인 패킷 삭제 또는 TCP
재설정이 발생하면 계측된 클라이언트의 재시도 로직이
redis_retry_count를 증가시키고 지수 백오프 루프를 트리거합니다.
이렇게 하면 시도 간에 대기 시간이 발생합니다 (예:
100ms, 200ms, 또는 400ms). 사용자는
총 지연 시간이 길다고 느끼지만 근본 원인은 클라이언트 측 대기 지연을 트리거하는 네트워크
패킷 손실입니다. |
VPC 흐름 로그에서 삭제된 패킷, 대역폭 제한 또는 리전 간 라우팅 이상을 확인합니다. 제한 시간이 공격적인 경우 클라이언트 연결 제한 시간 (socket_timeout 또는
connect_timeout)이 일시적인 네트워크 지터를 고려하여 예상 RTT보다 큰지 확인합니다. |
모든 것이 중지되고 원격 분석 파이프라인의 모든 계층에서 지연 시간이 길다고 보고합니다.
|
Redis는 단일 스레드입니다. O(N)
시간 복잡도 명령어를 실행하면 대규모 세트에서 KEYS *, SMEMBERS
또는 수백만 개의
필드가 있는 해시에서 HGETALL와 같은 Redis 엔진이 요청을 처리하기 위해 일시중지됩니다. 명령어가 실행되는 동안 다른 모든 애플리케이션 요청이 대기열에 추가되어 시스템 전체의 지연 시간이 급증합니다. 커스텀 redis_client_rtt가 서버의 지연 시간 (commands/usec_per_call)과 일치하므로 명령어를 실행하는 서버가 병목 현상입니다. |
Trace를 열고 느린 스팬의 Redis 명령어를 확인하여 차단을 일으키는 쿼리를 식별합니다. 코드에서 차단 명령어를 비차단 명령어로 바꿉니다. 서버 스레드를 잠그지 않고 대규모 데이터 세트를 점진적으로 반복하려면
|
트래픽이 적은 경우에도 애플리케이션에서 모든 Redis 명령어에 대해 일관되고 높은 기준 지연 시간을 보고합니다.
|
Redis 서버는 명령어를 즉시 실행하지만 애플리케이션과 인스턴스는 서로 다른 리전 (예: us-central1 및 us-east1)에 배포됩니다. 모든 네트워크 패킷은 이러한 지리적 데이터 센터 간의 실제 Google Cloud 인프라를 통해 이동해야 합니다. 따라서 모든 왕복에 대해 빛의 속도
리전 간 지연 시간 페널티가 발생합니다. |
지연 시간을 줄이려면 애플리케이션을 인스턴스와 동일한 리전 및 영역에 배포합니다. 애플리케이션 및 인스턴스의 리전을 보려면 Google Cloud 콘솔을 사용합니다. |
다음 단계
- 클라이언트 측 측정항목에 대해 자세히 알아보세요.
- Memorystore for Redis에 사용할 수 있는 클라이언트 측 측정항목에 대해 알아보세요.