Git :)

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Caffeine Cache 적용기
    Java 2024. 7. 3. 22:24

    Caffeine Cache 적용 방법

     - 왜 사용할까?

    • 자주 빈번하게 조회되는 데이터를 DB에 접근하여 가져오게 되면 DB의 리소스가 낭비가 될 확률이 높다.
    • 그래서 자주 그리고 변경이 적은 데이터를 DB에서 계속 접근하여 가져오는 것이 아니라 캐시와 같은 저장소에 저장해두고 사용하여 성능의 이점을 위해 사용한다.

     

    1. Dependency

    implementation group: 'com.github.ben-manes.caffeine', name: 'caffeine', version: '3.1.8'

    2. 캐시 사용하기

     - 3가지 전략

    • Manual Populating
      • 캐시에 수동으로 데이터를 적재하고, 사용하는 방법
      • 결과 ==> Person{name='테스트', age=33, weight='76kg', height='173cm'}
    public class CaffeineCacheApplication {
    
        private static Cache<String, Person> cache = Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .maximumSize(100)
                .build();
    
        public static void main(String[] args) {
    
            Person person = new Person() ;
            cache.put("person1", person) ;
    
            printCache() ;
    
        }
    
        private static void printCache() {
            Person dataObject1 = cache.getIfPresent("person1") ;
    
           System.out.println(dataObject1) ;
    
            Person dataObject2 = cache
                    .get("person2", k -> new Person("테스트2", 25, "75", "180"));
    
            System.out.println(dataObject2) ;
            System.out.println(cache.getIfPresent("person2")) ;
            
        }
    }

     

     

    결과값 ==>

    Person{name='테스트', age=33, weight='76kg', height='173cm'}
    Person{name='테스트2', age=25, weight='75', height='180'}
    Person{name='테스트2', age=25, weight='75', height='180'}

     

    • Synchronous Loading
      • 캐시를 로드하는 이 방법은 수동 전략의 Get 방식과 유사하다.
      • 샘플코드는 아래와 같다.
    private static void synchronousLoading() {
        LoadingCache<String, Person> synchronousLoadingCache = Caffeine.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(1, TimeUnit.MINUTES)
                .build(k -> new Person()) ;
    
        Person dataObject = synchronousLoadingCache.get("person");
        System.out.println(dataObject) ;
    }

     

    • Asynchronous Loading
    • 이전 전략과 동일하게 작동하지만 작업을 비동기식으로 수행하고 실제 값을 보유하는 CompletableFuture를 반환한다.
    • 샘플코드는 아래와 같다.
    AsyncLoadingCache<String, DataObject> cache = Caffeine.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(1, TimeUnit.MINUTES)
            .buildAsync(k -> DataObject.get("Data for " + k));

     

     

    3. 캐시 삭제하기

    • Size-Based Eviction
      • 설정된 사이즈보다 많은 양이 추가되면 삭제가 발생한다.
      • 샘플코드는 아래와 같다.
    LoadingCache<String, DataObject> cache = Caffeine.newBuilder()
            .maximumSize(1)
            .build(k -> DataObject.get("Data for " + k));
    • Time-Based Eviction
      • 액세스 후 만료 - 마지막 읽기 또는 쓰기가 발생한 이후 기간이 지나면 항목이 만료된다.
      • Expire after write — 마지막 쓰기가 발생한 이후 기간이 지나면 항목이 만료된다.
      • 사용자 정의 정책 — Expiry 구현에 의해 각 항목에 대해 개별적으로 만료 시간이 계산된다.
      • 샘플코드는 아래와 같다.
    cache = Caffeine.newBuilder().expireAfter(new Expiry<String, DataObject>() {
        @Override
        public long expireAfterCreate(
                String key, DataObject value, long currentTime) {
            return value.getData().length() * 1000;
        }
        @Override
        public long expireAfterUpdate(
                String key, DataObject value, long currentTime, long currentDuration) {
            return currentDuration;
        }
        @Override
        public long expireAfterRead(
                String key, DataObject value, long currentTime, long currentDuration) {
            return currentDuration;
        }
    }).build(k -> DataObject.get("Data for " + k));