적시에 응답을 받지 못하는 Azure Cache for Redis 클라이언트 작업으로 인해 대기 시간이 높거나 시간 초과 예외가 발생할 수 있습니다. 이 문서에서는 대기 시간 및 시간 초과가 발생할 수 있는 일반적인 문제를 해결하는 방법을 설명합니다.
작업은 다양한 단계에서 문제가 발생하거나 시간이 초과할 수 있습니다. 문제의 원인은 원인과 완화를 결정하는 데 도움이 됩니다. 이 문서는 클라이언트 쪽 및 서버 쪽 문제로 나뉩니다.
클라이언트 쪽 문제
- 높은 클라이언트 연결
- 클라이언트 호스트의 높은 CPU
- 큰 키 값
- Redis 클라이언트의 메모리 압박
- 클라이언트 호스트의 네트워크 대역폭 제한
- RedisSessionStateProvider 재시도 제한 시간
- Linux 기반 클라이언트 애플리케이션에 대한 TCP 설정
- 트래픽 버스트 및 스레드 풀 구성
서버 쪽 문제
클라이언트 쪽 문제 해결
다음 클라이언트 쪽 문제는 대기 시간 및 성능에 영향을 줄 수 있으며 시간 제한으로 이어질 수 있습니다.
높은 클라이언트 연결
캐시에 대한 최대값을 초과하는 클라이언트 연결에 대한 클라이언트 요청은 실패할 수 있습니다. 클라이언트 연결이 높으면 반복되는 다시 연결 시도를 처리할 때 서버 부하가 높아질 수도 있습니다.
높은 클라이언트 연결은 클라이언트 코드의 연결 누수를 나타낼 수 있습니다. 연결이 재사용되지 않거나 제대로 닫히지 않을 수 있습니다. 연결 사용을 위한 클라이언트 코드를 검토합니다.
높은 연결이 모두 합법적이고 필요한 클라이언트 연결인 경우 캐시를 연결 제한이 더 높은 크기로 업그레이드해야 할 수 있습니다. 연결된 클라이언트 메트릭의 최대 집계가 캐시 크기에 허용되는 최대 연결 수보다 가깝거나 높은지 확인합니다. 클라이언트 연결당 크기 조정에 대한 자세한 내용은 Azure Cache for Redis 성능을 참조하세요.
클라이언트 호스트의 높은 CPU
클라이언트 CPU 사용량이 많으면 시스템이 할당된 작업을 따라갈 수 없다는 것을 나타냅니다. 캐시가 응답을 신속하게 보내더라도 클라이언트는 응답을 충분히 빠르게 처리하지 못할 수 있습니다. 클라이언트 CPU를 80%미만으로 유지하는 것이 가장 좋습니다.
클라이언트의 높은 CPU 사용량을 완화하려면 다음을 수행합니다.
- CPU 급증의 원인을 조사합니다.
- 더 많은 CPU 용량을 사용하여 클라이언트를 더 큰 VM(가상 머신) 크기로 업그레이드합니다.
Azure Portal에서 사용 가능한 메트릭을 사용하거나 VM의 성능 카운터를 통해 클라이언트의 시스템 전체 CPU 사용량을 모니터링합니다. 메트릭 오류(형식: UnresponsiveClients) 를 확인하여 클라이언트 호스트가 Redis 서버의 응답을 제 시간에 처리할 수 있는지 확인합니다.
단일 프로세스의 CPU 사용량이 낮을 수 있지만 시스템 전체 CPU는 높을 수 있으므로 프로세스 CPU를 모니터링하지 않도록 주의해야 합니다. 제한 시간과 관련된 CPU 사용량의 급증을 주의 깊게 관찰하세요. CPU 사용량이 높으면 timeoutException
오류 메시지에서 in: XXX
값이 높아질 수도 있습니다. 예제는 트래픽 버스트 및 스레드 풀 구성 섹션을 참조하세요.
StackExchange.Redis 1.1.603 이상은 local-cpu
오류 메시지에 timeoutException
매트릭을 포함합니다. 버그가 정기적으로 수정되어 코드가 시간 제한에 더 강하도록 하기 때문에 최신 버전의 StackExchange.Redis NuGet 패키지를 사용해야 합니다. 자세한 내용은 StackExchange.Redis에서 예외 조사를 timeout
참조하세요.
큰 키 값
redis-cli --bigkeys
명령을 사용하여 캐시에서 큰 키를 확인할 수 있습니다. Redis-cli, Redis 명령줄 인터페이스에 대한 자세한 내용은 Redis CLI를 참조하세요.
문제를 완화하려면:
VM의 크기를 늘려 더 높은 대역폭 기능을 얻습니다. 클라이언트 또는 서버 VM의 대역폭이 증가하면 크기가 큰 응답의 데이터 전송 시간을 줄일 수 있습니다. 두 VM의 현재 네트워크 사용량을 현재 VM 크기의 제한과 비교합니다. 서버 또는 클라이언트에서만 더 많은 대역폭이 충분하지 않을 수 있습니다.
애플리케이션에서 사용하는 연결 개체 수를 늘립니다. 라운드 로빈 방식을 사용하여 여러 연결 개체에 대한 요청을 수행할 수 있습니다. 여러 키와 더 작은 값을 사용하는 방법에 대한 자세한 내용은 더 많은 키와 더 작은 값 고려를 참조하세요.
Redis 클라이언트의 메모리 압력
클라이언트의 메모리 압력으로 인해 캐시 응답 처리가 지연되는 성능 문제가 발생할 수 있습니다. 메모리 압력이 발생하면 시스템에서 데이터를 디스크에 페이지할 수 있습니다. 이 페이지 폴트 가 시스템이 크게 느려진 원인입니다.
클라이언트의 메모리 압력을 검색하려면 다음을 수행합니다.
- VM의 메모리 사용량을 모니터링하여 사용 가능한 메모리를 초과하지 않는지 확인합니다.
- 클라이언트의
Page Faults/Sec
성능 카운터를 모니터링합니다. 정상적인 작업 중에도 대부분의 시스템에는 어느 정도의 페이지 폴트가 있습니다. 요청 시간 제한에 해당하는 페이지 폴트의 급증은 메모리 부족을 나타낼 수 있습니다.
클라이언트의 높은 메모리 압력을 완화하려면 다음을 수행합니다.
- 클라이언트의 메모리 사용량을 줄이기 위해 메모리 사용 패턴을 조사합니다.
- 메모리가 더 많은 더 큰 크기로 클라이언트 VM을 업그레이드합니다.
클라이언트 호스트의 네트워크 대역폭 제한
해당 아키텍처에 따라 클라이언트 머신은 네트워크 대역폭 가용성에 제한이 있을 수 있습니다. 클라이언트가 네트워크 용량을 오버로드하여 사용 가능한 대역폭을 초과하는 경우 서버가 전송하는 만큼 빠르게 클라이언트 쪽에서 데이터가 처리되지 않습니다. 이 경우 시간이 초과될 수 있습니다.
이 문제를 완화하려면 네트워크 대역폭 소비를 줄이거나 클라이언트 VM 크기를 네트워크 용량이 더 많은 크기로 늘리세요. 자세한 내용은 큰 요청 또는 응답 크기를 참조하세요.
RedisSessionStateProvider retryTimeout
RedisSessionStateProvider
을 사용하는 경우에는 retryTimeout
을 올바르게 설정해야 합니다. retryTimeoutInMilliseconds
값이 operationTimeoutInMilliseconds
값보다 높아야 합니다. 그렇지 않으면 다시 시도하지 않습니다.
다음 예제에서는 retryTimeoutInMilliseconds
가 3000
로 설정됩니다.
<add
name="AFRedisCacheSessionStateProvider"
type="Microsoft.Web.Redis.RedisSessionStateProvider"
host="enbwcache.redis.cache.windows.net"
port="6380"
accessKey="..."
ssl="true"
databaseId="0"
applicationName="AFRedisCacheSessionState"
connectionTimeoutInMilliseconds = "5000"
operationTimeoutInMilliseconds = "1000"
retryTimeoutInMilliseconds="3000"
>
자세한 내용은 다음을 참조하세요.
Linux 기반 클라이언트 애플리케이션에 대한 TCP 설정
Linux에서 호스트되는 클라이언트 애플리케이션은 Linux의 낙관적 TCP 설정으로 인해 연결 문제가 발생할 수 있습니다. 자세한 내용은 Linux 호스팅 클라이언트 애플리케이션에 대한 TCP 설정을 참조하세요.
트래픽 버스트 및 스레드 풀 구성
트래픽 버스트와 잘못된 ThreadPool
설정이 결합되면 Redis 서버에서 이미 전송되었지만 클라이언트 측에서 아직 사용되지 않은 데이터를 처리하는 데 지연이 발생할 수 있습니다. 오류(유형: UnresponsiveClients) 메트릭을 확인하여 클라이언트 호스트가 트래픽의 급격한 급증을 따라잡을 수 있는지 확인합니다. 스레드 풀이 버스트 시나리오에서 빠르게 확장되도록 ThreadPool 설정을 구성할 수 있습니다.
StackExchange.Redis의 timeoutException
메시지를 사용하여 더욱 자세히 조사할 수 있습니다.
System.timeoutException: timeout performing EVAL, inst: 8, mgr: Inactive, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 64221, ar: 0,
IOCP: (Busy=6,Free=999,Min=2,Max=1000), WORKER: (Busy=7,Free=8184,Min=2,Max=8191)
앞의 예외는 몇 가지 문제를 보여 줍니다.
IOCP
섹션 및WORKER
섹션에서Busy
값이Min
값보다 크므로ThreadPool
설정을 조정해야 합니다.- 이 값
in: 64221
은 클라이언트의 커널 소켓 계층에서 64,221바이트를 받았지만 애플리케이션에서 읽지 않음을 나타냅니다. 이러한 차이는 일반적으로 애플리케이션(예: StackExchange.Redis)이 서버에서 보내는 만큼 빠르게 네트워크에서 데이터를 읽지 않음을 의미합니다.
StackExchange.Redis 1.1.603 이상은 local-cpu
오류 메시지에 timeoutException
매트릭을 포함합니다. 버그가 정기적으로 수정되어 코드가 시간 제한에 더 강하도록 하기 때문에 최신 버전의 StackExchange.Redis NuGet 패키지를 사용해야 합니다. 자세한 내용은 StackExchange.Redis의 시간 제한 예외 조사를 참조하세요.
서버 쪽 문제 해결
다음과 같은 서버 쪽 문제는 성능에 영향을 미치고 시간 제한으로 이어질 수 있습니다.
높은 메모리 사용량
서버의 메모리 압력으로 인해 요청 처리가 지연되는 다양한 성능 문제가 발생할 수 있습니다. 메모리 부하가 발생하면, 시스템이 데이터를 디스크로 이동시키므로 시스템 속도가 크게 느려집니다.
메모리 압력의 몇 가지 가능한 원인은 캐시가 최대 용량에 가까운 데이터로 채워지거나 Redis 서버에 높은 메모리 조각화가 있다는 것입니다.
예를 들어 데이터가 1KB 및 1MB 크기로 분산되는 경우처럼 부하 패턴이 높은 크기의 데이터를 저장하는 경우 조각화가 발생할 수 있습니다. 기존 메모리에서 1KB 키를 삭제하면 1MB 키가 공간에 맞지 않아 조각화가 발생합니다. 마찬가지로 1MB 키를 삭제하면 추가된 1.5MB 키가 기존 회수된 메모리에 맞지 않습니다. 사용되지 않은 이 여유 메모리는 조각화됩니다.
캐시가 조각화되어 높은 메모리 압력으로 실행되는 경우 시스템은 RSS(상주 집합 크기) 메모리를 복구하기 위해 장애 조치(failover)를 수행합니다. Redis는 이 문제를 식별하는 데 도움이 되는 INFO 명령을 통해 두 가지 used_memory
통계를 노출합니다.used_memory_rss
Azure Portal에서 이러한 메트릭을 볼 수도 있습니다.
used_memory_rss
값이 used_memory
메트릭의 1.5배보다 높은 경우 메모리가 조각납니다. 다음과 같은 경우에 조각화로 인해 이슈가 발생할 수 있습니다.
- 메모리 사용량이 캐시의 최대 메모리 제한에 가깝습니다.
used_memory_rss
메트릭이 최대 메모리 제한보다 높으므로 잠재적으로 메모리에 페이지 오류가 발생할 수 있습니다.
메모리 사용량을 정상 상태로 유지하는 데 도움이 되는 몇 가지 작업을 수행할 수 있습니다.
- 메모리 정책을 구성 하고 키에 만료 시간을 설정합니다. 조각화가 있는 경우 이 정책만으로는 충분하지 않을 수 있습니다.
- 메모리 조각화를 보상하기에 충분히 큰 maxmemory-reserved 및 maxfragmentationmemory-reserved 값을 구성합니다.
- 사용 중인 메모리와 같은 메트릭에 대한 경고를 생성하여 잠재적인 영향에 대해 조기에 알림을 받을 수 있습니다.
- 더 많은 메모리 용량을 사용하여 더 큰 캐시 크기로 조정합니다. 자세한 내용은 Azure Cache for Redis 계획 FAQ를 참조하세요.
메모리 관리에 대한 자세한 권장 사항은 메모리 관리에 대한 모범 사례를 참조하세요.
높은 서버 부하
서버 부하가 높으면 Redis 서버가 바빠서 요청을 따라갈 수 없고, 결과적으로 시간 초과 또는 응답 속도가 느려집니다. 높은 서버 부하를 완화하려면 먼저 높은 메모리 압력으로 인한 장기 실행 명령 과 같은 원인을 조사합니다.
Azure Portal에서 서버 로드 와 같은 메트릭을 모니터링 할 수 있습니다. 서버 부하 메트릭을 확인하려면 캐시 페이지의 왼쪽 탐색 메뉴에서 모니터링 아래에서 인사이트를 선택하고 서버 부하 그래프를 봅니다. 또는 왼쪽 탐색 메뉴의 모니터링에서 메트릭을 선택한 다음 메트릭 아래에서 서버 로드를 선택합니다.
시간 제한과 관련된 서버 부하 사용량 급증을 주시하십시오. 서버 부하 메트릭에 대한 경고를 만들어 잠재적인 영향에 대해 초기에 알려 줍니다.
서버 부하 급증
C0 및 C1 캐시에서 내부 Defender 스캔이 VM에서 실행되는 동안 요청 증가 없이 서버 부하에 짧은 급증이 발생할 수 있습니다. 이러한 계층에서는 내부 Defender 검사가 수행되는 동안 요청 처리 시간이 길어집니다.
C0 및 C1 계층의 캐시에는 멀티태스크에 대한 단일 코어만 있으므로 내부 Defender 검색 및 Redis 요청을 제공하는 작업을 구분합니다. 내부 Defender 스캔에서 발생하는 추가 대기 시간이 C1 캐시의 프로덕션 워크로드에 부정적인 영향을 미치는 경우, 여러 CPU 코어를 제공하는 C2와 같은 더 높은 계층의 제품으로 확장하여 성능을 향상시킬 수 있습니다. 자세한 내용은 적절한 계층 선택을 참조하세요.
클라이언트 연결 수의 급격한 변화에 대한 자세한 내용은 클라이언트 연결 급증 방지를 참조하세요.
확장
더 많은 분할된 데이터베이스로 확장 하여 여러 Redis 프로세스에 부하를 분산하거나 더 많은 CPU 코어를 사용하여 더 큰 캐시 크기로 확장할 수 있습니다. 크기 조정 작업은 노드를 중심으로 데이터를 이동하고 클러스터 토폴로지 변경을 포함할 수 있으므로 CPU 및 메모리를 많이 사용합니다. 자세한 내용은 Azure Cache for Redis 계획 FAQ 및크기 조정을 참조하세요.
오랫동안 실행되는 명령
일부 Redis 명령 실행은 다른 명령에 비해 비용이 많이 듭니다. Redis 명령 설명서에서는 각 명령의 시간 복잡성을 보여 줍니다. Redis 명령 처리는 단일 스레드입니다. 실행하는 데 시간이 오래 걸리는 모든 명령은 이를 따르는 다른 명령을 차단할 수 있습니다.
Redis 서버에 발급한 명령을 검토하여 성능에 미치는 영향을 파악합니다. 예를 들어 KEYS 명령은 O(N)(Big O Notation) 작업이라는 사실을 모르고 자주 사용됩니다. CPU 급증을 줄이기 위해 KEYS
을 피하고 SCAN을 사용할 수 있습니다.
콘솔에서 다음 Redis 명령을 실행하여 장기 실행 및 비용이 많이 드는 명령을 조사할 수 있습니다.
-
이
CLIENT LIST
명령은 클라이언트 연결 서버에 대한 정보와 통계를 대부분 사람이 읽을 수 있는 형식으로 반환합니다. -
이
INFO
명령은 컴퓨터가 구문 분석하기 쉽고 사용자가 쉽게 읽을 수 있는 형식으로 서버에 대한 정보와 통계를 반환합니다. 이 섹션은CPU
CPU 사용량을 조사하는 데 유용할 수 있습니다. 최대값인100
의server_load
는 Redis 서버가 항상 바빴으며 요청을 처리할 때 유휴 상태가 아니었음을 나타냅니다.명령의
INFO
출력 예는 다음과 같습니다.# CPU used_cpu_sys:530.70 used_cpu_user:445.09 used_cpu_avg_ms_per_sec:0 server_load:0.01 event_wait:1 event_no_wait:1 event_wait_count:10 event_no_wait_count:1
-
MONITOR
는 Redis 서버에서 처리된 모든 명령을 다시 스트리밍하는 디버깅 명령입니다.MONITOR
은 데이터베이스에 무슨 일이 일어나고 있는지 이해하는 데 도움이 될 수 있습니다. 이 명령은 까다로워서 성능에 부정적인 영향을 미치고 저하시킬 수 있습니다. -
Redis 느린 로그는 지정된 실행 시간을 초과한 쿼리를 기록하는 시스템입니다. 실행 시간에는 클라이언트와 대화하거나 회신을 보내는 것과 같은 I/O 작업이 포함되지 않지만 실제로 명령을 실행하는 데 필요한 시간만 포함됩니다.
이
SLOWLOG
명령은 Redis 느린 쿼리 로그를 읽고 다시 설정하며 클라이언트 쪽에서 장기 실행 명령을 조사하는 데 사용할 수도 있습니다. SLOWLOG GET을 사용하여 Redis 서버에 대해 실행되는 비용이 많이 드는 명령을 모니터링하고 기록할 수 있습니다.
네트워크 대역폭 제한
캐시 크기가 다르면 네트워크 대역폭 용량도 다릅니다. 서버가 사용 가능한 대역폭을 초과하면 데이터가 클라이언트로 빨리 전송되지 않습니다. 서버가 클라이언트에게 데이터를 충분히 빠르게 푸시할 수 없어서 클라이언트 요청이 타임아웃될 수 있습니다.
Azure Portal에서 캐시 읽기 및 캐시 쓰기와 같은 메트릭을 모니터링하여 사용 중인 서버 쪽 대역폭의 양을 확인할 수 있습니다. 이러한 메트릭에 대한 경고를 만들어 잠재적 영향에 대해 조기에 통보합니다.
네트워크 대역폭 사용량이 최대 용량에 근접하는 상황을 완화하려면 다음을 수행합니다.
- 네트워크 수요를 줄이기 위해 클라이언트 호출 동작을 변경합니다.
- 더 많은 네트워크 대역폭 용량을 사용하여 더 큰 캐시 크기로 조정합니다. 자세한 내용은 Azure Cache for Redis 계획 자주 묻는 질문을 참조하세요.
서버 유지 관리
계획되거나 계획되지 않은 유지 관리로 인해 클라이언트 연결이 중단될 수 있습니다. 예외의 수와 유형은 코드 경로에서 요청의 위치와 캐시가 연결을 닫는 시점에 따라 달라집니다.
Azure Redis 캐시에서 장애 조치(failover)가 발생하는 경우 중단된 노드의 모든 클라이언트 연결이 여전히 실행 중인 노드로 전송됩니다. 연결 증가로 인해 서버 부하가 급증할 수 있습니다. 모든 클라이언트 연결이 다시 생성되고 두 노드 간에 재배포되도록 클라이언트 애플리케이션을 다시 부팅해 볼 수 있습니다.
요청을 보내지만 장애 조치(failover)가 발생할 때 응답을 받지 못하는 작업에서 예외가 timeout
발생할 수 있습니다. 닫힌 연결 개체에 대한 새 요청은 다시 연결이 성공적으로 발생할 때까지 연결 예외를 수신합니다.
예외가 발생한 동안 timeout
Azure Redis 캐시에 장애 조치(failover)가 있었는지 확인하려면 오류 메트릭을 확인합니다. 캐시의 Azure Portal 페이지에서 왼쪽 탐색 메뉴의 모니터링 아래에서 메트릭을 선택합니다. 그런 다음 오류 메트릭을 측정하고 ErrorType으로 분할된 새 차트를 만듭니다. 이 차트를 만들면 장애 조치(failover) 횟수가 표시됩니다. 장애 조치(failover)에 대한 자세한 내용은 Azure Cache for Redis에 대한 장애 조치(failover) 및 패치를 참조하세요.
서버 유지 관리로 인한 문제 완화에 대한 자세한 내용은 다음 문서를 참조하세요.