본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

 

 

강의 요약

오늘은 Redis String 데이터 타입의 주요 명령어와 Java 클라이언트(Jedis), 그리고 성능 최적화 기법인 파이프라이닝에 대한 키워드가 강의에 나왔다. 주로 연산자 위주로 소개되었고 파이프라이닝은 간단하게 나오고 끝나서 연산자, jedis, lettuce, 파이프라인에 대해 추가적으로 살펴보았다.

 

 

String Data Type Command

Redis String 타입은 단순해 보이지만 다양한 활용이 가능하다. 시스템 설계 시 각 명령어의 시간복잡도를 이해하고 적절히 선택해야 한다.

MSET, MGET의 시간복잡도는 O(N)이지만 단일 명령으로 여러 키의 값을 설정하거나 조회할 수 있어 지연 시간을 감소시킬 수 있다.

 

명령어 설명 시간 복잡도
SET / GET 단일 키 저장/조회 O(1)
SETNX 키가 없을 때만 저장 O(1)
MSET / MGET 다중 키 저장/조회 O(N)
INCR / INCRBY 원자적 카운터 증가 O(1)
GETRANGE / SETRANGE 문자열 부분 조회/수정 O(N)

 

  • 대부분의 String 연산은 O(1)로 매우 효율적이다.
  • 그러나 GETRANGE나 SETRANGE처럼 랜덤 액세스 문자열 명령어는 큰 문자열을 처리할 때 성능 문제를 일으킬 수 있다.

 

Java Redis 클라이언트

Redis 자바 클라이언트는 대표적으로 Jedis, Lettuce, Redisson 세 가지를 많이 쓰게 된다. 셋 다 Redis에 붙는 라이브러리지만, 애초에 지향하는 목표와 추상화 레벨이 꽤 다르다.

 

Jedis

Jedis는 가볍고 쉬운 동기식 클라이언트에 초점을 둔 라이브러리이다. Redis 명령을 자바 코드에서 거의 그대로 호출하는 느낌이라 학습 비용이 낮고, 작은 서비스에서는 빠르게 붙여서 쓰기 좋다. 

 

다만 Jedis 인스턴스 자체는 스레드 세이프하지 않기 때문에, 멀티 스레드 환경에서는 반드시 JedisPool 같은 커넥션 풀을 통해서만 사용해야 한다. 풀로 감싸면 멀티 스레드 환경에서도 무난히 쓸 수 있지만, 커넥션 수 관리나 풀 튜닝에 신경을 써야 한다는 부담이 생긴다.

커넥션 풀링은 레디스 커넥션 수를 증가시키는 물리적 비용이 발생하기 때문에 Lettuce를 권장하는 추세이다.
(Spring Boot 기본 설정 : Lettuce)


Lettuce

Lettuce는 처음부터 비동기·논블로킹·리액티브 사용을 목표로 설계된 클라이언트로, 하나의 커넥션을 여러 스레드가 공유해도 되는 구조라 스레드 세이프한 특징이 있다. 이 구조 덕분에 Spring WebFlux 같은 리액티브 스택과 잘 맞고, 트래픽 증가에 대비한 확장성을 챙기기에도 좋다.

 

Redisson

Redisson은 다양한 분산 객체를 제공하는 레디스 클라이언트이다. 다른 두 클라이언트가 레디스의 기본 자료구조를 다루는 API만 제공하는 데 비해 레디슨은 분산된 환경에서 사용할 수 있는 다양한 객체를 구현해놓았다. 단순 클라이언트라기보다는 Redis 기반 분산 컬렉션·락·캐시·서비스 프레임워크에 가까운 포지션을 가진다.

특히 락 쪽이 Lettuce와 가장 크게 갈리는 지점이다. Lettuce로 분산 락을 쓰려면 `SETNX`, `EXPIRE`, 스핀 락, 만료 처리 등을 직접 구현해야 하는 반면, Redisson은 위에서 말한 다양한 락 구현을 라이브러리 차원에서 제공해준다. 그래서 “분산 환경에서의 락과 동기화”가 중요한 서비스라면, 단순 클라이언트보다 Redisson을 사용하는 것이 좋을 수 있다.

 

파이프라이닝

일반적인 Redis 요청/응답 흐름은 다음과 같다:

[일반 요청]
Client: SET key1 → Server: OK
Client: SET key2 → Server: OK
Client: SET key3 → Server: OK
(매 요청마다 RTT 발생)


그런데 파이프라이닝을 사용하여 여러 Redis 명령을 한 번에 서버로 전송해 RTT를 줄이고 네트워크를 최적화할 수 있다.

[파이프라이닝]
Client: SET key1, SET key2, SET key3 →
                    ← Server: OK, OK, OK
(RTT 1회로 감소)

 

성능 향상 폭

Redis 공식 문서에 따르면, 파이프라이닝을 활용하면 초당 처리량이 최대 10배까지 향상될 수 있다. 이는 단순히 RTT 절감 효과뿐 아니라 시스템 콜(read/write) 횟수 감소로 인한 컨텍스트 스위칭 비용 절감 효과도 포함된다.

 

 

그러면 파이프라인을 사용할 때의 조심해야할 점은 무엇일까?

 

유의사항 1. 파이프라이닝 ≠ 트랜잭션

 

가장 흔한 오해가 파이프라이닝을 트랜잭션으로 착각하는 것이다. 파이프라이닝은 단순히 네트워크 최적화 기법일 뿐, 원자성(Atomicity)을 보장하지 않는다. 데이터 정합성이 중요한 작업에서는 반드시 MULTI/EXEC를 사용해야 한다.

파이프라이닝: A, B, C 명령 전송 → A 성공, B 실패, C 성공 (가능)
트랜잭션(MULTI/EXEC): A, B, C 명령 → 전체 성공 또는 전체 실패

 

 

유의사항 2. 서버 메모리 사용량 증가

파이프라이닝 사용 시 서버는 모든 응답을 메모리에 큐잉해야 한다. 한 번에 너무 많은 명령을 보내면 서버 메모리 부담이 증가하므로, 10,000개 단위로 배치 처리하는 것이 권장된다.

 

유의사항 3. 명령 간 종속성 주의

명령들이 순차적으로 처리되지만, 이전 명령의 결과를 기반으로 다음 명령을 구성해야 하는 경우에는 파이프라이닝을 사용할 수 없다.



참고 출처

 

 

 

시작 시간
종료 시간
학습 인증

 

수강 인증


https://fastcampus.info/4oKQD6b

+ Recent posts