Redis 와 캐싱 · 자료구조별 쓰임 · 이론
여섯 자료구조와 그 자리
한 줄 요약
Redis 를 잘 쓴다는 것은 명령을 많이 아는 것이 아니라, 문제에 맞는 자료구조를 고르는 것이다.
왜 이게 필요했나
많은 팀이 Redis 를 String 하나로만 씁니다. 전부 JSON 으로 직렬화해 SET 하고 GET 합니다. 동작은 합니다. 그런데 사용자 프로필의 이메일 한 필드만 바꾸려 해도 전체를 읽어 파싱하고 수정해 다시 씁니다. 동시에 두 요청이 그렇게 하면 한쪽이 덮어씁니다.
Hash 를 쓰면 HSET user:42 email a@b.com 한 줄이고, 다른 필드와 충돌하지 않습니다. 자료구조 선택 하나가 경쟁 조건을 없앱니다.
어떻게 동작하나
String 은 단순 값과 카운터입니다. INCR 이 원자적이라는 점이 중요합니다 — 조회수, 레이트 리밋 카운터, 시퀀스 번호에 씁니다. SET key val NX EX 60 은 분산 잠금의 기본 형태입니다.
Hash 는 필드가 여러 개인 객체입니다. 필드 단위 갱신과 조회가 되고, 필드 수가 적으면 Redis 가 내부적으로 압축된 인코딩을 써서 메모리도 아낍니다.
List 는 순서 있는 목록이고 양쪽 끝 삽입·삭제가 O(1) 입니다. 작업 큐와 최근 활동 목록에 씁니다. 가운데 접근은 O(N) 이라 큰 리스트를 인덱스로 뒤지면 안 됩니다.
Set 은 중복 없는 집합이고 교집합·합집합·차집합이 명령 하나입니다. 태그, 팔로워, 중복 제거에 씁니다. SADD 의 반환값으로 "처음 보는 것인가"를 알 수 있어 멱등성 구현에도 쓰입니다.
ZSet(정렬 집합)은 점수를 가진 집합입니다. 점수로 정렬된 상태가 항상 유지되고, 순위 조회가 O(log N) 입니다. 랭킹, 우선순위 큐, 시계열 윈도우(점수를 타임스탬프로)에 씁니다. 이 코스에서 별도 실습 하나를 통째로 쓸 만큼 중요합니다.
Stream 은 추가 전용 로그입니다. 컨슈머 그룹과 확인응답이 있어 진짜 큐에 가장 가깝습니다. 앞 코스에서 다뤘습니다.
현장에서 만나는 모습
운영에서 가장 조심할 명령은 KEYS 입니다. 전체 키스페이스를 훑으며 그동안 Redis 는 다른 일을 못 합니다. Redis 는 단일 스레드로 명령을 처리하기 때문에, 키가 수백만 개인 인스턴스에서 KEYS * 한 번이 수 초의 전면 정지를 만듭니다. 반드시 SCAN 을 커서로 돌려야 합니다.
같은 이유로 FLUSHALL, 큰 컬렉션에 대한 SMEMBERS / LRANGE 0 -1, DEL 로 거대한 키를 지우는 것(대신 UNLINK)도 조심해야 합니다. "Redis 가 갑자기 느려졌다"의 상당수는 O(N) 명령 하나입니다.
메모리 관점도 알아 둘 만합니다. MEMORY USAGE <key> 로 키별 실제 사용량을 볼 수 있고, 같은 데이터라도 자료구조에 따라 몇 배씩 차이가 납니다.
다음 실습에서 할 것
여섯 자료구조를 하나씩 직접 다루고, KEYS 대신 SCAN 으로 순회하고, 마지막에 같은 데이터를 다른 자료구조로 저장했을 때의 메모리 차이를 표로 만듭니다.