:
그냥 (!) 참고 : 만료 및 퇴거를 혼동하지 마십시오. 만료는 항목이 캐시에 의해 더 이상 반환되지 않을 수 있으며 지정된 시점 또는 기간 후에 발생할 수 있음을 의미합니다. 축출은 자원을 비우기위한 조치이며, 항목은 캐시에서 제거됩니다. 만료 후 동시에 또는 나중에 퇴거가 발생할 수 있습니다.
모든 일반적인 캐시 제품은 일명 "특정 시점"만료를 지원하지 않습니다. 우리는 우리의 응용 프로그램에서 자주 사용법을 필요로하므로 이것을 지원하기 위해 cache2k과 약간의 노력을했습니다. 당신이 메트릭 객체의 시간 기준이있는 경우
static class MetricsEntry {
long nextUpdate;
List<Metrics> metrics;
}
static class MyEntryExpiryCalculator implements EntryExpiryCalculator<Integer, MetricsEntry> {
@Override
public long calculateExpiryTime(Integer _key, MetricsEntry _value, long _fetchTime, CacheEntry _oldEntry) {
return _value.nextUpdate;
}
}
Cache createTheCache() {
Cache<Integer, MetricsEntry> cache =
CacheBuilder.newCache(Integer.class, MetricsEntry.class)
.sharpExpiry(true)
.entryExpiryCalculator(new MyEntryExpiryCalculator())
.source(new MySource())
.build();
return cache;
}
, 당신은 그것을 사용할 수 있습니다 및 추가 항목 클래스를 생략 할 수 있습니다 : 여기
는 cache2k의 청사진이다.
sharpExpiry(true)
은 cache2k에 정확한 만기를 지시합니다. 이 값을 지정하지 않으면 만료 시간이 수 밀리 초이지만 액세스 시간은 약간 더 빠릅니다. 주제 2에 관한
:
직선 앞으로 접근 방식은 캐시 키와 간격 분을 사용하는 것입니다. 당신이 요청을 할 경우 05 :
static class MySource implements CacheSource<Integer, MetricsEntry> {
@Override
public MetricsEntry get(Integer interval) {
MetricsEntry e = new MetricsEntry();
boolean crossedIntervalEnd;
do {
long now = System.currentTimeMillis();
long intervalMillis = interval * 1000 * 60;
long startOfInterval = now % (intervalMillis);
e.metrics = calculateMetrics(startOfInterval, interval);
e.nextUpdate = startOfInterval + intervalMillis;
now = System.currentTimeMillis();
crossedIntervalEnd = now >= e.nextUpdate;
} while (crossedIntervalEnd);
return e;
}
}
(10)에 대한 메트릭을 반환 : 00-10 여기
엄격하게 이전 구간의 통계를 반환 (캐시 로더 일명) 캐시 소스 10:07라고 말하십시오.
방금 즉시 과거 간격의 측정을 계산하려면
는, 그것은 간단하다 :
static class MySource implements CacheSource<Integer, MetricsEntry> {
@Override
public MetricsEntry get(Integer interval) {
MetricsEntry e = new MetricsEntry();
long intervalMillis = interval * 1000 * 60;
long startOfInterval = System.currentTimeMillis();
e.metrics = calculateMetrics(startOfInterval, interval);
e.nextUpdate = startOfInterval + intervalMillis;
return e;
}
}
캐시 소스의 사용은 put()
을 통해 장점이있다. cache2k가 블로킹 중이므로 하나의 메트릭에 대해 여러 요청이 들어 오면 하나의 메트릭 계산 만 시작됩니다.
밀리 초에 대한 정확한 만료가 필요하지 않으면 다른 캐시도 사용할 수 있습니다. 캐시 값 내에 메트릭을 계산하는 데 걸리는 시간을 저장 한 다음 이에 따라 만료 시간을 수정해야합니다.
좋은 점이 있습니다!
그런데 주기적으로 이전 항목을 제거하는 스레드를 작성해야합니다. 상자 밖으로 벗어나는 상자를 사용하는 것이 전체 캐시를 피하는 것이 아닌가? 이 문제에 키/값 측면이 없다는 것이 맞습니다. 방금 키로 해시 코드를 사용했기 때문에 대기열을 기반으로하는 시간을 찾을 수 없었습니다. –
새 항목을 추가하거나 항목을 읽는 방법 중 하나가 호출되었을 때 만료 된 항목을 삭제할 수 없습니까? 이것이 본질적으로 '캐시 (Cache)'가하는 것입니다 : 모든 쓰기 (어쨌든 쓰여지는 세그먼트의 경우) 및 가끔 읽는 경우 제거 된 항목을 제거합니다. – ColinD
@Rohitchauhan 캐시에서 제거하는 것은 캐싱에 "작은 추가 기능"일 뿐이며 효율적으로 구현할 수는 없습니다. 요점은 캐싱입니다. 키가 부족하다는 것은 캐시를 사용할 이유가 없다는 것을 의미합니다. 먼저 30 분 캐시와 필터를 수동으로 사용하도록 제안하고 싶었지만 'Deque'또는 'PriorityQueue'가 훨씬 더 의미가있는 것처럼 보입니다. 퇴거를 추가하는 것은 사소한 일입니다. – maaartinus