From 0574f4f6290ec365c2308e37ae3fc70cae1fa23c Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 14 Sep 2025 17:43:53 +0900 Subject: [PATCH] =?UTF-8?q?feat(cache):=20=EC=9D=B8=EA=B8=B0=20=EC=BA=90?= =?UTF-8?q?=EB=A6=AD=ED=84=B0=20=EC=A1=B0=ED=9A=8C=EC=97=90=20=EC=9C=88?= =?UTF-8?q?=EB=8F=84=EC=9A=B0=20=EA=B8=B0=EB=B0=98=20=EB=8F=99=EC=A0=81=20?= =?UTF-8?q?=EC=BA=90=EC=8B=9C=20=ED=82=A4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ChatCharacterService.getPopularCharacters()에 @Cacheable 추가 - 키: popular-chat-character:: - 윈도우(매일 20:00 UTC) 전환 시 자동으로 신규 키 사용 → 전일 순위 캐시와 분리 보장 Why: 동일 윈도우 내 반복 요청의 DB 부하를 줄이고, 경계 전환 시 자연스러운 캐시 갱신을 보장. --- .../chat/character/service/ChatCharacterService.kt | 5 +++++ .../kr/co/vividnext/sodalive/configs/RedisConfig.kt | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/service/ChatCharacterService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/service/ChatCharacterService.kt index e48bf21..ea0f5c1 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/service/ChatCharacterService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/service/ChatCharacterService.kt @@ -19,6 +19,7 @@ import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepositor import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterTagRepository import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterValueRepository import org.springframework.beans.factory.annotation.Value +import org.springframework.cache.annotation.Cacheable import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort import org.springframework.stereotype.Service @@ -42,6 +43,10 @@ class ChatCharacterService( * Spring Cache(@Cacheable) + 동적 키 + 고정 TTL(24h) 사용 */ @Transactional(readOnly = true) + @Cacheable( + cacheNames = ["popularCharacters_24h"], + key = "T(kr.co.vividnext.sodalive.chat.character.service.RankingWindowCalculator).now('popular-chat-character').cacheKey" + ) fun getPopularCharacters(limit: Long = 20): List { val window = RankingWindowCalculator.now("popular-chat-character") val topIds = popularCharacterQuery.findPopularCharacterIds(window.windowStart, window.nextBoundary, limit) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/configs/RedisConfig.kt b/src/main/kotlin/kr/co/vividnext/sodalive/configs/RedisConfig.kt index 04a6c2c..eea5eab 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/configs/RedisConfig.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/configs/RedisConfig.kt @@ -123,6 +123,16 @@ class RedisConfig( ) ) + // 24시간 TTL 캐시: 인기 캐릭터 집계용 + cacheConfigMap["popularCharacters_24h"] = RedisCacheConfiguration.defaultCacheConfig() + .entryTtl(Duration.ofHours(24)) + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer())) + .serializeValuesWith( + RedisSerializationContext.SerializationPair.fromSerializer( + GenericJackson2JsonRedisSerializer() + ) + ) + return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(defaultCacheConfig) .withInitialCacheConfigurations(cacheConfigMap)