데이터·캐시·저장소 용어
Redis, 캐시 운영, 분산 DB, 샤딩, 인덱스, 락, 정합성 등 데이터를 다루는 용어
- 용어 32개
Redis (레디스)
메모리에 데이터를 두는 키-값 저장소(인메모리 DB). 캐시, 세션, 분산 락, 간단한 큐 등에 쓴다.
- 명령을 기본적으로 싱글 스레드로 하나씩 처리한다. 그래서 오래 걸리는 명령 하나가 뒤의 모든 요청을 지연시킨다.
- 데이터가 메모리에 있어 빠르지만 용량은 메모리 크기에 제한된다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind · 결제요청 전 -더미 데이터- Redis로 관리하기
remote cache
네트워크 너머의 별도 서버(예: Redis)에 둔 캐시.
- 여러 서버가 같은 캐시를 공유하지만 매번 네트워크 왕복이 든다. 서버 안에 둔 local cache와 비교한다(운영체제·시스템 노트 참고).
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
cache hit / miss / hit rate
요청한 데이터가 캐시에 있으면 hit, 없어서 원본(DB)까지 가면 miss, hit의 비율이 hit rate(적중률).
- hit rate가 갑자기 떨어지면 원본으로 트래픽이 쏟아진다는 신호다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
cache stampede (thundering herd)
캐시가 비거나 한꺼번에 만료될 때, 많은 요청이 동시에 원본(DB)으로 몰리는 현상.
- 대응 예) 만료 시각에 무작위 값을 더해 분산(jitter), 한 요청만 원본을 읽어 캐시를 채우게 함(lock), 미리 채워 두기(warm-up).
- 서버 재시작이나 scale out 직후 local cache가 비면서 자주 생긴다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
cache invalidation (캐시 무효화)
원본이 바뀌었을 때 캐시의 옛 값을 지우거나 갱신하는 것.
- 어렵기로 유명한 문제다. local cache는 서버마다 따로라서 원본이 바뀐 것을 모른다.
- 먼저 “얼마나 오래된 값까지 허용할지”(stale 허용 범위)를 정하고, 필요하면 Pub/Sub 같은 방식으로 모든 서버에 “이 키를 지워라”고 알린다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
TTL (Time To Live)
데이터나 캐시, 레코드가 유효한 시간. 지나면 자동으로 만료된다.
- 예) 캐시 만료 시간, DNS 레코드를 캐시해도 되는 시간, 분산 락이 자동으로 풀리는 시간.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
Pub/Sub (발행/구독)
발행자가 채널에 메시지를 보내면, 그 채널을 구독 중인 모두가 받는 방식.
- Redis의 Pub/Sub은 메시지를 저장하지 않아서 그 순간 구독하지 않던 쪽은 받지 못한다. 저장되는 로그형 구조는 Redis Stream이나 Kafka 같은 것이다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind · Kafka 핵심 개념 - Topic·Partition·Offset·DLQ
bitmap (비트맵)
비트 하나로 true/false를 표현해 메모리를 크게 줄이는 자료구조.
- 예) 사용자별 출석 여부를 1비트로 저장.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
hot key / hot partition
특정 키(또는 파티션)에 요청이 몰려 그것을 담당하는 노드만 과부하가 되는 상태.
- 서버를 늘려도 몰린 키는 한 노드가 처리하므로 효과가 없다. 키를 쪼개거나 로컬 캐시를 앞에 두는 식으로 푼다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind · Kafka 핵심 개념 - Topic·Partition·Offset·DLQ
slot / hash tag (Redis Cluster)
Redis Cluster는 키를 16384개의 slot으로 나눠 노드에 분배한다. 키에 {...}(해시 태그)를 쓰면 같은 slot에 모인다.
{user:1}:profile,{user:1}:order는 같은 slot이라 한 노드에서 함께 조회(MGET)하거나 한 스크립트로 처리할 수 있다.- slot이 다른 키를 한 번에 처리하려 하면 오류가 나거나 노드별로 나눠 요청해야 한다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
MGET
여러 키를 한 번의 요청으로 조회하는 Redis 명령.
- 키마다 따로 조회하면 네트워크 왕복이 키 수만큼 늘어난다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
atomicity (원자성)
중간 상태 없이 전부 실행되거나 전혀 실행되지 않는 성질. 다른 작업이 중간에 끼어들 수 없다.
- race condition을 막는 핵심 개념이다(운영체제·시스템 노트 참고).
- 학습 노트: 스레드 동시성 문제 정리 - race·deadlock·livelock·starvation
Lua script (Redis)
Redis 안에서 실행하는 스크립트. 스크립트 전체가 명령 하나처럼 원자적으로 실행된다.
- “재고가 0보다 크면 1 차감”을 클라이언트가 GET 후 DECR로 처리하면 사이에 다른 요청이 끼어 재고가 음수가 될 수 있다. Lua로 묶으면 그 사이에 다른 명령이 끼어들 수 없다.
MULTI/EXEC는 원자적이지만 중간 결과로 분기할 수 없고, Lua는 분기와 원자성을 모두 지원하며 왕복도 한 번이다.- 스크립트가 길면 그동안 Redis 전체가 멈추므로 짧게 쓴다. Cluster에서는 다루는 키가 모두 같은 slot이어야 한다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind · 분산 락과 멱등성 키 설계
DEL vs UNLINK, KEYS vs SCAN (Redis 운영)
서버를 멈추게 하지 않는 방식으로 삭제·조회하는 명령 구분.
DEL은 동기 삭제라 큰 키를 지우면 그동안 서버가 멈춘다.UNLINK는 삭제 표시만 하고 실제 메모리 해제는 백그라운드에서 한다.KEYS *는 전체를 한 번에 훑어 서버를 막는다.SCAN은 커서로 조금씩 순회한다.- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
dual write (이중 쓰기)
두 곳(예: 구 버전과 신 버전의 저장 형식)에 동시에 쓰는 것.
- 캐시 포맷을 바꿀 때 v1과 v2 키에 동시에 쓰다가, v2가 충분히 채워지면 읽기를 v2로 전환한다. 배포 중 구·신 버전 서버가 섞여도 깨지지 않는다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
SSOT (Single Source of Truth)
데이터의 기준이 되는 단 하나의 원본.
- 캐시와 DB 값이 다르면 SSOT를 믿는다. write-behind에서 Redis를 1차 SSOT로 두는 설계도 있다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind
NoSQL
관계형(SQL) 모델을 쓰지 않는 DB의 통칭. 키-값, 문서, wide-column, 그래프 등이 있다.
- JOIN이나 트랜잭션을 포기하는 대신 수평 확장과 쓰기 성능이 강하다. 조회 패턴에 맞춰 테이블을 설계해야 한다.
LSM Tree
쓰기를 디스크의 제자리에서 수정하지 않고 메모리에 모았다가 순차적으로 덧붙여 쓰는 저장 구조.
- 쓰기가 빠르다. Cassandra 같은 DB가 쓴다. 쓰기 순서: commit log에 순차 기록 → 메모리(memtable) → 가득 차면 파일(SSTable)로 flush → 백그라운드에서 합침(compaction).
consistent hashing
노드를 링(ring) 모양으로 배치하고 키의 해시 값으로 담당 노드를 정하는 분산 방식.
- 노드를 추가하거나 빼도 일부 데이터만 재배치된다. 이 때문에 “무엇으로 조회할지”(partition key)를 먼저 정하고 테이블을 설계한다.
quorum / tunable consistency
복제본 중 몇 대가 응답해야 성공으로 볼지를 정하는 방식. quorum은 과반수.
- 예) ONE(빠름), QUORUM(과반수), ALL(가장 엄격). 요청마다 일관성과 속도를 조절할 수 있다.
sharding vs partitioning
둘 다 데이터를 나누는 방법이다. sharding은 여러 DB 서버로 수평 분할하는 것, partitioning은 한 DB 안에서 테이블을 기준(날짜 등)으로 쪼개는 것.
- partitioning은 오래된 파티션을
DROP PARTITION으로 즉시 삭제하는 식으로 시계열 데이터에 유리하다. - 데이터가 커질 때 방법이 이것뿐은 아니다. 오래된 데이터를 저렴한 저장소로 옮기는 archiving(hot/cold 분리), 일정 기간 뒤 삭제하는 TTL·보존 정책, 압축, 모델 재설계도 있다.
- 학습 노트: 파티션 작업 · DB 테이블 용량 증설
index / composite index (인덱스 / 복합 인덱스)
조회를 빠르게 하려고 미리 만들어 두는 색인 구조.
- 복합 인덱스는 컬럼 순서가 중요하다.
(a, b)인덱스는WHERE a=?나WHERE a=? AND b=?에는 쓰이지만WHERE b=?단독에는 쓰이지 않는다(leftmost prefix 규칙). - 인덱스는 쓰기 비용과 저장 공간을 늘린다.
- 학습 노트: 인덱스 · 인덱스, 키 · 인덱스 설계와 쿼리 재구성 패턴
replication / Primary-Replica / failover
DB를 복제해 두는 구조. 쓰기를 받는 Primary와 복제본인 Replica로 나뉜다.
- Replica는 읽기를 나누거나 장애에 대비한다. Primary가 죽으면 Replica를 새 Primary로 올리는 것이 failover다.
- 이중화 운영 = 같은 역할의 장비를 두 벌 이상 둔다.
- 학습 노트: 서버 장애 대응 방안
OLTP vs OLAP
OLTP는 주문, 결제 같은 짧은 거래를 빠르게 처리하는 용도, OLAP은 대용량 데이터를 모아 분석 조회하는 용도.
- 분석용 DB는 컬럼 단위로 저장하는 컬럼 지향(columnar) 구조를 많이 쓴다.
CDC (Change Data Capture)
DB의 변경 로그를 읽어 다른 시스템으로 변경 사항을 전달하는 기술.
- 새 저장소로 데이터를 복제하거나, 시스템을 합치고 분리할 때 옛 시스템과 새 시스템을 맞춰 가는 용도로 쓴다.
- 학습 노트: 분산 락과 멱등성 키 설계
idempotency key (멱등성 키)
같은 요청이 두 번 와도 결과가 한 번만 반영되게 하는 요청 고유 키.
- 서버가 “이미 처리한 키”면 이전 결과를 그대로 돌려준다. 결제 버튼을 두 번 눌러도 한 번만 결제되게 한다. idempotent(멱등성)는 개발 기본 노트 참고.
- 학습 노트: 분산 락과 멱등성 키 설계
optimistic lock / pessimistic lock
낙관적 락은 충돌이 드물다고 보고 락 없이 진행하다가 커밋할 때 충돌을 검사(보통 version 컬럼), 비관적 락은 충돌이 잦다고 보고 먼저 락을 잡고 진행.
- 낙관적 락은 충돌하면 실패 처리하고 재시도한다. 비관적 락의 예는
SELECT ... FOR UPDATE. - 락은 구현 위치로도 나눈다. DB lock은 DB가, memory lock(
synchronized등)은 그 프로세스 안에서만 유효하다. - 학습 노트: 분산 락과 멱등성 키 설계 · 비관적 락 & 낙관적 락 TPS 차이
spin lock vs waiting lock
spin은 락이 풀릴 때까지 루프를 돌며 계속 확인(CPU를 쓰지만 짧은 대기에 유리), waiting은 잠들어 있다가 락이 풀리면 깨어남.
- 학습 노트: 분산 락과 멱등성 키 설계
distributed lock (분산 락)
여러 서버가 공유하는 외부 저장소(Redis, DB 등)에 두는 락.
synchronized같은 락은 JVM 하나 안에서만 유효해서 서버가 3대면 락도 3개다. 분산 락은 서버 수와 무관하게 하나다.- Redis 단일 노드 방식:
SET lock:키 내UUID NX PX 3000.NX는 키가 없을 때만 설정(한 명만 성공),PX 3000은 3초 후 자동 만료(잡은 서버가 죽어도 영원히 잠기지 않음). 해제할 때는 값이 내 UUID인지 확인한 뒤 지워야 하고, 확인과 삭제를 원자적으로 하려고 Lua를 쓴다. - RedLock은 독립된 Redis N대(보통 5대)의 과반수에서 락을 얻어야 성공으로 보는 알고리즘이다. 시계 차이(NTP)나 처리 지연에 대한 안전성은 논쟁이 있다.
- 주의: 작업이 TTL보다 오래 걸리면 락이 먼저 풀려 두 곳이 동시에 작업할 수 있다. 락을 연장하는 watchdog, 또는 fencing token으로 대응한다.
- 학습 노트: 분산 락과 멱등성 키 설계
fencing token
락을 얻을 때마다 증가하는 번호를 붙여, 저장소가 오래된 번호의 요청을 거부하게 하는 기법.
- 락이 만료된 뒤 뒤늦게 도착한 옛 락 보유자의 쓰기를 막는다.
- 학습 노트: 분산 락과 멱등성 키 설계
transactional outbox
DB 저장과 메시지 발행을 하나로 묶을 수 없을 때 쓰는 패턴. 이벤트를 같은 DB 트랜잭션으로 outbox 테이블에 함께 저장하고, 별도 프로세스(또는 CDC)가 읽어 발행한다.
- DB는 커밋됐는데 Kafka 발행이 실패해서 생기는 불일치를 막는다.
- 이종 시스템(DB와 메시지 브로커) 사이에는 하나의 트랜잭션이 없어서 이런 패턴이 필요하다.
- 학습 노트: 분산 락과 멱등성 키 설계
eventual consistency (최종적 일관성)
잠시 값이 어긋나도, 시간이 지나면 모든 복제본이 같은 값으로 수렴하는 성질.
- write-behind, 캐시, 복제 구조에서 흔히 받아들이는 타협이다.
- 학습 노트: 캐시 전략과 운영 이슈 - Redis·stampede·무효화·write-behind · 분산 락과 멱등성 키 설계