WIL (2025-09-08 ~ 2025-09-14)
Redis 자료구조 집중 요약 (Data Structures Only)
이번 주는 자료구조 자체만 정리했다. 각 구조의 한 줄 설명, 언제 쓰는지, 핵심 명령과 복잡도, 주의점만 남겼다.
0) TL;DR
- String / List / Set / Sorted Set(ZSET) / Hash / Stream / Bitmap·Bitfield / HyperLogLog / Geo
- 기본 패턴만 알면 80%는 끝: 캐시(String), 큐(List), 중복 제거(Set), 랭킹(ZSET), 작은 객체(Hash), 이벤트 로그(Stream), 출석·플래그(Bitmap), 고유 수 추정(HLL), 반경 검색(Geo).
1) 한눈 비교표
타입 | 특징 | 대표 시나리오 | 핵심 명령 | 삽입 | 갱신/조회/범위 | 주의/비고 |
String | 값 1개(바이너리 안전) | 캐시, 카운터, 토큰 | SET/GET, SETEX, GETEX, INCRBY | O(1) | O(1) | TTL 옵션(NX/XX/EX/PX/KEEPTTL) |
List | 양끝 입출(큐/스택) | 작업 큐, 최근 N개 | LPUSH/RPUSH, BLPOP/BRPOP, LRANGE, LTRIM | O(1) (양끝) | LRANGE O(N) | 중간 삭제/접근 O(N) |
Set | 중복 없음, 무순서 | 태그, 팔로우, 교집합 | SADD/SREM, SISMEMBER, SINTER | 평균 O(1) | 집합연산 O(N) | 큰 집합은 SSCAN |
ZSET | 점수 기반 정렬 | 랭킹, 점수 집계 | ZADD, ZINCRBY, ZRANGE*, ZREMRANGEBYRANK | O(log N) | 범위 O(log N+M) | 상위 N만 유지로 pruning |
Hash | 작은 JSON 느낌 | 사용자/상품 속성 | HSET/HGET/HMGET, HGETALL, HINCRBY | 평균 O(1) | HGETALL O(N) | 필요한 필드만 조회 |
Stream | 로그 + 컨슈머그룹 | 이벤트 처리, 재시도 | XADD, XGROUP, XREADGROUP, XACK | O(1) | O(1~) | MAXLEN 유지, PENDING 관리 |
Bitmap/Bitfield | 비트 플래그 | 출석, 활성여부 | SETBIT/GETBIT, BITCOUNT, BITFIELD | O(1) | BITCOUNT O(N/word) | 오프셋 설계 고정 |
HyperLogLog | 근사 유니크 카운트 | 일간 UV | PFADD, PFCOUNT, PFMERGE | O(1) | O(1) | 목록 조회 불가, 오차 허용 |
Geo | 좌표 + 반경 검색 | 근처 매장/충전소 | GEOADD, GEOSEARCH, GEODIST | O(log N) | O(log N+M) | 내부 ZSET, 단위 주의 |
복잡도 주의: *MEMBERS, *RANGE, *GETALL 류는 요소 수에 비례. 대량 데이터엔 SCAN 계열 사용.
2) 자료구조별 핵심 정리
2.1 String — "포스트잇"
- 언제: 캐시 값, 토큰, 분산 락, 카운터.
- 명령:
- 캐시: SET key value EX 60
- 조건부 set(없을 때만): SET k v NX EX 60
- 카운터: INCRBY k 1
- TTL만 갱신: GETEX k EX 30
- 주의: 큰 값은 네트워크·메모리 비용↑. 만료 설계 없으면 캐시 폭주 위험.
2.2 List — "줄 서기"
- 언제: 작업 큐(생산자/소비자), 최근 N개 보관.
- 명령:
- 넣기/빼기: RPUSH q 1 2, BLPOP q 5
- 슬라이스: LRANGE q 0 9
- 상한 유지: LTRIM q 0 999
- 주의: 중간 접근/삭제는 비쌈(O(N)).
2.3 Set — "중복 없는 모음"
- 언제: 유저 태그, 팔로우, 추천 교집합.
- 명령: SADD, SISMEMBER, SINTER, SPOP, SCARD
- 주의: 전체 나열 SMEMBERS 대신 대규모는 SSCAN.
2.4 Sorted Set(ZSET) — "점수 달린 순위표"
- 언제: 랭킹, 점수 기반 정렬, 시간/점수 범위 조회.
- 명령:
- 추가/증가: ZADD rank 1 user:1, ZINCRBY rank 1 user:1
- 조회: ZREVRANGE rank 0 9 WITHSCORES, ZRANGEBYSCORE rank 0 100
- 정리: ZREMRANGEBYRANK rank 0 -1001 (Top 1000 유지)
- 주의: 대량 멤버 관리 시 정리(pruning) 필요.
2.5 Hash — "작은 JSON"
- 언제: 객체를 필드 단위로 저장(이름, 포인트 등).
- 명령: HSET user:1 name Taehoon point 100, HMGET user:1 name point, HINCRBY user:1 point 10
- 주의: HGETALL 남용 금지(필드 많을수록 비용↑).
2.6 Stream — "이벤트 로그"
- 언제: 소비자 그룹으로 작업 분배/재시도 필요한 큐.
- 명령:
- 추가: XADD orders * id 100 price 3000
- 그룹 생성: XGROUP CREATE orders g1 $ MKSTREAM
- 읽기: XREADGROUP GROUP g1 c1 COUNT 100 BLOCK 5000 STREAMS orders >
- 확인: XACK orders g1 <id>
- 주의: MAXLEN으로 길이 제한, PENDING(미확인) 주기적 정리.
2.7 Bitmap/Bitfield — "출석판/플래그"
- 언제: 사용자 i의 상태(0/1), 빠른 합계.
- 명령: SETBIT attend:20250910 123 1, GETBIT attend:20250910 123, BITCOUNT attend:20250910
- 주의: 오프셋에 어떤 의미를 줄지(사용자ID/날짜 등) 처음에 고정.
2.8 HyperLogLog — "UV 근사치"
- 언제: 고유 수를 메모리 작게, 빠르게 추정.
- 명령: PFADD uv:20250910 u1 u2, PFCOUNT uv:20250910
- 주의: 개별 목록은 못 얻는다(근사치 전용).
2.9 Geo — "근처 찾기"
- 언제: 반경/거리 기반 검색.
- 명령: GEOADD shop 126.9 37.5 s1, GEOSEARCH shop FROMLONLAT 126.9 37.5 BYRADIUS 3 km WITHDIST
- 주의: 내부적으로 ZSET, 단위(km/m) 명시.
3) 사용처 기반 선택 가이드
- 캐시·토큰·카운터 → String
- 큐/백로그 → List(간단), Stream(여러 소비자·재시도)
- 중복 없는 집합/교집합 → Set
- 순위/정렬·점수 → ZSET
- 작은 객체 → Hash
- 출석/활성 플래그 → Bitmap/Bitfield
- 대략 UV → HyperLogLog
- 반경·거리 → Geo
'Loopers' 카테고리의 다른 글
🔥 "랭킹 좀 만들어달라는데 Redis 메모리가..." - ZSET 랭킹 시스템 구축기 (1) | 2025.09.11 |
---|---|
"같은 주문이 두 번 결제됐습니다" 💸 - Kafka로 배운 분산 시스템의 잔혹한 현실 (1) | 2025.09.05 |
🚨 “그냥 @EventListener면 끝?” — 이벤트, 언제·왜·어떻게 사용할 것인가 ⚙️ (3) | 2025.08.29 |
Resilience와 보상 트랜잭션: 장애에 대응하는 방법 (1) | 2025.08.24 |
PG가 터져도 우리 서비스는 멀쩡해야 한다 🔥 (3) | 2025.08.22 |