캐싱 전략
1) 캐시 및 수행 위치
캐시는 대기 시간과 고가의 리소스 (CPU/DB/외부 API) 에 대한로드를 줄이는 빠른 메모리 레이어입니다. 중요한 목표:- 속도 (p95/p99 더 낮음), 비용 (탈출/CPU 감소), 안정성 (피크 아래의 종속성 감소).
- "시끄러운 이웃" 으로부터의 피크 스무딩 및 격리.
1. 클라이언트 (브라우저/모바일) -TP 캐시, IndexedDB, 로컬 스토리지.
2. 가장자리/CDN-POP 노드는 사용자, 캐시 정적 및 API의 일부에 더 가깝습니다.
3. L7- 게이트웨이/리버스 프록시-Nginx/Envoy/Varnish (microcash, SWR).
4. 서비스 캐시 - 클러스터 내에서 Redis/Memcashed.
5. 프로세스 중-메모리 내 (Caffeine/Guava/LRU-맵).
6. 데이터베이스의 캐시-재료 표현, 보조 색인.
규칙: 가능한 한 소비자와 가깝게 캐시하지만 진실을 한 번 유지하십시오.
2) 캐시 패턴
2. 캐시 제외 1 개 ("게으른로드")
응용 프로그램은 먼저 캐시에서 읽습니다. 소스에서 누락 된 경우 캐시에 기록하십시오.
장점: 단순성, 제어. 단점: 콜드 스타트, 불일치 창.
2. 2 읽기
읽기는 항상 캐시를 통해 이루어지며 캐시 자체가 누락되면 소스로 이동합니다 (라이브러리/프록시 레이어).
TTL/직렬화 정책을 중앙 집중화하는 것이 편리합니다.
2. 3 쓰기/쓰기 백 (쓰기 뒤에)
쓰기: 캐시에 기록하고 동기식으로 → 일관성을 높이고 대기 시간을 높입니다.
쓰기 백: 캐시에 쓰기, 소스 → 빠르게 소싱하기 위해 비동기식 플래시 쓰기, 손실 및 충돌 위험.
2. 4 새로 고침 (사전 예방)
"TTL이 곧 만료 될 것" 으로 예측하고 백그라운드의 키를 업데이트하여 각인을 방지합니다.
2. 5 네거티브 캐싱
"데이터 없음/404/빈" 을 짧은 TTL로 캐싱하면 소스의로드가 줄어 듭니다.
2. 6 마이크로 캐싱
매우 짧은 TTL (0. "거의 역학" (목록, 메인) 에 대한 L7의 5-5 초) -꼬리를 크게 줄입니다.
3) STP 캐시: 헤더 및 제어
3. 1 기본 제목
'Cache-Control': 'max-age', 's-maxage' (
검사기: 'ETag' (컨텐츠 해시), 'Last-Modified'.
조건이있는 쿼리: 'If-None-match', 'If-Modified-Since' → 304 수정되지 않음.
3. Vary 및 키 2 개
'Vary: 수락 인코딩, 승인, 쿠키, 수락 언어' -다른 캐시 옵션을 생성합니다. 카디널리티를 "폭발" 시키지 않도록 '바리' 를 최소화하십시오.
3. 3 STP 응답 예
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=60
ETag: "a1b2c3"
Vary: Accept-Encoding
4) 키 디자인 및 TTL
4. 키 1 개
구조: '테넌트: 사용자: {id}: 프로필: v3' (스키마 버전 포함).
키에서 PII를 피하십시오.
컬렉션의 경우-키 + 쿼리 매개 변수 (정규화 및 정렬).
4. TTL과 일관성 2 개
짧은 TTL은 불일치를 줄이지 만 미스를 증가시킵니다.
중요한 데이터의 경우 유효성 검사기 ('ETag') 및 SWR (부실한 동안).
장애의 긴 TTL + "폭탄" 은 거의 변하지 않습니다.
4. 3 Versioning/basting
호환되지 않는 변경의 경우 접두사/키 버전 ('v2 → v3') 을 변경하십시오.
정적 리소스의 경우-파일 이름의 컨텐츠 해시.
5) 장애: 전략 및 관행
5. 1 직접 삭제
프록시의 'DEL key '/' PURGE'. 위험: 제거와 여러 리더 간의 레이스.
5. 대리 키 2 개
문서를 태그 세트 (범주/저자) 와 연결하십시오. 장애-태그 별.
Varnish/Edge- 'Surrogate-Key: 기사: 42 태그: 저자: 7' + 'BAN 태그: 저자: 7'.
5. 3 이벤트 중심 장애
펍/서브 (Kafka/NATS): 소스가 변경되면 "무효화" 이벤트를 게시합니다.
캐시 소비자는 키를 듣고 삭제/업데이트합니다
5. 4 2 단계
먼저, 키를 쓸모 없게 표시하고 (소프트 TTL) 오래된 서비스를 제공하고 백그라운드에서 업데이트하고 원자 적으로 교체합니다.
6) 스탬피드/도그 파일 및 핫 키 다루기
6. 1 요청 합병 (단일 비행)
한 생산자가 키를 업데이트하고 나머지는 결과를 기다리고 있습니다 (뮤텍스/라벨 "업데이트").
6. 지터 2 TTL
동기식 팽창을 피하기 위해 TTL에 임의성 (λ10-20%) 을 추가하십시오.
6. 3 소프트 -TTL + 하드 TTL
소프트 TTL 이전에는 새로 고침 트리거와 병행하여 캐시에서 서비스를 제공합니다. hard-TTL에 의해-우리는 미스를 고려합니다.
6. 핫 키 4 개
공유 된 로컬 캐시 (2 계층).
여러 파편 및 임의의 선택에 대한 핫 키 복제 (읽기 전용).
특정 키 업데이트에 대한 속도 제한.
6. 5 Redis + Lua의 예 (단일 비행 스케치)
lua
-- SETNX lock with TTL to avoid deadlocks local ok = redis. call("SET", KEYS[1], "1", "NX", "EX", ARGV[1])
if ok then return "LOCKED"
else return "WAIT"
end
7) 선점 정책 및 캐시 수신
7. 1 퇴거
LRU: 단순하고 지역에 좋습니다.
LFU: "오래 지속되는" 핫 키에 더 좋습니다.
ARC/TinyLFU: 최근/주파수 균형.
7. 2 입학
거대한 희귀 물체 (TinyLFU/Bloom 필터) 를 넣지 마십시오.
크기/대기 시간 경계에서 큰 값 (LZ4/Zstd) 의 압축.
8) 차딩 및 토폴로지
8. 일관된 해싱 1 개
키를 노드에 안정적으로 분배하여 클러스터 성장/압축 중 이동을 줄입니다.
8. 2 Redis/Memached 토폴로지
Redis Cluster (슬롯/파편), Sentinel (feilover), 읽기 전용 복제.
Memcashed는 서버 수준의 복제가없는 클라이언트 측 샤딩 (케타마 해싱) 입니다.
8. 3 로컬 + 분산
캐스케이드: in-proc (micro-TTL/LRU) → Redis (TTL 더 긴) → 소스.
TTL 콜론 및 캐시 유효성 검사기에주의하십시오.
9) 가장자리, CDN과 L7 캐시
9. 1 마이크로 캐시 неNginx
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:100m inactive=10m;
map $request_method $skip_cache { default 0; POST 1; PUT 1; DELETE 1; }
server {
location /api/list {
if ($skip_cache) { add_header Cache-Control "no-store"; }
proxy_cache api;
proxy_cache_valid 200 2s; # micro-cache proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on; # SWR add_header X-Cache $upstream_cache_status;
proxy_pass http://upstream;
}
}
9. 2 특사 (SWR 및 조건)
yaml http_filters:
- name: envoy. filters. http. cache typed_config:
"@type": type. googleapis. com/envoy. extensions. filters. http. cache. v3. CacheConfig typed_config:
"@type": type. googleapis. com/envoy. extensions. http. cache. file_system_http_cache. v3. FileSystemHttpCacheConfig cache_path: "/var/cache/envoy"
9. 3 바니시 (대리 키)
배치 장애를 위해 태그에 'Surrogate-Key' 및 'ban' 을 사용하십시오.
10) 캐시 및 데이터 일관성
10. 1 쓰기 읽기
사용자 프로필/재활용 빈의 경우 짧은 TTL, 쓰기 또는 클라이언트 마킹 (쓰기 후 N 초 동안 우회) 을 제공하십시오.
10. 2 최종 vs 강한
권장/분석-최종 + 긴 TTL.
돈/주문 상태-짧은 TTL, 검증, 때로는 중요한 경로에 캐시가없는 경우.
10. 불변량 3 개
엄격한 TTL과 재확인없이 보안/ACL에 영향을 미치는 필드를 캐시하지 마십시오.
11) 관찰 가능성, SLO 및 관리
11. 1 메트릭
(PHP 3 = 3.0.6, PHP 4)
(PHP 3 = 3.0.6, PHP 4)
대기 시간: 캐시 대 소스에서 p50/p95/p99.
hot _ keys _ topN 및 QPS/바이트.
11. 2 개의 통나무와 흔적
로그 'X-Cache: HIT/MISS/STALE/UPDATING'.
추적에서 응답 소스 ('cash = 참', 'tier = edge' 서비스 '로컬') 를 표시하십시오.
11. 3 SLO 접근 방식
예: "API/카탈로그 p99 요청의 1%. "
11. 런북 4 개
"미스 성장" → TTL, 워밍업/장애, 핫키, 캐시 크기 및 수락 정책을 확인하십시오.
12) 안전 및 다중 임대
키에 테넌트 ID가 포함되어 있습니다 (HTTP의 경우 'Vary').
개인 응답을 '공개' 로 캐시하지 마십시오.
민감한 데이터가 포함 된 암호화 캐시 또는 비 PII/ID 만 저장합니다.
13) 전형적인 요리법
13. 카탈로그/테이프 1 개 (거의 동적)
Edge-microcash 1-3 s + SWR 내부-15-60 초 동안 Redis, 업데이트 이벤트에 의한 장애.
13. 2 사용자 프로필
TTL 30-120 s를 사용한 캐시 제외, 프로파일 업데이트 후 5-10 초 우회 (쿠키/헤더) 또는 쓰기.
13. 3 통화 과정/참고 도서
새로운 데이터가 게시 될 때 긴 TTL (분 시간) + 대상 장애; 조건부 GET를위한 'ETag'.
13. 검색 결과 4 개
Edge-microcash 1-2 초, 내부-새로 고침 및 통합, 키의 쿼리 매개 변수의 정규화.
14) 반 패턴
장애가없는 현금: TTL → 긴 부적합한 창에만 희망하십시오.
거대한 'Vary': 옵션의 "폭발" → 낮은 적중률.
prod/실험을위한 단일 캐시 → 오염.
TTL이 만료되면 스탬피드 → 소스 스파이크에 대한 보호 기능이 없습니다.
엄격한 보증없이 현금/권리/ACL 캐시.
"연속적인 모든 것" 의 압축-추가 CPU, 작은 물체의 p99 악화.
15) 구현 점검표
- 캐시 레벨과 대상 (에지/서비스/로컬) 을 정의하십시오.
- 디자인 키 (버전, 테넌트, 매개 변수 정규화).
- 패턴을 선택하십시오 (캐시 제외/읽기/새로 고침).
- TTL/soft-TTL/jitter 설정, SWR 활성화
- 통합/단일 비행, 스탬프 보호 구현.
- 장애 조직 (이벤트, 태그, 퍼지/금지).
- 히트 비율/대기 시간 지표 및 'X-Cache' 대시 보드를 입력하십시오.
- 핫키 부하 테스트를 수행하십시오.
- SLO 및 런북을 작성하십시오.
- 보안/테넌트 격리 및 'Vary' 를 확인하십시오.
16) FAQ
Q: 무엇을 선택해야합니까?
A: 간단한 서비스의 경우-캐시 제외. 중앙 집중화와 단일 정책-읽기가 필요합니다.
Q: 최적의 TTL을 이해하는 방법?
A: 허용되는 노후화, 업데이트 빈도 및 대상 적중률에서 시작합니다. 지터를 추가하고 p95/p99/비용을 관찰하십시오.
Q: 쓰기는 언제 적절합니까?
A: 최종 일관성이 허용되고 "추가" 에 대한 안정적인 큐/로그가있는 고 부하 스트림의 경우.
Q: 승인 된 응답을 캐시 할 수 있습니까?
A: 예, '비공개' 및/또는 'Vary' 스위치에 세입자/사용자를 표시하십시오. 진정한 개인-클라이언트 캐시.
Q: 캐시를 예열하는 방법?
A: 인기있는 키, 배경 벌레, 로그에서 재생, 릴리스/피크 전에 예열 (검은 금요일 등) 목록.
17) 총계
효과적인 캐싱은 핵심 설계 + 합리적인 TTL + 이벤트 장애, SWR/새로 고침 및 각인 방지에 의해 강화 된 잘 선택된 패턴입니다. 캐시 (클라이언트/에지/서비스) 를 계층화하고 관찰 가능성과 SLO를 추가하며 안정적인 대기 시간 테일, 예측 가능한 비용 및 최대 복원력을 얻습니다.