ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 카페인 캐시 키 재사용
    카테고리 없음 2020. 8. 17. 02:42

    질문

    카페인 을 사용하여 캐시 를 구현했습니다. 1 day후에 만료되기를 원하며 정상적으로 작동합니다. 문제는 수정 된 쿼리 (매개 변수 값으로 수정 됨)를 사용하여 캐시 에서 데이터를 가져 오려고하면 항상 동일한 결과를 얻는다는 것입니다. 동일한 매개 변수 값 (예 : 동일한 날짜 범위)으로 쿼리를 실행 한 경우에만 동일한 결과를 얻고 싶습니다. 내 이해는 동일한 cache-key 를 재사용해서는 안된다는 것입니다.하지만 어떻게하지 않는지 잘 모르겠습니다.이것이 구현입니다.

    @Service
    public class SomeServiceImpl implements SomeService {
      private static final String CACHE_KEY = "some-key";
      private Cache<String, List<SomeVO>> someCache;
    
    
    
      public RecentHighestSlotWinsServiceImpl() {
    
        someCache= Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.DAYS).build();
      }
    
      @Override
      public List<SomeVO> checkCacheForData(Instant startDate, Instant endDate) {
    
      List<SomeVO> someList= someCache.getIfPresent(CACHE_KEY);
      if (someList!= null) {
          return someList;
      } else {
          log.info("Loading from DB ");
          List<SomeVO> templateResult= getData(startDate, endDate);
          if (templateResult.isSuccessAndNotNull()) {
              someCache.put(CACHE_KEY, Objects.requireNonNull(templateResult.getData()));
          }
          return templateResult;
      }
    }

    답변1

    이를 처리하는 몇 가지 방법 :

    1. @Louis Wasserman이 언급했듯이 다음과 같이하십시오.
    import java.time.Instant;
    import java.util.Objects;
    
    public class CacheKey {
      private Instant startDate;
      private Instant endDate;
    
      public CacheKey() {
      }
    
      public CacheKey(Instant startDate, Instant endDate) {
        this.startDate = startDate;
        this.endDate = endDate;
      }
    
      public Instant getStartDate() {
        return startDate;
      }
    
      public void setStartDate(Instant startDate) {
        this.startDate = startDate;
      }
    
      public Instant getEndDate() {
        return endDate;
      }
    
      public void setEndDate(Instant endDate) {
        this.endDate = endDate;
      }
    
      @Override
      public boolean equals(Object o) {
        if (this == o)
          return true;
        if (o == null || getClass() != o.getClass())
          return false;
        CacheKey cacheKey = (CacheKey) o;
        return Objects.equals(startDate, cacheKey.startDate) &&
            Objects.equals(endDate, cacheKey.endDate);
      }
    
      @Override
      public int hashCode() {
        return Objects.hash(startDate, endDate);
      }
    }

    귀하의 방법 checkCacheForData 에서 다음을 사용하십시오.

    @Service
    public class SomeServiceImpl implements SomeService {
      private Cache<CacheKey, List<SomeVO>> someCache;
    
    
    
      public RecentHighestSlotWinsServiceImpl() {
    
        someCache= Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.DAYS).build();
      }
    
      @Override
      public List<SomeVO> checkCacheForData(Instant startDate, Instant endDate) {
    
      List<SomeVO> someList= someCache.getIfPresent(new CacheKey(startDate,endDate));
      if (someList!= null) {
          return someList;
      } else {
          log.info("Loading from DB ");
          List<SomeVO> templateResult= getData(startDate, endDate);
          if (templateResult.isSuccessAndNotNull()) {
              someCache.put(new CacheKey(startDate,endDate), Objects.requireNonNull(templateResult.getData()));
          }
          return templateResult;
      }
    }
    1. 별도의 객체를 갖는 대신 시작 날짜와 종료 날짜의 문자열 표현을 연결하여 캐시 키로 사용할 수 있습니다.
    @Service
    public class SomeServiceImpl implements SomeService {
      private Cache<String, List<SomeVO>> someCache;
    
    
    
      public RecentHighestSlotWinsServiceImpl() {
    
        someCache= Caffeine.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.DAYS).build();
      }
    
      @Override
      public List<SomeVO> checkCacheForData(Instant startDate, Instant endDate) {
    
    String cacheKey = startDate.toString() + endDate.toString();
      List<SomeVO> someList= someCache.getIfPresent(cacheKey);
      if (someList!= null) {
          return someList;
      } else {
          log.info("Loading from DB ");
          List<SomeVO> templateResult= getData(startDate, endDate);
          if (templateResult.isSuccessAndNotNull()) {
              someCache.put(cacheKey, Objects.requireNonNull(templateResult.getData()));
          }
          return templateResult;
      }
    }


     

     

     

     

    출처 : https://stackoverflow.com/questions/62682661/reuse-caffeine-cache-key

    댓글

Designed by Tistory.