TrotVote
[IT 심층 분석]

Redis 클러스터 환경에서의 핫 키(Hot Key) 문제와 특정 노드 CPU 급등 현상 해결 전전

김민준 · IT 시스템 엔지니어|
수백만 명의 사용자가 이용하는 실시간 랭킹 서비스의 백엔드를 Redis 클러스터로 구성해두었는데 서비스 피크타임마다 특정 Redis 노드 하나만 CPU가 90%를 넘으며 비명을 지르고 나머지 노드들은 한자리 수 점유율로 여유롭게 있는 불균형 현상이 발생했습니다. Redis 클러스터는 키의 해시 슬롯을 기준으로 여러 노드에 데이터를 분산하는 구조인데도 이렇게 특정 노드에 부하가 몰리는 것은 핫 키(Hot Key) 문제의 전형적인 증상이었습니다. 핫 키란 초당 수십만 번 이상 읽히거나 쓰이는 특정 캐시 키를 뜻합니다. 이 키가 속한 해시 슬롯은 필연적으로 한 개의 노드에만 귀속됩니다. 아무리 노드를 많이 추가해도 이 핫 키만을 처리하는 책임은 영원히 그 특정 노드에만 집중되는 근본적인 한계가 있습니다. redis-cli --hotkeys 명령어로 분석해보니 서비스 진입 시 사용자에게 오늘의 랭킹 Top-100을 제공하는 sorted set 구조의 키 값이 압도적으로 많은 접근 수를 기록하고 있었습니다. 핫 키 문제를 완화하기 위한 첫 번째 전략은 읽기 쪽에서의 복제본 활용이었습니다. Redis 클러스터의 각 노드에는 읽기 전용 복제본(Replica)이 존재합니다. 애플리케이션의 Redis 클라이언트 설정에서 읽기 명령어를 복제본 노드에도 분산하도록 READONLY 모드를 활성화하여 읽기 부하 자체를 마스터와 복제본이 나누어 감당하게 했습니다. 두 번째로는 애플리케이션 단에서 인메모리 로컬 캐시 레이어를 하나 더 얹는 것이었습니다. 핫 키의 값 자체를 각 서버 프로세스의 로컬 메모리에 짧은 TTL로 캐싱해두면 Redis에 도달하는 요청 수 자체가 급감합니다. 이 패턴을 다단 캐시(Multi-Level Cache)라고 부릅니다. 세 번째로 해당 랭킹 데이터를 단일 키가 아닌 여러 개의 샤딩된 키로 분리하여 다른 해시 슬롯에 분산하는 리팩터링도 진행했습니다. 세 가지 방어막을 모두 적용하자 가장 부하가 심했던 Redis 노드의 CPU는 90%대에서 15%대로 급강하했고 클러스터 전체가 아름답게 균형을 찾았습니다.