Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

Redis에서 대용량 객체 삭제 시 서버 블로킹 방지 방법

Redis에서 해시(hash), 리스트(list), 셋(set), 정렬된 셋(sorted set)과 같은 문자열이 아닌 대용량 객체를 삭제할 때는 서버가 상당한 시간 동안 멈출 수 있으며, 이로 인해 클라이언트 타임아웃 같은 문제가 발생할 수 있습니다. 그 원인은 Redis의 작동 방식에 있는 두 가지 핵심 특성 때문입니다.

대용량 객체 삭제가 서버를 블로킹하는 이유

  • Redis는 단일 스레드(single-threaded) 방식으로 작동합니다. 연결된 클라이언트 수와 관계없이 한 번에 하나의 명령만 처리할 수 있습니다. 따라서 하나의 명령 실행이 오래 걸리면 다른 모든 명령은 그동안 대기해야 하며, 전체 서비스 응답 속도에 영향을 미치게 됩니다.

  • DEL 명령은 해시, 리스트, 셋, 정렬된 셋에 대해 O(n) 복잡도를 가집니다. 즉, 요소 100개를 가진 객체를 삭제할 때보다 요소 100만 개를 가진 유사한 객체를 삭제할 때 약 10,000배 더 많은 시간이 소요됩니다. 데이터 규모가 커질수록 삭제 비용이 기하급수적으로 늘어나는 셈입니다.

블로킹 없이 대용량 객체 삭제하는 해결 방법

다행히도 Redis는 서버를 장시간 블로킹하지 않고 대용량 객체를 삭제할 수 있는 도구들을 제공합니다. 아래에서 객체 유형별 해결 방법을 정리했습니다:

  • 대용량 해시(Hash) 삭제 방법
  • 대용량 리스트(List) 삭제 방법
  • 대용량 셋(Set) 삭제 방법
  • 대용량 정렬된 셋(Sorted Set) 삭제 방법

각 기법의 핵심은 한 번에 전체 객체를 삭제하는 대신, SCAN과 같은 커서 기반 순회 명령과 HDEL, LPOP, SREM, ZREM 등을 조합하여 일정 배치(batch) 단위로 나누어 점진적으로 삭제하는 것입니다. 이렇게 하면 각 명령이 짧은 시간 안에 완료되므로 다른 클라이언트의 요청 처리가 지연되지 않습니다. 또한 Redis 4.0 이상에서는 비동기 방식으로 메모리를 해제하는 UNLINK 명령을 활용할 수 있어, 대용량 키 삭제 작업을 훨씬 효율적으로 처리할 수 있습니다.