개요
데이터베이스의 시스템 확장은 어려운 점이 많기 때문에 부하를 최소화하여 확장 필요성을 줄이는 것이 바람직하다
이를 위한 기본적인 접근법은 조회 이전에 캐시를 먼저 확인하는 것이다
높은 캐시 히트율을 유지하면 데이터베이스 확장 없이도 상당한 트래픽을 처리할 수 있다
이 글에서는 대용량 트래픽 환경에서 캐시를 사용했을때에 대한 주의사항과 예방하는 방법을 설명한다
1. 캐시 쇄도 (Cache Stampede)
: 다량의 키 만료 등으로 캐시 미스가 동시에 많이 발생할 경우 데이터베이스에 부담이 가중되는 상황
: 정확히 같은 시간에 키를 만료되도록 구현하면 발생
- 해결 방법
: 캐시 만료 시간을 무작위로 약간씩 지연
: 전자공학의 Jitter 개념을 활용하여 0~10초 사이의 무작위 지연시간을 추가하여 DB로의 부담을 분산
: 서비스 마다 허용할 수 있는 지연 시간이 다르기 때문에 서비스에 맞게 지터 시간을 설정해야한다 (사용자가 더 오래된 정보를 볼 수 있기 때문)
2. 캐시 관통 (Cache Penetration)
: 데이터베이스에서 읽었음에도 캐싱 되지 않는 현상
: 불필요한 조회 요청이 자주 발생
: 이를 예방하기 위해 데이터가 없다는 것도 캐싱하여 데이터베이스 부하를 줄인다
- 해결 방법
: `값이 없음`을 캐싱하여 데이터베이스의 트래픽을 줄임
: 블룸 필터를 사용하면 확률적으로 캐시 관통을 방지할 수 있다
: 그러나 블룸 필터의 정합성이 깨지면 블룸 필터 복구를 위해 모든 캐시를 읽어야 해서 운영에 어려움이 따름
: 널 오브젝트 패턴을 통해 `값이 없음`을 캐싱하는 편이 더 낫다
: 원시 타입의 경우 이 객체를 대체할 특정 값을 지정해야함
3. 캐시 시스템 장애
: 평이한 트래픽 상황에서는 캐시 시스템에 장애가 발생하더라도 데이터베이스로 트래픽을 보내면 서비스를 정상 운영할 수 있다
: 하지만 트래픽이 큰 상황에는 캐시 시스템이 복구될 때까지 데이터베이스에 과부하가 발생한다
: 데이터베이스가 감당할 수 있는 범위의 트래픽을 유지하도록 계획을 세워야한다
- 해결안
: 핵심 기능을 정의하여 캐시 시스템이 망가져도 반드시 동작해야할 기능만 제외하고 나머지는 일시적으로 운영이 중단되도록 한다
: 캐시 시스템이 복구 되는 동안 데이터베이스가 핵심 기능에 의한 트래픽을 처리할 수 있도록 하고, 부가 기능에 대해서는 대체 UI를 제공하거나 양해를 구한다
4. 핫키 만료
: 많은 요청이 집중되는 키를 핫키라고 한다
: 핫키가 만료되는 순간 여러 요청이 동시에 데이터베이스를 불필요하게 반복해서 조회할 수 있다
: 가능하다면 캐시의 만료기한을 없에거나 백그라운드에서 주기적으로 새 값을 적용해서 캐시가 만료되지 않게 하는 것이 좋다
: 하지만 핫키가 때에 따라 바뀌는 환경에서는 핫키가 아닌 데이터로 인해 캐시 저장소 공간이 낭비될 수 있다
- 해결안
: 분산 락을 사용하여 공간 낭비 없이 불필요한 데이터베이스 중복 조회를 방지할 수 있다
: 멀티스레드 프로그래밍에서 공유 자원을 다룰때 락을 사용하는 것과 비슷한 원리
: 캐시를 애플리케이션 서버 간 공유 자원으로 보고 캐시 미스가 발생했을 때 락을 설정하고 캐싱한 후에 락을 해제함으로써 단 한 번의 작업만 허용
: 레디스를 사용하면 분산락을 적용하기 굉장히 쉽다. (레드락 알고리즘 덕분)
Reference
'Database > Database' 카테고리의 다른 글
DRBD (Distributed Replicated Block Device) (1) | 2024.02.17 |
---|---|
갈레라 클러스터 (Galera Cluster) (1) | 2024.02.17 |
개발 시 데이터베이스 선택 가이드 (0) | 2024.01.22 |
분류로 보는 DBMS (0) | 2023.11.07 |
레디스 VS 엘라스틱 서치 (Redis vs ElasticSearch) (0) | 2023.08.20 |