반응형

Cache 전략

Cache Aside Pattern

  • 캐시를 옆에 두고 필요할 때만 데이터를 캐시에 로드하는 전략.
  • 애플리케이션은 캐시 데이터가 있는지 확인하고, 있으면 바로 캐시 데이터로 응답.
  • 캐시 데이터가 없으면 DB에서 조회하여 캐시에 저장한 후 응답. 이후 요청시 캐시 데이터로 응답.
  • 캐시 클러스터 장애가 발생해도 시스템 전체의 오류로 전파되지 않는다.
  • 캐시 미스 발생시 성능 저하가 발생할 수 있다.
  • 최신 데이터 동기화 문제가 발생할 수 있다.

Write Through Pattern

  • DB 데이터 변경 작업이 일어날 때마다 캐시 데이터를 갱신하는 전략.
  • 캐시 데이터를 항상 최신 상태로 유지할 수 있다.
  • 쓰지 않는 데이터도 캐시에 저장되기 때문에 리소스를 낭비할 수 있다.
  • 쓰기 작업이 빈번하게 발생할 경우 성능 저하가 발생할 수 있다.

예제

의존성 추가

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.properties

spring.redis.host=redis.example.com
spring.redis.port=6379

RedisCacheConfig

@EnableCaching
@Configuration
public class RedisCacheConfig {
    @Bean
    public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
            .disableCachingNullValues() // null value 캐시안함
            .disableKeyPrefix()
            .entryTtl(Duration.ofSeconds(10)); // 캐시의 유효시간 설정

        return RedisCacheManager.RedisCacheManagerBuilder
            .fromConnectionFactory(redisConnectionFactory)
            .cacheDefaults(defaultConfig)
            .withCacheConfiguration(CacheKey.USER, defaultConfig.entryTtl(Duration.ofMinutes(10)))
            .build();
    }
}

CacheKey

public interface CacheKey {
    String USER = "user";
}

User

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {
    private String id;
    private LocalDateTime searchTime;
}

UserService

@Slf4j
@Service
public class UserService {
    @Cacheable(value = CacheKey.USER, key="#id", unless = "#result.id == null")
    public User getUser(String id) {
        log.info("getUser id : {}", id);
        return new User(id, LocalDateTime.now());
    }

    @CachePut(value = CacheKey.USER, key = "#user.id")
    public User saveUser(User user) {
        // do save
        return user;
    }

    @CacheEvict(value = CacheKey.USER, key = "#id")
    public void deleteUser(String id) {
        // do delete
    }
}

참고

반응형

'Development > Spring' 카테고리의 다른 글

[Spring] AOP  (0) 2020.12.27
[Spring] Cookie & Session  (0) 2020.12.27
[Spring] Swagger  (0) 2020.12.27
[Spring] Argument Resolver  (0) 2020.12.27
[Spring] Filter & Interceptor  (0) 2020.12.27

+ Recent posts