[BACK-008][중급] 캐시에 저장하고 제때 새로 읽기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[BACK-008][중급] 캐시에 저장하고 제때 새로 읽기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 141회 작성일 26-09-03 08:34

본문

[이번 수업]
서버가 같은 데이터를 요청마다 원본 저장소에서 다시 읽으면 응답이 느려지고 부하가 커집니다. 이번에는 캐시(cache), 즉 자주 쓰는 결과를 가까운 곳에 잠시 저장하는 방법과 오래된 값을 제때 버리는 만료 전략을 배웁니다.

[선수지식]
Python의 딕셔너리, 함수, 조건문을 알고 파일을 실행할 수 있어야 합니다. Windows는 py --version, macOS·Linux는 python3 --version으로 Python 3 설치를 확인하세요.

[학습목표]
1. 캐시 적중과 누락이 원본 조회에 미치는 영향을 설명한다.
2. TTL과 명시적 무효화를 함께 사용한다.
3. 데이터 특성에 따라 캐시 키와 만료 시간을 정한다.

[핵심개념]
캐시 키(cache key)는 저장한 값을 찾는 이름입니다. 키가 있고 유효하면 적중(hit), 없거나 만료됐으면 누락(miss)입니다. 캐시 어사이드(cache-aside)는 먼저 캐시를 확인하고, 누락일 때 원본을 읽어 캐시에 채우는 방식입니다. 캐시는 원본이 아니므로 사라져도 다시 만들 수 있어야 합니다.

TTL(Time To Live)은 값을 재사용할 수 있는 시간입니다. 짧으면 최신성은 좋아지지만 원본 조회가 늘고, 길면 빠르지만 오래된 값이 남을 수 있습니다. 가격·권한처럼 변경 영향이 큰 값은 쓰기 성공 직후 관련 키를 삭제하는 명시적 무효화도 필요합니다. 만료는 시간이 지난 키를 무효로 만들고, 축출(eviction)은 메모리가 부족할 때 정책에 따라 키를 내보내므로 서로 다릅니다. HTTP에서는 Cache-Control의 max-age로 신선한 기간을 지정합니다. 개인 응답은 공유 캐시에 섞이지 않도록 private 또는 no-store 지시자를 검토합니다.

[따라하기]
아래를 cache_demo.py로 저장하세요. 실제로 기다리지 않도록 now 값을 직접 전달합니다.

```python
TTL = 5
origin = {"lesson": "v1"}
cache = {}

def read_lesson(now):
    item = cache.get("lesson")
    if item is not None and now < item["expires_at"]:
        return f"HIT {item['value']}"

    value = origin["lesson"]
    cache["lesson"] = {
        "value": value,
        "expires_at": now + TTL,
    }
    return f"MISS {value}"

print(read_lesson(0))
print(read_lesson(2))
origin["lesson"] = "v2"
cache.pop("lesson", None)
print(read_lesson(3))
print(read_lesson(9))
```

Windows PowerShell에서는 py cache_demo.py, macOS·Linux에서는 python3 cache_demo.py를 실행하세요. 예상 결과는 다음과 같습니다.

```text
MISS v1
HIT v1
MISS v2
MISS v2
```

처음에는 캐시가 비어 누락되고 두 번째는 적중합니다. 원본을 v2로 바꾼 뒤 키를 지웠으므로 다시 누락됩니다. 시각 9에는 시각 3에 저장한 값의 TTL 5초가 지나 또 누락됩니다. 실제 단일 프로세스에서 경과 시간을 잴 때는 시스템 시각 변경의 영향을 받지 않는 time.monotonic()을 사용할 수 있습니다.

[흔한 실수]
모든 데이터에 같은 긴 TTL을 적용하거나 쓰기 뒤 키를 지우지 않으면 오래된 값이 보입니다. 사용자·언어·권한이 다른 응답을 같은 키에 저장하면 결과가 섞입니다. 누락 때 여러 요청이 동시에 원본으로 몰리는 캐시 스탬피드도 있으므로 짧은 잠금, 요청 합치기, TTL 분산을 상황에 맞게 검토하세요. 적중률과 함께 오래된 값의 발생도 측정합니다.

[보안 주의]
사용자별 데이터의 키에는 사용자나 테넌트 경계를 포함하고 권한 변경 시 즉시 무효화합니다. 비밀번호·토큰·민감한 전체 응답은 공유 캐시에 저장하지 않으며 HTTP 인증 응답의 캐시 지시자를 명확히 설정하세요. 외부 입력을 그대로 무제한 키로 만들지 말고 길이와 형식을 제한합니다. 캐시 장애 때도 권한 검사를 생략하지 말고 본인 소유의 로컬 메모리에서만 실습합니다.

[직접 해볼 과제]
origin에 profile과 notice를 추가하고 각각 TTL 2초와 10초를 적용하세요. 시각 0, 3, 11의 결과를 표로 기록하고, profile 변경 직후 그 키만 삭제했을 때 notice 캐시가 유지되는지 확인하세요.

[확인문제]
1. 캐시 적중과 누락은 각각 어떤 상태인가요?
2. TTL 만료와 메모리 축출은 어떻게 다른가요?
3. 원본 데이터를 바꾼 직후 관련 캐시 키를 삭제하는 이유는 무엇인가요?

[다음 학습]
DB-008에서 관계형 데이터베이스 대신 NoSQL을 선택하는 조건과 판단 기준을 배웁니다.

[공식 참고 자료]
HTTP 캐싱 표준 RFC 9111
https://www.rfc-editor.org/rfc/rfc9111

Redis EXPIRE 명령
https://redis.io/docs/latest/commands/expire/

Redis 키 축출 안내
https://redis.io/docs/latest/develop/reference/eviction/

Python 단조 시계
https://docs.python.org/3/library/time.html#time.monotonic

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
2,298
어제
5,103
최대
16,772
전체
773,352
Copyright © 소유하신 도메인. All rights reserved.