Azure Cache for Redis 대기 시간 및 제한 시간 문제 해결

적시에 응답을 받지 않는 클라이언트 작업으로 인해 대기 시간이 높거나 시간 제한 예외가 발생할 수 있습니다. 작업은 다양한 단계에서 시간 초과할 수 있습니다. 시간 제한이 발생하는 위치는 원인과 완화를 확인하는 데 도움이 됩니다.

이 섹션에서는 Azure Cache for Redis에 연결하는 경우 발생하는 대기 시간 및 시간 제한 문제를 해결하는 방법을 설명합니다.

참고 항목

이 가이드에 나오는 문제 해결 단계 중 몇 가지는 Redis 명령을 실행하고 다양한 성능 메트릭을 모니터링하는 것을 포함합니다. 자세한 내용 및 지침은 추가 정보 섹션의 문서를 참조합니다.

클라이언트 쪽 문제 해결

클라이언트 쪽 문제 해결은 다음과 같습니다.

트래픽 버스트 및 스레드 풀 구성

트래픽 버스트와 잘못된 ThreadPool 설정이 결합되면 Redis 서버에서 이미 전송되었지만 클라이언트 측에서 아직 사용되지 않은 데이터를 처리하는 데 지연이 발생할 수 있습니다. 메트릭 “오류”(형식: UnresponsiveClients)를 확인하여 클라이언트 호스트가 트래픽의 급격한 급증을 따라갈 수 있는지 확인합니다.

예제 ThreadPoolLogger를 사용하여 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 섹션에 Min 값보다 큰 Busy 값이 있습니다. 이러한 차이는 ThreadPool 설정을 조정해야 한다는 것을 나타냅니다.
  • 또한 in: 64221도 볼 수 있습니다: 이 값은 64,221바이트를 클라이언트의 커널 소켓 계층에서 받았지만 애플리케이션에서 아직 읽지 않았음을 나타냅니다. 이 차이는 일반적으로 애플리케이션(예: StackExchange.Redis)이 데이터를 서버에서 보내는 만큼 빠르게 네트워크로부터 읽지 못하고 있음을 의미합니다.

ThreadPool 설정을 구성하여 버스트 시나리오에서 스레드 풀이 신속하게 스케일 업할 수 있도록 합니다.

큰 키 값

여러 키와 더 작은 값을 사용하는 방법에 대한 자세한 내용은 더 많은 키와 더 작은 값 고려를 참조하세요.

redis-cli --bigkeys 명령을 사용하여 캐시에서 큰 키를 확인할 수 있습니다. 자세한 내용은 redis-cli, Redis 명령줄 인터페이스--Redis를 참조하세요.

  • VM 크기를 늘려 대역폭 기능을 더 높입니다.
    • 클라이언트 또는 서버 VM의 대역폭이 증가하면 크기가 큰 응답의 데이터 전송 시간을 줄일 수 있습니다.
    • 두 머신의 현재 네트워크 사용량과 현재 VM 크기 한도를 비교해 보세요. 서버에서만 또는 클라이언트에서만 대역폭이 증가하는 것으로는 충분하지 않을 수 있습니다.
  • 애플리케이션에서 사용하는 연결 개체 수를 늘립니다.
    • 라운드 로빈 방식을 사용하여 여러 연결 개체에 대한 요청을 수행할 수 있습니다.

클라이언트 호스트의 높은 CPU

클라이언트 CPU 사용량이 높다는 것은 시스템이 할당된 작업을 따라잡을 수 없다는 것을 의미합니다. 캐시가 신속하게 응답을 전송해도 클라이언트가 제시간에 응답을 처리하지 못할 수 있습니다. 클라이언트 CPU를 80% 미만으로 유지하는 것이 좋습니다. 메트릭 “오류”(유형: UnresponsiveClients)를 확인하여 클라이언트 호스트가 Redis 서버의 응답을 제 시간에 처리할 수 있는지 확인합니다.

Azure Portal에서 제공하는 메트릭을 사용하거나 머신의 성능 카운터를 통해 클라이언트의 시스템 전체 CPU 사용량을 모니터링하세요. 단일 프로세스는 CPU 사용량이 낮지만 시스템 전체 CPU 사용량은 높을 수 있으므로 프로세스 CPU를 모니터링하지 않도록 주의합니다. CPU 사용량에서 제한 시간에 해당 하는 급증을 확인합니다. [트래픽 버스트] 섹션에 설명된 대로 높은 CPU는 TimeoutException 오류 메시지의 in: XXX 값을 높이는 원인이 될 수도 있습니다.

참고 항목

StackExchange.Redis 1.1.603 이상은 TimeoutException 오류 메시지에 local-cpu 매트릭을 포함합니다. StackExchange.Redis NuGet 패키지의 최신 버전을 사용 중인지 확인합니다. 버그가 코드에서 정기적으로 수정되어 시간 제한에 대한 강력한 기능을 제공합니다. 최신 버전을 보유하는 것이 중요합니다.

