Redis Cache 연동(Spring Boot)
학습 목표
Spring Boot와 Redis를 연동하여
Application에서 Caching하는 방법을 학습
Redis Setting
Redis는 사내에서 제공되는 Redis를 사용!
우선 dev용으로 셋팅!
SpringBoot + Redis Cache 연동
Gradle Dependency
// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
RedisTemplate과 RedisCacheManager가 있는데 Cache는 RedisCacheManager를 사용 합니다.
RedisCacheManager의 동작은 RedisCacheManagerBuilder를 사용하여 구성할 수 있으며, 이를 통해 기본 RedisCacheConfiguration, 트랜잭션 동작, 및 미리 정의된 캐시를 설정할 수 있습니다.
Spring cache추상화를 implement받아서 RedisCacheManager와 RedisCacheConfiguration을 구현해줍니다.
Class-Level Annotation (@CacheConfig) 방식도 가능하지만 RedisConfig로 구현하였습니다.
@Configuration
public class RedisConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 기본 캐시 설정
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)) // TTL 설정: 10분
.disableCachingNullValues() // Null 값 캐싱 비활성화
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) // 키 직렬화
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); // 값 직렬화
// RedisCacheManager 생성
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(defaultCacheConfig) // 기본 캐시 구성 적용
.build();
}
}
application.yml 설정
spring:
data:
redis:
host: test.redis.acet.com
port: 11038
password: helloworld!
위의 Redis정보는 Spring Boot가 시작될 때 application.yml에서 redis관련 설정들을 읽어들이고
이 설정들을 기반으로 RedisConnectionFactory Bean을 자동으로 생성 합니다.
이렇게 생성된 Bean은 아래소스처럼 RedisConfig Class에서 사용되며, Redis와의 연결을 설정하고
CacheMaanger로써 Redis를 사용할 수 있도록 구성합니다.
이제 Redis를 사용할 수 있도록 구성이 되었으니 Spring Cache 추상화 개념을 익히고 Caching작업을 합니다.
Spring Cache 추상화는 간단히 말해 Cache를 사용하는 작업을 단순화하는 도구 입니다.
Cache System의 구체적인 구현을 신경쓰지 않고 간단히 어노테이션만으로 Cache를 관리할 수 있습니다.
참고 : https://docs.spring.io/spring-framework/reference/integration/cache/annotations.html
아래는 Service의 Method이며, 아래의 메소드에 @Cacheable을 적용하였습니다.
@Cacheable(value = "redisTest", keyGenerator = "customKeyGenerator")
public ResponseData getResponseData(String q) throws IOException {
}
}
특징으로는 keyGenerator를 통해서 customKey를 만들어서 Cache Key로 사용했습니다.
CustomKeyGenerator Class는 KeyGenerator를 구현하였습니다.
저같은 경우는 쿼리에 대한 정규화 처리를 한 뒤 정렬 후 Hash값으로 만들어줬습니다.(SHA256)
generate method를 @Override해서 필요한 로직을 구현하시면 됩니다.
또한 값을 Hash값으로 만들어줬는데요
여러가지 토큰도 있으나 Hash값을 선택한 이유는
짧고 고정된 길이를 제공하여 메모리 사용이 예측가능하고 저장공간을 절약 할 수있어서 입니다.
토큰의 경우는 포함된 정보에 따라 길이가 길어질수 있고 결국 메모리 사용이 증가합니다.
또한 보안도 Hash값이 좋습니다:)
@Component
public class CustomKeyGenerator implements KeyGenerator {
private final Logger LOG = LoggerFactory.getLogger(CustomKeyGenerator.class);
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder cachingKey = new StringBuilder(target.getClass().getSimpleName() + "_"+ method.getName() + "_"); // 기본키
LOG.info("q="+params[0].toString());
String query = params[0].toString().replaceAll(" ","").replaceAll("'", "\"");
// String to char[]
char[] sortTargets = query.toCharArray();
Arrays.sort(sortTargets);
String sortedStr = String.valueOf(sortTargets);
LOG.debug("sorted = {}", sortedStr);
String hashValue = HashGenerator.generateSHA256Hash(sortedStr);
LOG.debug("hashValue = {}", hashValue);
cachingKey.append(hashValue);
LOG.info("cachingKey = {}", cachingKey);
return cachingKey.toString();
}
}
이제 잘 동작하는지 즉, Redis에 잘 저장되는지 확인이 필요합니다.
Redis 접속 툴
Jenbrain부터 많은 툴이 있었으며 대~충 무료인걸로 골랐습니다ㅋㅋ
AnotherRedisDesktopManager 사용
download : https://github.com/qishibo/AnotherRedisDesktopManager/releases
접속정보를 넣고 connection을 하면 아래와 같이 Redis 정보가 보입니다.
결과적으로 원하는 Key가 Redis의 key로 들어가있고 value에 응답값이 제대로 들어가있는지 확인하면 됩니다.
끝~