Reactive Redis 사용법

2024. 7. 12. 21:05·Spring/대용량 트래픽

2024.07.07 - [Spring/대용량 트래픽] - Reactive Redis란?

 

Reactive Redis란?

2024.07.07 - [Spring/대용량 트래픽] - Spring Webflux R2DBC 여러가지 기능들 Spring Webflux R2DBC 여러가지 기능들2024.07.06 - [Spring/대용량 트래픽] - Spring Webflux R2DBC 사용해보기 Spring Webflux R2DBC 사용해보기2024.0

lsdiary.tistory.com

준비물
  1. Redis 6(Docker Container)
  2. Gradle
    1. spring-boot-starter-data-redis-reactive

혹여나 Docker와 Redis가 설치되어 있지 않다면 이 글을 참고 하길바란다. https://lsdiary.tistory.com/55

 

Redis,Docker 설치하기와 수많은 에러

도커 컨테이너 기반으로 Redis를 설치해보겠다. https://hub.docker.com/_/redis redis - Official Image | Docker Hub Quick reference Supported tags and respective Dockerfile links 7.2.4, 7.2, 7, latest, 7.2.4-bookworm, 7.2-bookworm, 7-bookworm,

lsdiary.tistory.com

모두 설치가 되었다면 다음과 같은 명령으로 Redis 컨테이너를 실행한다.

docker run -it -p 6379:6379 redis:6.2

실행되었다면 다음 명령으로 cli를 들어간다.

docker exec -it [containerID] redis-cli

그리고, monitor 명령으로 redis에 어떠한 상호작용이 일어나는지 모니터링 해주면 준비는 끝이다.


 

본인은 InteliJ로 돌아와서 다음과 같은 의존성을 추가해줬다.

implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'

이렇게 잘 추가가 되었다면 제대로 된것이다.

다음은 .yml 파일설정이다.

data:
  redis:
    host: 127.0.0.1
    port: 6379

 

이렇게 설정을 해주면 연결 끝~? R2DBC와 마찬가지로 lazy로 연결을 시도하기 때문에 port번호를 틀리게 해도 실패하는 메세지가 뜨지 않는다.(물론 R2DBC에서는 비밀번호를 틀리게 했었음)

-> 검증 로직을 넣어줘야한다.

RedisConfig.java
@Configuration
@RequiredArgsConstructor
@Slf4j
public class RedisConfig implements ApplicationListener<ApplicationReadyEvent> {
    private final ReactiveRedisTemplate<String, String> reactiveRedisTemplate;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        reactiveRedisTemplate.opsForValue().get("1")
                .doOnSuccess(i -> log.info("initialize to redis connection"))
                .doOnError((err) -> log.error("failed to initialize redis connection: {}", err.getMessage()))
                .subscribe();
    }
}

 

마찬가지로 강제로 어플리케이션이 실행될때, Redis에 "1"인 키값을 요청해서 실패시 에러를 발생시키도록 해줬다.

성공시에는 위와같은 화면이 나와야한다.

Redis-cli 모니터링화면에서도 확인할 수있다.

reactiveRedisTemplate.opsForList().leftPush("list1", "hello").subscribe();
reactiveRedisTemplate.opsForValue().set("sampleKey1", "sample", Duration.ofSeconds(60)).subscribe();

작성한 config파일에 위와같은 코드를 추가해서 Redis에 데이터를 저장할수 있다.


Cache로 사용

 

기존에 생성해두었던 로직에 더해서(사용자 아이디로 사용자를 찾음) -> 이걸 캐시로 사용하는 코드를 작성해보겠다.

ReactiveRedisTemplate을 이용할 것인데, 위의 설정파일에서 만들어준 다음과 같은 코드(String, String 형식)는ReactiveRedis가 실행하면서 default로 만들어주는 Bean이다.

private final ReactiveRedisTemplate<String, String> reactiveRedisTemplate;

 

하지만 우리가 원하는 로직은 사용자를 찾는 것이기 때문에 <String, User> 형식이 필요하다. -> 커스텀하게 만들어주는건 원하는 형식에 맞춰 따로 설정이 필요하다.

RedisConfig.java
@Bean
public ReactiveRedisTemplate<String, User> reactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory){
    ObjectMapper objectMapper = new ObjectMapper()
            // 모르는 속성에 실패처리 안함
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            // created_at, updated_at 등 시간에 관한 처리
            .registerModule(new JavaTimeModule())
            .disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
    Jackson2JsonRedisSerializer<User> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(objectMapper, User.class);
    RedisSerializationContext<String, User> serializationContext = RedisSerializationContext
            .<String, User>newSerializationContext()
            .key(RedisSerializer.string())
            .value(jsonRedisSerializer)
            .hashKey(RedisSerializer.string())
            .hashValue(jsonRedisSerializer)
            .build();
    return new ReactiveRedisTemplate<>(connectionFactory, serializationContext);
}

