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 명령을 활용할 수 있어, 대용량 키 삭제 작업을 훨씬 효율적으로 처리할 수 있습니다.