클라이언트의 높은 CPU 사용량을 완화하려면 다음을 수행합니다.

  • CPU 스파이크의 원인을 조사합니다.
  • CPU 용량이 더 많은 더 큰 VM 크기로 클라이언트를 업그레이드합니다.

클라이언트 호스트의 네트워크 대역폭 제한

클라이언트 컴퓨터의 아키텍처에 따라, 클라이언트 컴퓨터는 어느 정도의 네트워크 대역폭을 사용할 수 있는지에 제한이 있습니다. 클라이언트가 네트워크 용량을 오버로드하여 사용 가능한 대역폭을 초과하면 서버에서 보내는 만큼 신속하게 클라이언트 쪽에서 데이터가 처리되지 않습니다. 이 경우 시간이 초과될 수 있습니다.

예제 BandwidthLogger를 사용하여 대역폭 사용량이 시간에 따라 어떻게 바뀌는지 모니터링합니다. 이 코드는 (Azure 웹 사이트와 같이) 권한이 제한된 일부 환경에서 성공적으로 실행되지 않을 수도 있습니다.

이 문제를 완화하려면 네트워크 대역폭 소비를 줄이거나 클라이언트 VM 크기를 네트워크 용량이 더 많은 크기로 늘리세요. 자세한 내용은 큰 요청 또는 응답 크기를 참조하세요.

Linux 기반 클라이언트 애플리케이션에 대한 TCP 설정

Linux의 낙관적 TCP 설정으로 인해 Linux에서 호스트되는 클라이언트 애플리케이션에 연결 문제가 발생할 수 있습니다. 자세한 내용은 Linux 호스팅 클라이언트 애플리케이션에 대한 TCP 설정을 참조하세요.

RedisSessionStateProvider 다시 시도 시간 제한

RedisSessionStateProvider를 사용하는 경우 다시 시도 시간 제한을 올바르게 설정했는지 확인합니다 retryTimeoutInMilliseconds 값이 operationTimeoutInMilliseconds 값보다 높아야 합니다. 그렇지 않으면 다시 시도하지 않습니다. 다음 예제에서 retryTimeoutInMilliseconds가 3,000으로 설정됩니다. 자세한 내용은 Azure Cache for Redis에 대한 ASP.NET 세션 상태 제공자세션 상태 제공자 및 출력 캐시 공급자의 구성 매개 변수를 사용하는 방법을 참조하세요.

<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"
>

서버 쪽 문제 해결

서버 쪽 문제 해결은 다음과 같습니다.

서버 유지 관리

계획되거나 계획되지 않은 유지 관리로 인해 클라이언트 연결이 중단될 수 있습니다. 예외의 수와 유형은 코드 경로에서 요청의 위치와 캐시가 연결을 닫는 시점에 따라 달라집니다. 예를 들어, 요청을 보냈지만 장애 조치(failover)가 발생할 때 응답을 받지 못한 작업에서 시간 제한 예외가 발생할 수 있습니다. 닫힌 연결 개체에 대한 새 요청은 다시 연결이 성공적으로 발생할 때까지 연결 예외를 수신합니다.

자세한 내용은 다음 다른 섹션을 확인합니다.

시간 초과가 발생한 동안 Azure Cache for Redis에 장애 조치(failover)가 있었는지 확인하려면 메트릭 오류를 확인합니다. Azure Portal의 리소스 메뉴에서 메트릭을 선택합니다. 그런 다음, Errors 메트릭을 ErrorType으로 나눈 새 차트를 생성합니다. 이 차트를 만들면 장애 조치(failover) 횟수가 표시됩니다.

장애 조치(failover)에 대한 자세한 내용은 Azure Cache for Redis에 대한 장애 조치(failover) 및 패치를 참조하세요.

높은 서버 부하

서버 부하가 높으면 Redis 서버가 요청을 따라갈 수 없어 시간이 초과됩니다. 서버의 응답 속도가 느려지고 요청 속도를 따라가지 못할 수 있습니다.

서버 부하와 같은 메트릭을 모니터링합니다. Server Load 사용량에서 제한 시간에 해당하는 급증을 확인합니다. 서버 로드에 대한 메트릭에 대한 알림을 생성하여 잠재적인 영향에 대해 조기에 알립니다.

높은 서버 부하를 완화하기 위해 수행할 수 있는 몇 가지 변경 사항은 다음과 같습니다.

  • 상위 메모리 압력으로 인해 이 문서에 언급한 장기 실행 명령과 같은 높은 서버 부하를 유발하는 원인을 조사합니다.
  • 더 많은 분할된 데이터베이스로 스케일 아웃하여 여러 Redis 프로세스에 부하를 분산하거나, 더 많은 CPU 코어가 있는 대규모 캐시 크기로 스케일 업합니다. 자세한 내용은 Azure Cache for Redis 계획 FAQ를 참조하세요.
  • C1 캐시의 프로덕션 워크로드가 바이러스 검사로 인한 추가 대기 시간으로 인해 부정적인 영향을 받는 경우 C2와 같은 다중 CPU 코어가 포함된 상위 계층 제품에 대한 비용을 지불하여 영향을 줄일 수 있습니다.

