Write-Behind(라이트 비하인드) 캐시 패턴은 캐시에 먼저 쓰고 데이터베이스에는 비동기적으로 나중에 반영하는 캐싱 전략이다. 쓰기 성능을 극대화하지만 데이터 유실 위험이 있다.
캐시 패턴 비교
| 패턴 | 쓰기 순서 | 읽기 | 일관성 | 쓰기 성능 |
|---|
| Cache-Aside | DB 직접 | 미스 시 DB | 강함 | 중간 |
| Write-Through | 캐시+DB 동시 | 캐시 우선 | 강함 | 낮음 |
| Write-Behind | 캐시→(비동기)DB | 캐시 우선 | 약함 | 높음 |
| Read-Through | 캐시가 DB 조회 | 캐시 우선 | 강함 | 중간 |
Write-Behind 동작
1. 클라이언트 → 캐시에 쓰기 (빠름)
2. 캐시는 즉시 성공 응답
3. 백그라운드 워커가 DB에 비동기 쓰기
4. DB 쓰기 실패 시 재시도 또는 알림
위험:
캐시 장애 시 DB에 반영 안 된 데이터 유실
Redis Write-Behind 구현
typescript
class WriteBehindCache {
private dirtyKeys = new Set<string>();
async write(key: string, value: object): Promise<void> {
// 1. 캐시에 즉시 쓰기
await redis.set(key, JSON.stringify(value));
this.dirtyKeys.add(key);
// 2. 즉시 성공 반환 (DB 쓰기 대기 없음)
}
// 백그라운드 플러시 (주기적 실행)
async flush(): Promise<void> {
const keys = [...this.dirtyKeys];
this.dirtyKeys.clear();
await db.transaction(async (trx) => {
for (const key of keys) {
const value = await redis.get(key);
if (value) {
await trx('data').insert(JSON.parse(value))
.onConflict('id').merge();
}
}
});
}
}
// 1초마다 DB에 플러시
setInterval(() => cache.flush(), 1000);
적합한 사용 사례
✅ 고빈도 쓰기 (게임 점수, 조회수, 좋아요)
✅ 배치 처리로 DB 쓰기 효율화
✅ DB 장애 시 데이터 버퍼링
❌ 금융 거래 (유실 불가)
❌ 즉각적 일관성 필요 시
관련 개념