Developer/Posting

[Redis] prefixKeysWith로 원하는 키값이 나오지 않을 때 (캐시 기본키와 prefix)

codingzipsa 2024. 2. 28. 20:01
반응형

이전 프로젝트 수행 시 캐싱을 적용하면서 있었던 애로사항을 2개 포스팅으로 정리해본다.

 

캐싱을 적용하고 DevOps쪽에서 키값 이슈로 CLI에서 중간에 Depth가 비어보인다고 연락을 받아서 처리했던 내용이다.

1. simple() from Spring Data Redis

보통 레디스 설정 내 아래와 같이 키와 캐싱 시간 등 설정을 진행할 것이라고 생각한다.

	@Bean
    public CacheManager redisCacheManager(GenericJackson2JsonRedisSerializer serializer) {
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory());
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
				.computePrefixWith(CacheKeyPrefix.simple())
				.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(SerializationPair.fromSerializer(serializer))
                .entryTtl(Duration.ofMinutes(30));
        builder.cacheDefaults(configuration);
        return builder.build();
    }

 

여기서 문제가 되는 부분은 .computePrefixWith(CacheKeyPrefix.simple()) 이였다.

의도치 않았으나 키값이 project:app:subject 와 같이 ':'으로 분류되고 정리되어 CLI에서 명확하게 보이기를 원했는데 어떠한 이유에서인지 중간에 계속 '::'와 같이 두개의 콜론이 붙은 키값으로 캐싱이 진행되고 있었다.

 

트래킹을 하면서 공식문서를 확인해보았다. 역시 공식문서에 답이 있었다.

 

https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/cache/CacheKeyPrefix.html#simple()

 

CacheKeyPrefix (Spring Data Redis 3.2.2 API)

Functional Interface: This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. CacheKeyPrefix is a callback hook for creating custom prefixes prepended to the actual key stored in Redis.

docs.spring.io

 

해당문서에서 simple() 메소드로 이동하면 아래와 같은 문구가 나온다.

For example, a cache named myCache will prefix all cache keys with myCache::.

 

myCache라는 이름의 캐시는 myCache::이라는 고정값으로 처리되게 된다라는 의미로 해석이 된다. 즉, 모든 캐시 이름 뒤에 콜론이 두개가 붙게 되는 것이다.

 

2. Solution

이를 개선하기 위해 아래와 같이 코드를 수정하였다.

 

	@Bean
    public CacheManager redisCacheManager(GenericJackson2JsonRedisSerializer serializer) {
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory());
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
				.computePrefixWith(CacheKeyPrefix.simple()) // AS-IS
                		.computePrefixWith(cacheName -> myCache: + cacheName + ":") // TO-BE
				.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(SerializationPair.fromSerializer(serializer))
                .entryTtl(Duration.ofMinutes(30));
        builder.cacheDefaults(configuration);
        return builder.build();
    }

 

어떻게 보면 굉장히 간단한 문제일 수 있으나 캐싱 트래킹 및 히스토리 생성에 있어 일관성 있는 관리의 시작은 명칭이기 때문에 사내에서 Redis CLI를 이용하여 모니터링 한다던가 명칭 커스터마이징할 때 위와 같이 처리한다면 크게 문제가 없을 것이라 생각이 든다.

반응형