서버 부하 급증

C0C1 캐시에서는 VM에서 바이러스 검사가 실행되는 동안 하루에 몇 번씩 요청 증가로 인해 서버 부하가 일시적으로 급증하는 것을 볼 수 있습니다. 이러한 계층에서 바이러스 검사가 진행되는 동안 요청에 대한 대기 시간이 길어집니다. C0C1 계층의 캐시에는 멀티태스크에 위한 단일 코어만 있어 바이러스 검색 및 Redis 요청 처리 작업을 나눕니다.

높은 메모리 사용량

이 섹션은 이동되었습니다. 자세한 내용은 상위 메모리 사용량을 참조하세요.

장기 실행 명령

일부 Redis 명령 실행은 다른 명령에 비해 비용이 많이 듭니다. Redis 명령 설명서는 각 명령의 시간 복잡성을 보여 줍니다. Redis 명령 처리는 단일 스레드입니다. 실행하는 데 시간이 오래 걸리는 명령은 명령 뒤에 오는 다른 모든 명령을 차단할 수 있습니다.

Redis 서버에 실행하는 명령을 검토하여 성능에 미치는 영향을 파악합니다. 예를 들어, KEYS 명령은 O(N) 작업이라고 알지 못해도 자주 사용됩니다. SCAN을 사용하여 CPU 급증을 줄이는 KEYS를 방지할 수 있습니다.

SLOWLOG GET 명령을 사용하여 서버에 대해 실행되는 비용이 많이 드는 명령을 측정할 수 있습니다.

고객은 콘솔을 사용하여 이러한 Redis 명령을 실행하여 장기 실행 및 비용이 많이 드는 명령을 조사할 수 있습니다.

  • SLOWLOG는 Redis 느린 쿼리 로그를 읽고 다시 설정하는 데 사용됩니다. 클라이언트 쪽에서 장기 실행 명령을 조사하는 데 사용할 수 있습니다. Redis 느린 로그는 지정된 실행 시간을 초과한 쿼리를 기록하는 시스템입니다. 실행 시간에는 클라이언트와 통신, 회신 보내기 등과 같은 I/O 작업이 포함되지 않지만 실제로 명령을 실행하는 데 필요한 시간만 포함됩니다. 고객은 SLOWLOG 명령을 사용하여 Redis 서버에 대해 실행되는 비용이 많이 드는 명령을 측정/로그할 수 있습니다.
  • MONITOR는 Redis 서버에서 처리된 모든 명령을 다시 스트리밍하는 디버깅 명령입니다. 데이터베이스에 무슨 일이 일어나고 있는지 이해하는 데 도움이 될 수 있습니다. 이 명령은 까다로워서 성능에 부정적인 영향을 줄 수 있습니다. 성능이 저하될 수 있습니다.
  • INFO - 명령은 컴퓨터별로 구문 분석하기 쉽고 사람이 읽기 쉬운 형식으로 서버에 대한 정보 및 통계를 반환합니다. 이 경우 CPU 섹션은 CPU 사용량을 조사하는 데 유용할 수 있습니다. 서버 로드 100(최댓값)은 Redis 서버가 항상 사용 중이었고 요청을 처리할 때 한 번도 유휴 상태가 아니었음을 나타냅니다.

출력 샘플입니다.

# 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
  • CLIENT LIST - 클라이언트 연결 서버에 대한 정보와 통계를 대부분 사람이 읽을 수 있는 형식으로 반환합니다.

네트워크 대역폭 제한

캐시 크기가 다르면 네트워크 대역폭 용량도 다릅니다. 서버가 사용 가능한 대역폭을 초과하면 데이터가 클라이언트에게 신속하게 전송되지 않습니다. 서버에서 클라이언트로 데이터를 충분히 빠르게 푸시할 수 없어서 클라이언트 요청이 시간 초과될 수 있습니다.

"Cache Read" 및 "Cache Write" 메트릭을 사용하여 서버 쪽 대역폭의 사용량을 확인할 수 있습니다. 포털을 사용하여 이러한 메트릭을 볼 수 있습니다. 캐시 읽기 또는 캐시 쓰기와 같은 메트릭에 잠재적 영향을 초기에 알리도록 경고를 만듭니다.

네트워크 대역폭 사용량이 최대 용량에 근접하는 상황을 완화하려면 다음을 수행합니다.

  • 네트워크 수요를 줄이기 위해 클라이언트 호출 동작을 변경합니다.
  • 더 많은 네트워크 대역폭 용량을 사용하여 더 큰 캐시 크기로 조정합니다. 자세한 내용은 Azure Cache for Redis 계획 FAQ를 참조하세요.

StackExchange.Redis 시간 제한 예외 조사

StackExchange.Redis를 사용할 때 시간 제한을 해결하는 자세한 내용은 StackExchange.Redis에서 시간 제한 예외 조사를 참조하세요.