skarltjr / Memory_Write_Record

나의 모든 학습 기록
0 stars 0 forks source link

간단한 redis 캐시 활용 및 부하테스트 해보기 #122

Open skarltjr opened 1 year ago

skarltjr commented 1 year ago

무엇을 확인하고자 하는가?

1. 캐시를 사용하지 않은 부하테스트 결과

2. 특정 데이터를 미리 캐시해둔 후 부하테스트

그냥 캐시를 사용하면 성능이 개선된다가 아니라 눈으로 확인하고 싶었다.

초당 처리가능한 요청이 3배이상 개선
응답속도는 절반 이하로 감소를 직접 확인
다만 수정이 많이 발생하는곳엔 애초부터 캐시를 사용하지않도록 조심하자
수정의 경우 다시 캐시하는 과정에서 굉장히 많은 시간이 소요된다.

부하테스트 참고 : https://jobc.tistory.com/225

skarltjr commented 1 year ago

redis config

@EnableCaching
@Configuration
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String host;

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

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setPort(port);
        redisStandaloneConfiguration.setHostName(host);

        LettuceConnectionFactory lettuceConnectionFactory =
                new LettuceConnectionFactory(redisStandaloneConfiguration);

        return lettuceConnectionFactory;
    }

    @Bean
    public RedisCacheManager redisCacheManager() {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(
                                new StringRedisSerializer()))
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(
                                new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues()
                .entryTtl(Duration.ofHours(1L));

        return RedisCacheManager.RedisCacheManagerBuilder
                .fromConnectionFactory(redisConnectionFactory())
                .cacheDefaults(redisCacheConfiguration)
                .build();

    }
}

controller

  @GetMapping("/cache/{id}")
  @Cacheable(value = "MyEntity",key="#id",unless = "#result==null",cacheManager = "redisCacheManager")
  public String handle(@PathVariable Long id) {
      myService.withCache(id);
      return "string";
  }

  @GetMapping("/non/{id}")
  public String handle2(@PathVariable Long id) {
      myService.withoutCache(id);
      return "string";
  }

service

@Service
@RequiredArgsConstructor
public class MyService {
    //private final MyService2 myService2;
    private final MyRepo myRepo;

    public void init() {
        myRepo.save(new MyEntity(null,1));
    }

    @Transactional(readOnly = true)
    public void withCache(Long id) {
        myRepo.findById(id);
    }

    @Transactional(readOnly = true)
    public void withoutCache(Long id) {
        myRepo.findById(id);
    }
}

부하테스트 스크립트

import time
from locust import HttpUser, task
from locust.user.wait_time import constant

class QuickstartUser(HttpUser):
    wait_time = constant(1)

    @task
    def monitor_check(self):
        self.client.get("/cache/1")