본문 바로가기
DB

Spring Boot에서 Redis를 기본적인 Cache(spring-boot-starter-cache)로 사용하기

by 공부 안하고 싶은 사람 2021. 8. 2.
반응형

의존성

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

Spring-boot-starter-web 혹은 spring-boot-starter-data-redis을 받으면

Spring-boot-starter-cache에 대한 의존성을 모두 포함하여 받을 수있다.

 

 

설정

spring.cache.type: redis
spring.redis:
    host: localhost
    port: 6379

 

 

캐시 사용

기본 사용은 ConcurrentMapCacheManager가 등록되며 인메모리 ConcurrentHashMap으로 캐시 역할을 수행하는 듯 보인다.

@Cacheable : 캐시 있으면 가져오고, 없으면 등록

@CachePut : 무조건 등록

// SpEl 문법 사용가능
@Cacheable(key = "#id",
           value = "post-single",
           unless = "#result.shares < 500")
//반환된 결과 중 shares값이 500 미만인 경우에만 캐시 적용

위 annotation이 있는 함수에서 (보통 파라미터로 전달된 것들을 key로 설정)

캐시에 키의 존재 유무에 따라 키값이 있다면, 저장된 value값을 반환한다. 없다면, 함수의 로직을 실행하고 value 저장

 

@CacheEvict

@CacheEvict(value = "post-single", key = "#id") @DeleteMapping("/delete/{id}")
// id로 저장된 캐시를 지우기

 

 

캐시사용 커스터마이징

CacheManager

@EnableCaching 주석 을 추가하여 Spring Boot는 기본 캐시 구성으로 RedisCacheManager 를 자동 구성합니다. 그러나 몇 가지 유용한 방법으로 캐시 관리자 초기화 전에 이 구성을 수정할 수 있습니다.

 

 

client 설정

두가지 client를 선택할 수 있지만, 디폴트인 Lettuce가 성능이 좋으므로 그대로 사용한다.

  1. Lettuce client(default) : Netty기반 비동기 클라이언트
  2. Jedis client : Jedis는 별도의 추가 설정이 필요함
dependencies {
  compile group: 'redis.clients', name: 'jedis'
  compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.6.2'
  compile ('org.springframework.boot:spring-boot-starter-data-redis') {
      exclude group: 'io.lettuce', module: 'lettuce-core'
  }
}    
@Configuration
@EnableCaching
public class RedisCacheConfig {
  @Autowired
  private ObjectMapper objectMapper;
  ///...

    //@Bean // Jedis
    public RedisConnectionFactory redisConnectionFactory() {{
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort());
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        //pool config 설정들 추가
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(config);
        jedisConnectionFactory.setPoolConfig(poolConfig);
        return jedisConnectionFactory;
    }

      @Bean // Lettuce
    public RedisConnectionFactory redisConnectionFactory() {
        LettuceClientConfiguration lettuceClientConfigurationBuilder = LettuceClientConfiguration.builder()
            .commandTimeout(Duration.ofMillis(TIMEOUT))
            .shutdownTimeout(Duration.ofMillis(TIMEOUT))
            .readFrom(ReadFrom.SLAVE_PREFERRED)
            .build();

        RedisStaticMasterReplicaConfiguration clusterConfiguration = new RedisStaticMasterReplicaConfiguration(MASTER_HOST, MASTER_PORT);
        clusterConfiguration.addNode(SLAVE1_HOST, SLAVE1_PORT);

        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(
            clusterConfiguration, lettuceClientConfigurationBuilder);
        lettuceConnectionFactory.setValidateConnection(false);

        return lettuceConnectionFactory;
    }

    @Bean
    public CacheManager orderCacheManager(
      @Qualifier("redisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            .disableCachingNullValues()
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)))
            .entryTtl(Duration.ofSeconds(DEFAULT_TTL_SECONDS));


        return RedisCacheManager.RedisCacheManagerBuilder
            .fromConnectionFactory(redisConnectionFactory)
            .cacheDefaults(redisCacheConfiguration)
            .build();
    }


    @Bean
    public RedisTemplate<String, Object> redisTemplate(
      @Qualifier("redisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
        RedisSerializer<?> genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
        RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(stringRedisSerializer);
        return redisTemplate;
    }
}
  1. Redis Client 커스터마이징
  2. CacheManager 커스터마이징 -> 스프링 cache로 사용하기 위함
  3. Redis 변환 커스터마이징

 

 

적용

@Cacheable(key = "T(java.lang.String).format('%s', #ano)",
        value = "ORDER:getItem",
        cacheManager = "orderManager"
    )
//orderManager에서 String, getItem을 등록

 

 

인라인

@Autowired CacheManager cacheManager;
...
    cacheManager.getCache("common-classes").evict("academies:" + academyId + ":classes");
...
728x90
반응형

'DB' 카테고리의 다른 글

REDIS  (0) 2021.03.20
MsSQL Shrink  (0) 2021.02.25
NoSQL  (0) 2021.02.03

댓글