위와 같이 설정파일에 빈으로 등록해주자.

더보기

위 설정 파일같은 경우 https://lsdiary.tistory.com/83에서 다시 상세하게 볼수있다.

 

Spring Boot Cache

2024.05.08 - [Spring/대용량 트래픽] - Redis Cache로 실습하기 Redis Cache로 실습하기2024.05.07 - [Spring/대용량 트래픽] - Redis Cache 이론 Redis Cache 이론2024.05.07 - [Spring/대용량 트래픽] - Redis Key, Scan 명령어 Red

lsdiary.tistory.com

UserSevcie.java
    public Mono<User> findById(Long id){
        return reactiveRedisTemplate.opsForValue()
                .get(getUserCacheKey(id))
                .switchIfEmpty(
                        userR2dbcRepository.findById(id)
                                .flatMap(u -> reactiveRedisTemplate.opsForValue()
                                        .set(getUserCacheKey(id), u)
                                        .then(Mono.just(u)))
                );
//        return userR2dbcRepository.findById(id);
    }

 

기존 Spring Data Redis와의 차이점은 Mono, Flux로 감싸느냐의 차이이다.

Redis-cli

  • 그렇다면 User에 대해서 업데이트를 해주는 경우는 어떨까?

Redis에 저장되어있는 값도 변경을 해줘야할것이다. 다음과 같이 unlink() 메서드(비동기 삭제)로 Redis에 저장되어있는 데이터를 삭제하고 DB에 저장하는식으로 Service로직을 수정해준다.

public Mono<User> update(Long id, String name, String email){
    return userR2dbcRepository.findById(id)
            .flatMap(u -> {
                u.setName(name);
                u.setEmail(email);
                return userR2dbcRepository.save(u);
            })
            .flatMap(u -> reactiveRedisTemplate.unlink(getUserCacheKey(id)).then(Mono.just(u)));
}
  • 삭제

public Mono<Void> deleteById(Long id){
    return userR2dbcRepository.deleteById(id)
            .then(reactiveRedisTemplate.unlink(getUserCacheKey(id)))
            .then(Mono.empty());
}

 

  • TTL설정 : set인자에 Duration.ofxxx(원하는 시간)

2024.07.13 - [Spring/대용량 트래픽] - Spring MVC vs Webflux 성능 비교(with Jmeter)

 

Spring MVC vs Webflux 성능 비교(with Jmeter)

2024.07.12 - [Spring/대용량 트래픽] - Reactive Redis 사용법 Reactive Redis 사용법2024.07.07 - [Spring/대용량 트래픽] - Reactive Redis란? Reactive Redis란?2024.07.07 - [Spring/대용량 트래픽] - Spring Webflux R2DBC 여러가지

lsdiary.tistory.com

 

'Spring > 대용량 트래픽' 카테고리의 다른 글

Blockhound로 디버깅하기  (0) 2024.07.13
Spring MVC vs Webflux 성능 비교(with Jmeter)  (0) 2024.07.13
Reactive Redis란?  (0) 2024.07.07
Spring Webflux R2DBC 여러가지 기능들  (0) 2024.07.07
Spring Webflux R2DBC 사용해보기  (0) 2024.07.06
'Spring/대용량 트래픽' 카테고리의 다른 글
  • Blockhound로 디버깅하기
  • Spring MVC vs Webflux 성능 비교(with Jmeter)
  • Reactive Redis란?
  • Spring Webflux R2DBC 여러가지 기능들
Ls._.Rain
Ls._.Rain
안되면 될때까지 삽질했던 기록
  • Ls._.Rain
    Ls{Diary}
    Ls._.Rain
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • Github (2)
      • Spring (51)
        • Batch Programming (13)
        • 결제 (4)
        • 대용량 트래픽 (32)
        • OpenAI (0)
        • Security (0)
        • WebSocket (0)
        • JPA (1)
      • Algorithm (67)
        • DFS (6)
        • BFS (6)
        • Dynamic Programming (10)
        • Brute Force (4)
        • Binary Search (6)
        • 구현, 시뮬레이션 (15)
        • Stack (1)
        • Greedy (4)
        • Priority_Queue (2)
        • Back Tracking (3)
        • Geometry (2)
        • SCC (1)
        • 투포인터 (4)
        • 최대유량 (1)
        • 정렬 (1)
      • OS (0)
      • DevOps (15)
        • AWS (11)
        • Docker (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • hELLO· Designed By정상우.v4.10.0
Ls._.Rain
Reactive Redis 사용법
상단으로

티스토리툴바