BackEnd/Redis

[Redis] 캐싱을 이용한 간단한 성능 개선 테스트(Apache JMeter)

연향동큰손 2025. 8. 25. 17:00

Redis 캐싱을 이용해 조회성능 테스트를 진행했다.

 

 

캐싱이란?

 

캐싱은 자주 사용하는 데이터를 임시 저장소(캐시)에 보관하여, 데이터 조회 속도를 높이고 시스템 부하를 줄이는 기술이다.

 

캐싱을 사용하게 되면 메모리에 저장된 데이터를 반환 함으로써 디스크 기반의 데이터베이스보다 빠르게 데이터를 불러올 수 있다는 장점이 있다.

 

이러한 캐싱 기술은 웹 서비스의 성능을 높일 수 있다는 장점이 있지만 무작정 사용한다면 오히려 성능 저하나 오류가 발생할 수 있다.

 

캐싱 전략 선택시 고려사항

  1. 데이터의 변경 빈도 : 캐싱에 대상이 되는 데이터가 가변성이 높다면 캐시 데이터가 최신 데이터를 반영하고 있지 않을 수 있다. 또한 잦은 캐시 무효화와 재생성으로 인해 부하가 증가할 수 있다.
  2. 데이터를 한번 쓰고 여러번 읽는 경우 : 사용자 프로필과 같이 데이터를 한번 쓰고 여러번 읽는 경우 캐싱 효과가 좋다.
  3. 캐시 데이터의 수명 : 캐시 데이터가 지워지지 않고 계속 캐시 저장소에 저장되어 있는것은 바람직하지 않다. 따라서 캐시 만료 정책을 적절히 설정하여 캐시 데이터의 신선도를 유지할 필요가 있다.

 

캐싱을 통한 성능비교 테스트

 

캐싱을 통해 조회 성능을 비교하는 테스트를 진행했다.

 

테스트 도구로 Apache JMeter를 사용했다.

 

Apache JMeter란 서버가 제공하는 성능 및 부하를 측정할 수 있는 테스트 도구이다. 

이번에 처음 사용 해봤는데 다양한 테스트 시나리오를 쉽게 테스트 가능했고, 앞으로도 자주 사용하며 사용법을 익힐 예정이다.

 

Spring에서는 여러 캐시 저장소(Redis, Ehcache, Caffeine, ConcurrentMap 등)를 사용할 수 있도록 CacheManager 인터페이스를 제공한다.

 

나는 Redis로 캐싱을 구현할 예정이므로 RedisConfig 클래스를 생성해 Redis 커넥션 설정 및 스프링 캐시 추상화에서 사용하는 CacheManager 구현체를 Redis로 설정해줬다.

@Configuration
@EnableCaching   
@EnableRedisRepositories
public class RedisConfig {

    @Value("${spring.data.redis.host}")
    private String host;

    @Value("${spring.data.redis.port}")
    private int port;

    @Value("${spring.data.redis.password}")
    private String redisPassword;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port);
        config.setPassword(redisPassword);
        return new LettuceConnectionFactory(config);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.setDefaultSerializer(new StringRedisSerializer());
        return redisTemplate;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {

        RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(1)) // TTL 1분
                .disableCachingNullValues()
                .serializeKeysWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer()));

        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(defaultConfig)
                .build();
    }
}

 

 

그리고 게시글 조회 메서드에 대해서 @Cacheable를 추가해 해당 키를 가진 데이터가 캐시에 존재하지 않으면 DB에 조회하고 캐시에 저장하도록 하고,

만약 캐시 메모리에 해당 키를 가진 데이터가 캐시에 존재하면 DB조회를 하지않고 캐시에 저장된 데이터를 반환 하도록 했다.

@Cacheable(value = "postsCache", key = "'allPosts'")
public List<PostTotalListResponseDto> getTotalPostList() {

    List<Post> posts = postRepository.findAll();

    List<Post> sortedPosts = posts.stream()
            .sorted((p1, p2) -> p2.getCreatedAt().compareTo(p1.getCreatedAt()))
            .toList();

    return sortedPosts.stream()
            .map(PostTotalListResponseDto::toDto)
            .toList();
}

 

테스트 시나리오

  • 가상 사용자수 50 -> 100 -> 500 순으로 증가
  • 한명의 가상 사용자가 10초에 걸쳐 10번씩 조회 요청

테스트 결과

 

요청 수 5000의 경우 성능차이

  • 평균 응답속도 : 약 209배 빨라짐
  • 처리량(TPS) : 약 3.9배 증가

 

테스트 결과 요청수가 늘어날수록 캐시를 적용 했을때와 안했을때의 성능차이가 명확하게 나타났다.

 

요청수가 5000회인 경우 캐시 없이 DB에서 데이터를 조회할때는 평균응답이 2720ms까지 나타났지만 Redis를 적용한 경우 5000번의 요청에서도 13ms의 평균 응답을 유지했다.

 

TPS또한 Redis를 사용한 경우 5000번의 요청에서는 4배 가까이 증가하는 것을 확인할 수 있었다.

 

 

이 테스트를 통해 Redis 캐시를 사용할 경우 낮은 부하보다 높은 부하 환경에서 성능을 극대화 시킬 수 있다는 것을 알게되었다.

'BackEnd > Redis' 카테고리의 다른 글

Spring Boot + Redis를 활용한 Refresh Token 기능 구현  (0) 2025.08.24
Redis DB서버 구성  (0) 2025.08.22
Redis(Remote Dictionary Server)란?  (2) 2025.08.21