조회 성능을 위해서 cache를 써야한다
먼저 로컬에서 레디스 구동시켜서 연동을 확인하려고 한다
// 이미지 다운
docker pull redis
// 이미지 확인
docker images
// 컨테이너 올림
docker run --name test-redis -p 6379:6379 -d redis
// 올라간 컨테이너 확인
docker ps
implementation("org.springframework.boot:spring-boot-starter-data-redis")
// mac silicon only
val isMacOS: Boolean = System.getProperty("os.name").startsWith("Mac OS X")
val architecture = System.getProperty("os.arch").toLowerCase()
if (isMacOS && architecture == "aarch64") {
developmentOnly("io.netty:netty-resolver-dns-native-macos:4.1.68.Final:osx-aarch_64")
spring-boot-starter-data-redis 만 주입하고 실행했더니, 실행은 되지만 중간에 에러 로그들이 쌓였다.
찾아보니까, m1 인 경우에만 발생하는 로그들이였다.
(m1이 아니라면 아래 라인 의존성은 하지 않아도 된다.)
다른 글을 참고해서 io.netty:netty-resolver-dns-native-macos:4.1.82.Final:osx-aarch_64 을 m1 개발환경에서만 실행되게 했다. 참고한 글에 의하면 의존성이 포함되어있어도 배포시에는 문제가 없다고 한다.
참고
https://junho85.pe.kr/2054
https://github.com/netty/netty/issues/11020#issuecomment-1193280582
spring
redis
host: localhost
port: 6379
@Configuration
@EnableCaching
class RedisCacheConfig(
@Value("\${spring.redis.host}")
private val host: String,
@Value("\${spring.redis.port}")
private val port: Int
) {
@Bean
fun redisConnectionFactory(): RedisConnectionFactory = LettuceConnectionFactory(host, port)
@Bean
fun cacheManager(): CacheManager {
val objectMapper = ObjectMapper()
.registerModule(JavaTimeModule())
.activateDefaultTyping(BasicPolymorphicTypeValidator.builder()
.allowIfBaseType(Any::class.java).build(), ObjectMapper.DefaultTyping.EVERYTHING)
val redisCacheConfiguration: RedisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(GenericJackson2JsonRedisSerializer(objectMapper)))
.entryTtl(Duration.ofMinutes(3L))
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory())
.cacheDefaults(redisCacheConfiguration).build()
}
}
LettuceConnectionFactory Bean 등록cacheManager 에 serialize 설정을 원래는 다른 글들을 보고 아래처럼 했었다.
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(GenericJackson2JsonRedisSerializer()))
GenericJackson2JsonRedisSerializer 을 쓰게되면 @class 라는 프로퍼티가 redis 에 같이 적재된다고 했는데, 나는 없어서 자꾸 에러가 나는 것이다.
Exception while fetching data (/findNoticeOne) : Could not read JSON: Could not resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at
혹시 kotlin 이라서 그럴까..? 하고 구글링 해보니, 레퍼런스가 나왔다.
정확한 원인은 모르겠으나, kotlin의 serialze가 다른 부분이 있는 것 같다.
aop annotation으로 결과가 redis 에 캐싱되는걸 테스트 해봤다
원래 만들어둔 graphql method 에 아래 어노테이션을 사용했고, 같은 조회 쿼리를 2번 날렸을때 2번째에는 쿼리가 찍히지 않는 것을 확인했다 !!
@Cacheable(key = "#id", value = ["notice"])
redis-cli 통해서 데이터도 확인했는데, 불편하긴 하더라.
기능 구현할때 적절한 어노테이션을 사용해서 해봐야지.