Redis cache에 응답 최신성을 남기는 방법
Redis hot cache, 마지막 성공 cache와 DB fallback으로 응답 최신성을 드러낸 방법
한강자리 백엔드는 Redis로 현재값과 조립한 응답을 빠르게 읽고 외부 출처나 DB 조합이 순간적으로 실패하면 마지막 성공 응답을 찾는다.
cache 응답에는 출처에서 값을 확인한 시각과 최신성 상태를 함께 둔다. Redis에서 빠르게 읽은 값도 출처 시각이 오래됐다면 stale로 표시한다.
다시 만들 수 있는 Redis 값
한강자리에는 성격이 다른 cache가 있다.
| Cache | 예 | 목적 |
|---|---|---|
| Status cache | 주차장 최신 값 | lot 단위 빠른 조회 |
| Forecast cache | 예측 overview/timeline | 계산된 응답 재사용 |
| Home summary hot cache | 첫 화면 summary | 짧은 TTL의 빠른 응답 |
| Home summary stale cache | 마지막 성공 summary | rebuild 실패 시 fallback |
| 출처 상태 cache | 출처 확인 결과 | 반복 조회 비용 절감 |
기준 데이터와 이력은 Postgres에 두고 Redis에는 다시 만들 수 있는 조회 결과를 저장한다.
Redis가 비면 Postgres에서 조회 결과를 다시 만들고 Postgres의 기준 데이터나 이력이 손상되면 백업 복구 절차를 따른다.
flowchart LR API["API 읽기"] --> Redis["Redis 캐시"] Redis -->|적중| Response["응답"] Redis -->|미스| Postgres["Postgres 행"] Postgres --> Build["페이로드 만들기"] Build --> Redis Build --> Response
주차 cache 장애의 DB fallback
주차 값은 lot 단위로 자주 읽힌다. 앱, 위젯, home summary, 예측 입력이 모두 최신 주차 값을 필요로 한다.
코드에서는 현재 상태 캐시 역할을 RedisStatusCache가 맡는다. lot ID별 key에 JSON payload를 저장하고 cache를 읽을 때 malformed payload나 Redis 장애가 있으면 해당 entry를 무시하고 DB로 내려간다.
조회 경로에는 두 규칙을 적용한다.
- cache 장애는 DB fallback으로 처리한다.
- cache hit라도 오래된 값인지 다시 확인한다.
sequenceDiagram
autonumber
participant Query as 주차 조회
participant Cache as 상태 캐시
participant DB as Postgres
Query->>Cache: 주차 상태 캐시 확인
alt 캐시 적중
Cache-->>Query: 최신 주차 상태 반환
Query->>Query: 출처 시각으로 최신성 판단
else 미스 또는 캐시 사용 불가
Query->>DB: 저장소의 마지막 상태 확인
DB-->>Query: 저장된 상태 또는 없음
Query->>Query: 오래됐거나 비어 있는지 판단
end
stale 여부는 cache 저장 시점이 아니라 출처에서 확인한 시각으로 본다. 이 기준은 Redis TTL과 무관하게 같은 최신성 판정을 유지한다.
빠른 cache와 마지막 성공 cache
home-summary는 만들 때 비용이 큰 응답이다. 주차, 예측, 나들이, 출처 확인 결과를 모아야 한다.
응답을 다시 만들 때 두 종류의 cache를 사용한다.
- hot cache: 정상 응답을 빠르게 재사용하는 짧은 TTL cache.
- stale cache: 마지막 성공 payload를 더 오래 보관하는 backup cache.
정상적으로 다시 만들기에 성공하면 hot과 stale cache를 함께 갱신한다. hot cache가 비었고 다시 만들기에 실패하면 stale cache를 확인한다.
flowchart TD
Request["home-summary 요청"] --> Hot{"핫 캐시 적중?"}
Hot -->|예| ReturnHot["핫 응답 반환"]
Hot -->|아니오| Rebuild["DB/유스케이스에서 다시 만들기"]
Rebuild -->|성공| StoreBoth["핫 + 보관 캐시 저장"]
StoreBoth --> ReturnFresh["새 응답 반환"]
Rebuild -->|실패| Stale{"보관 캐시 적중?"}
Stale -->|예| ReturnStale["보관 응답 반환"]
Stale -->|아니오| Error["오류 발생"]
stale cache를 반환할 때는 payload의 갱신 상태와 출처 확인 결과를 유지해 “마지막으로 확인한 값”으로 표시한다. 확인 시각이나 stale 상태가 없으면 fallback을 반환하지 않는다.
HTTP 반복 요청 감소
서버 내부 Redis cache와 HTTP cache는 쓰임이 다르다. home-summary 응답에는 private cache header와 ETag를 붙인다. 같은 앱 인스턴스가 짧은 시간 안에 같은 첫 화면 값을 반복 요청하면 304를 받을 수 있다.
응답은 앱 접근 조건과 요청 맥락을 고려해 private cache로 다룬다.
출처 변경의 응답 영향
한강자리의 cache는 원천 데이터와 기준 데이터에서 다시 만드는 조회 결과다. 무효화 범위도 이 조회 결과의 pattern 단위로 정한다.
예측 결과가 바뀌면 forecast cache와 home summary cache가 영향을 받는다. 나들이 출처 확인 결과가 바뀌면 home summary에도 영향이 있다. 주차 값 cache는 polling 작업이 최신 snapshot을 쓰면서 갱신한다.
무효화 대상은 변경된 출처를 사용하는 forecast와 home summary 응답 단위로 정한다.
fallback의 최신성 메타데이터
Redis에는 다시 만들 수 있는 조회 결과를 두고 cache hit 뒤에도 출처의 확인 시각을 판정한다. hot cache는 빠른 응답에, stale cache는 rebuild 실패 때의 마지막 성공값에 사용한다. cache 장애는 DB fallback으로 흡수하고 지표로 남기며 stale 응답에는 갱신 상태를 보존한다. HTTP private cache는 같은 앱 인스턴스의 반복 요청을 줄이는 별도 경로다.
Comments
아직 댓글이 없습니다. 첫 댓글을 남겨주세요.
검토 대기 중