1. 캐시는 무적이 아니다.
비용을 고려한 최적화 순서
1순위: Network I/O 최적화 ├─ RTT 횟수 최소화 (배치 처리) ├─ 연결 재사용 (Connection Pooling) └─ 캐싱 (자주 쓰는 데이터) 2순위: Disk I/O 최적화 ├─ 순차 접근 설계 ├─ 인덱싱 └─ 캐싱 (핫 데이터) 3순위: 메모리 관리 ├─ 메모리 누수 제거 ├─ GC 튜닝 └─ 캐시 전략 4순위: CPU 최적화 ├─ 알고리즘 개선 ├─ 불필요한 연산 제거 └─ 병렬화 (마지막 수단)→ 그렇다면,
원본 링크cache가 과연 최고의 방법일까요? Cache가 최고의 방법일까
이렇게 순서를 정의했었다. 그리고 해당 문서의 전반적인 내용을 살펴보면, 다음과 같은 주장임을 알 수 있다.
Caching : memory 자원을 사용하는 행위.
- 이를 통해
Network와Disk I/O의 한계를 극복할 수 있음.
그러나 이 부분에서 다음과 같은 의문이 생긴다.
Cache Miss가 빈번하면,최적화 순서는 최적화를 보장할 수 있을까?- 캐시를 무한정 늘리면 모든
Network및Disk IO문제를 해결할 수 있지 않나?
Cache Miss 가 빈번하면 최적화 순서는 최적화를 보장하지 못한다.
-
cache hit시 비용- 로컬 캐시 :
Memory IO회 - 글로벌 캐시(Redis) :
Network IO+Memory IO
- 로컬 캐시 :
-
cache miss시 비용memory io(miss)+network io(db access)+disk io+memory io(cache update)
→ 오히려 비용이 증가.
이러한 문제가 발생할 수 있는 상황
- Random Access 패턴: 데이터가 불규칙하게 요청되어 캐시 히트율이 0%에 수렴할 때.
- Write-Heavy 시스템: 읽기보다 쓰기가 압도적으로 많아 캐시를 계속 비워야(Purge) 할 때
캐시를 무한히 늘릴 수 없다.
- 탐색 시간의 증가
- CPU가 탐색을 해야하는 범위가 넓어질 수록
CPU Cycle자체가 증가. → 연산 시간 증가 - 이 때문에
CPU내부의L1L2L3캐시가 용량이 작고, 계층화되어 관리됨.
- CPU가 탐색을 해야하는 범위가 넓어질 수록
- 데이터 일관성 유지 비용
cache miss발생 시cache를 업데이트 하여 일관성을 유지해야 함.(혹은 무효화)- 데이터 수정이 빈번하거나 사용자가 많으면 일관성을 유지하기 위한 비용 증가
cpu연산 +network io(redis의 경우)
- 데이터 수정이 빈번하거나 사용자가 많으면 일관성을 유지하기 위한 비용 증가
GC의 한계 → GC의 한계
결론
Cache : I/O 의 한계를 완전히 제거하지는 못함.
이상적인 최적화 : network io 를 최적화하기 위해서 요청 자체를 줄이거나, 데이터의 배치를 최적화하여야 함.
MSA에서 Cache
가정
DB 의 부하를 줄이기 위해 로컬 캐시와 글로벌 캐시를 함께 사용하고 있다. 이 때 특정 데이터가 업데이트 되는 순간, 모든 서버의 로컬 캐시 상태를 맞추기 위한 분삭 Lock 과 합의 알고리즘을 위해 CPU 사이클 이 과도하게 올라갔다. 이 상황에서 응답 속도와 데이터의 정확성 중 무엇을 우선 시 할 것인가?
→ CAP 정리(Consistency, Availability, Partition Tolerance)
Answer
→ Domain 에 따라 다르다.
모든 정보가 100% 정확하지 않아도 된다면, 최종 일관성(Eventual Consistency) 를 선택.
- 100% 정확해야 하는 경우 : 증권사, 은행 등
그렇지 않을 경우.
- 모든
cpu자원이합의 알고리즘을 처리하는 데 집중을 하게 됨.network latency발생 시 모든thread가blocking이 되고, 전체throughput이 급감.
대안책 : 성능과 최종 일관성을 유지하는 방법
Message Pub/SubCache TTL 설정- 도메인 분리
- 강한 일관성을 요구하는 구간은 캐시 사용 X. | 그 외 부분은 최종 일관성임을 인지하고, 캐시를 쓰되 오차를 허용