Look-Aside
- 캐시에서 데이터를 먼저 찾고, 없으면 DB에서 찾는다.
- DB 에서 찾은 데이터를 캐시에 삽입하는 과정도 수행된다.
하는 경우, 캐시된 데이터가 만료되는 경우 어플은 DB에 접근하여 데이터를 가져와서 캐시에 다시 저장한다.
여러 어플이 동시에 특정 키가 만료되었음을 인지하는 경우, 동시에 DB에 접근하여 데이터를 가져오려고 시도한다.
→ DB 과부하가 발생함.
적절한 만료 시간 설정
선 계산
확률적 접근
import java.util.Random;
public class Cache {
private static final int BASE_EXPIRATION_TIME = 300; // 기본 만료 시간 (초)
private static final int RANDOMIZATION_RANGE = 60; // 랜덤화 범위 (초)
private Random random = new Random();
public int getExpirationTime() {
return BASE_EXPIRATION_TIME + random.nextInt(RANDOMIZATION_RANGE);
}
}
PER 알고리즘
import java.util.Random;
public class Cache {
private static final int EXPIRATION_TIME = 300; // 기본 만료 시간 (초)
private static final double RECOMPUTE_PROBABILITY = 0.1; // 재계산 확률
private long lastUpdateTime;
private Random random = new Random();
public Cache() {
this.lastUpdateTime = System.currentTimeMillis();
}
public boolean shouldRecompute() {
long currentTime = System.currentTimeMillis();
long elapsedTime = (currentTime - lastUpdateTime) / 1000; // 경과 시간 (초)
if (elapsedTime >= EXPIRATION_TIME) {
return true; // 만료 시간 경과
}
double probability = RECOMPUTE_PROBABILITY * (elapsedTime / (double) EXPIRATION_TIME);
return random.nextDouble() < probability;
}
public void updateCache() {
// 캐시 갱신 로직
this.lastUpdateTime = System.currentTimeMillis();
}
}
randValue
: 0 과 1 사이의 랜덤값을 설정BETA
: 조정 가능한 상수로, 로그 값에 곱해주는 값이다.ttl - (BETA * Math.log(randValue) * EXPIRY_GAP)