민스씨의 일취일장

프로젝트 LOG | REDIS를 이용해 캐시 도입하기 본문

Projects/MetaPay

프로젝트 LOG | REDIS를 이용해 캐시 도입하기

읻민스 2024. 9. 12. 20:42
반응형

PaymentService에 Redis 캐시를 도입하는 과정(GitHub Issues #26)에 대한 글이다.

REDIS를 이용해 캐시 도입하기

Project Log : Redis Cache 도입하기 썸네일 이미지이다.
Project Log : Redis Cache 도입하기

작업 순서 계획

1. 프로젝트에 Redis 설정
2. 로컬 Redis에서 테스트
3. EC2 Redis용 인스턴스 추가하기
4. 작동 확인

1. 프로젝트에 Redis 설정

캐시를 적용할 서비스(PaymentService)에 Redis 설정을 하면서 캐시 도입을 시작한다.

build.gradle에 의존성 추가

build.gradle에 Redis 의존성을 추가한다. Redis도 일종의 Database이기 때문에, Database 연결과 비슷한 과정을 거친다.

implementation 'org.springframework.boot:spring-boot-starter-data-redis'
application.properties / applicaton-redis.properties

Redis 설정을 properties 파일에 추가해 줘야 한다. 이 때, application.properties에 직접해줘도 되고, application-redis.properties로 따로 해줘도 된다. application-reids.properties로 했다면, application.properties에서 프로필 포함(spring.profile.include) 해줘야 한다.

spring.data.redis.host = localhost
spring.data.redis.port = 6379
RedisConfig 생성하기

DataBase와 다른 점은 RedisConfig로 동작 설정을 해준다는 점이다.

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .disableCachingNullValues();
        return RedisCacheManager.builder()
                .cacheDefaults(cacheConfiguration)
                .build();
    }
}
  • redisTemplate

Redis와 상호작용할 때 필요한 RedisTemplate를 빈(Bean)으로 등록한다.

  • cacheManager

Redis를 조작/소통할 때 사용할 CacheManager를 Bean으로 등록한다.

entryTtl()을 이용해 데이터가 캐시로 남아 있는 시간을 설정한다. 매우 동적인 데이터인 경우 10초에서 5분, 보통은 15분에서 2시간, 거의 변하지 않는 데이터는 6시간에서 7일까지 등 상황에 맞게 설정해줘야한다.

@EnableCaching

Application 클래스에 @EnableCaching을 추가해준다.

 Cache를 사용할 메서드에 애너테이션 추가

PaymentService 등 캐시를 사용할 메서드에 애너테이션을 추가해준다.

@Cacheable(value = "payment", key = "#paymentId")
public Payment getPayment(String paymentId) {
    ...
}

@CachePut(value = "payment", key = "#payment.id")
public Payment updatePayment(Payment payment) {
    ...
}

@CacheEvict(value = "payment", key = "#paymentId")
public void deletePayment(String paymentId) {
    ...
}
  • @Cacheable

메서드 결과를 캐시에 저장하고, 동일한 파라미터로 메서드 호출 시, 캐시된 결과를 반환한다.

  • @CachePut

메서드 실행 결과를 항상 캐시에 저장 및 업데이트 한다. (Cacheable에서 데이터 동기화 문제 없이 사용할 수 있는 이유가 이 절차 때문이다.)

  • @CacheEvict

데이터베이스 내에서 삭제될 내용이 캐시에 있다면 함께 제거해준다. 캐시 메모리를 효율적으로 사용하기 위해 추가작업이 필요 없다는 점이 좋다.

2. Redis 실행하기

도커 컨테이너를 사용해 빠르게 Redis를 실행할 수 있다.

docker run --name redis-cache -p 6379:6379 -d redis

이것으로 Redis 준비는 완료이다.

2. 로컬 Redis에서 테스트하기

중간에 직렬화 등의 작은 실수가 있었지만, 빠르게 문제없이 작동하는 것을 확인할 수 있었다.

Redis CLI 무습이다.
Redis Cli

redis-cli에서 캐시된 키(payment::1)를 위에서 확인할 수 있다. 

3. EC2 Redis용 인스턴스 추가하기

새로운 인스턴스를 추가해 준 뒤, 2에서처럼 Redis 컨테이너를 실행시켜 준다. 이제 Redis 인스턴스의 Private IP를 서비스 Redis Host로 적용해주면 된다.

4. 클라우드 환경에서의 작동 확인

똑같은 방식으로 다시 한 번 테스틀 해준다. 이번 에는 Redis 인스턴스와 연결된 EC2 서비스로 요청을 보내주기만 하면 된다.

Redis CLI 모습이다.
Redis CLI

이 때 주의할 점은, 6379 포트의 인바운딩을 허용해 줘야 한다.

🚨 보안 인바운드 규칙에서 6379포트를 열어줘야 한다.

이후 계획

  • 캐시를 도입한 후 성능에 어떤 차이가 있는지 테스트 해볼 것이다. 
728x90
반응형