백엔드 데이터 인프라 79편 — Java Redis Client (Jedis vs Lettuce 깊이)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 79편. Java Redis Client — Jedis (sync) vs Lettuce (sync+async+reactive) 정확한 비교. Connection 모델·thread-safety·성능·Spring Boot 2+ 기본 Lettuce 인 이유·Redisson 의 위치까지 풀어쓴 학습 노트. Part 4 Redis 33편 마무리.

📚 백엔드 데이터 인프라 · 79편 — Java Redis Client (Jedis vs Lettuce 깊이)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 79편이에요. Redis 33편(47~79편) 의 마지막 글이고, 78편 clients-overview 에서 모든 언어 클라이언트를 훑었다면 이번 79편은 Java 클라이언트 — Jedis vs Lettuce 를 깊이 비교해요. 시리즈 1 자바 백엔드 입문 (59편) 의 자연스러운 후속이에요.

Jedis vs Lettuce가 어렵게 느껴지는 이유

Java 환경에서는 둘 다 공식 클라이언트인 데다 둘 다 충분히 좋아서, 선택이 한눈에 떨어지지 않아요.

첫째로 두 클라이언트의 설계 철학이 달라요. Jedis 는 전통적인 sync 방식에 connection pool 을 얹은 모델이고, Lettuce 는 Netty(Java 비동기 네트워크 프레임워크) 기반 비동기에 공유 connection 을 쓰는 모델이에요. 모델이 전혀 다르다 보니 한쪽에 익숙해진 사람이 다른 쪽을 처음 보면 어색하게 느껴져요.

둘째, Spring Boot 2.0 이상에서는 기본 클라이언트가 Lettuce 로 바뀌었어요. 왜 바뀌었는지, 계속 Jedis 를 써도 되는지가 의문이 되는데, 답은 비동기·반응형 환경과의 일관성, 그리고 thread-safety 때문이에요.

셋째, Redisson 의 위치가 헷갈려요. Jedis·Lettuce 와 다른 3번째 옵션으로, 분산 객체와 고급 HA 패턴을 제공해요. 처음에는 어디에 자리하는 라이브러리인지 잘 안 잡혀요.

이 글에서 두 클라이언트의 설계 철학·Connection 모델·thread-safety·성능·기능 비교·Spring 통합·Redisson 위치·선택 가이드까지 한 번에 풀어 봐요.

Jedis — Synchronous 클래식

설계 철학

  • 전통 sync — 각 명령이 호출자 스레드에서 블로킹
  • Connection 당 한 클라이언트 — Jedis 인스턴스 = 한 connection
  • Thread-safe X — 여러 스레드 공유 불가
  • JedisPoolconnection 재사용

사용

JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
config.setMinIdle(2);

JedisPool pool = new JedisPool(config, "localhost", 6379, 2000, "pass");

try (Jedis jedis = pool.getResource()) {
    jedis.set("key", "value");
    String val = jedis.get("key");
}

try-with-resources자동 connection 반환. 까먹으면 pool 누수.

장점

  • 학습 곡선 낮음 — 단순 동기 API
  • API 가 Redis 명령에 1:1 대응jedis.set·get·hget·zadd·... 직관적
  • 메모리 효율 (Netty 의존 X)

단점

  • Thread-safe X — JedisPool 필수
  • 비동기 X — 반응형 환경에서는 wrapping 필요
  • Cluster 환경 마이그레이션 약간 복잡 (JedisCluster 별도 클래스)

Lettuce — Netty 기반 다목적

설계 철학

  • Netty 비동기 I/O 기반
  • Connection multiplexing — 하나의 connection 으로 여러 스레드 안전 공유
  • Thread-safe ◯ — JedisPool 같은 pool 보통 불필요
  • 동기·비동기·반응형 3가지 API 모두 제공

사용

RedisClient client = RedisClient.create("redis://pass@localhost:6379");
StatefulRedisConnection<String, String> connection = client.connect();

// 동기 API
RedisCommands<String, String> sync = connection.sync();
sync.set("key", "value");

// 비동기 API
RedisAsyncCommands<String, String> async = connection.async();
RedisFuture<String> future = async.get("key");

// 반응형 API
RedisReactiveCommands<String, String> reactive = connection.reactive();
Mono<String> mono = reactive.get("key");

같은 connection 에서 3가지 API 모두 사용 가능.

장점

  • Thread-safe — pool 없이 단일 connection 공유
  • 비동기·반응형 1급 지원 — WebFlux(Spring 반응형 웹 프레임워크)·Reactor(JVM 반응형 스트림 라이브러리) 환경 자연스러움
  • Auto-reconnect — 네트워크 끊김 자동 복구
  • Cluster·Sentinel(Redis 자동 failover 관리자)·Master/Replica 다 자연스러움

단점

  • 학습 곡선 약간 높음 — async·reactive 모델
  • 메모리 사용량 — Netty 의존성으로 약간 큼
  • API 가 조금 더 추상화 — Redis 명령과 1:1 매칭 직관성 약간 ↓

Connection 모델 — 핵심 차이

Jedis

┌─ 스레드 1 ─ Jedis 인스턴스 1 ── connection 1 ── Redis
├─ 스레드 2 ─ Jedis 인스턴스 2 ── connection 2 ── Redis
└─ 스레드 3 ─ Jedis 인스턴스 3 ── connection 3 ── Redis

스레드마다 connection 을 하나씩 잡고, JedisPool 로 그 connection 을 재사용하는 풀을 둬요. 100 스레드면 100 connection 이 만들어지고, pool 한계에 닿으면 그 이후 요청은 대기에 들어가요.

Lettuce

┌─ 스레드 1 ─┐
├─ 스레드 2 ─┼── 공유 connection ── Redis (Netty event loop)
└─ 스레드 3 ─┘

하나의 connection 으로 모든 스레드를 multiplex(한 채널로 다중 처리) 해요. 명령 순서는 Netty 가 내부 큐로 보장해 주고요.

여기서 정말 중요한 자리가 하나 있어요. BLPOP·SUBSCRIBE 같은 블로킹 명령 을 Lettuce 의 공유 connection 에 박으면 전체가 멈춰요. 별도 connection 을 둬야 하고, 공유 connection 으로 보낼 건 블로킹 안 쓰는 일반 명령 만 보내야 해요.

성능 비교

일반 명령 (단순 GET/SET)

거의 동등해요. 둘 다 Redis 자체 처리 속도가 병목이라 클라이언트 차이는 미세해요.

Pipelining

비슷.

고동시성 (Spring Boot WebFlux, 수천 동시 요청)

Lettuce 압도적 유리 — connection multiplexing 으로 적은 리소스로 많은 요청.

단순 sync 환경

Jedis 가 약간 더 직관적이고 메모리도 적게 써요. 다만 큰 차이는 아니에요.

기능 비교

기능 Jedis Lettuce
동기 API
비동기 API X (JedisPooled 일부)
반응형 API X
Cluster ◯ (JedisCluster) ◯ (RedisClusterClient)
Sentinel
Master/Replica 자동 라우팅
Auto-reconnect
Topology auto-refresh X
Pub/Sub
Sharded Pub/Sub
Pipelining
Transactions
Lua scripting
RedisJSON·Search·TS △ (별도 모듈) △ (별도 모듈)

기능 격차는 크지 않아요. 연결 모델·thread-safety·반응형 지원이 결정적이에요.

Spring Boot 2.0+ — Lettuce 기본

기본값이 Lettuce 인 이유는 세 가지예요. 우선 thread-safe 라서 pool 관리가 자동으로 따라오고, Auto-reconnect 와 topology refresh 가 있어 Cluster·Sentinel 환경에서 안정적이에요. 마지막으로 WebFlux 와 일관돼서, 같은 클라이언트로 sync 와 reactive 를 다 처리할 수 있어요.

설정

spring:
  data:
    redis:
      host: localhost
      port: 6379
      password: pass
      timeout: 2000ms
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0
        cluster:
          refresh:
            adaptive: true
            period: 60s

Jedis 로 변경

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
spring:
  data:
    redis:
      jedis:
        pool:
          max-active: 50
          max-idle: 10

lettucejedis 로 키만 변경.

Redisson — 3번째 옵션

Jedis·Lettuce 와 결이 달라요. Redisson 은 분산 객체와 고급 HA 패턴을 들고 와요.

차이

  • 분산 객체RLock·RMap·RList·RBucket 같은 Java Collection 인터페이스를 Redis 위에 구현. 마치 로컬 객체처럼 사용.
  • Redlock(Redis 분산 락 알고리즘) 알고리즘 (63편) 자동 구현
  • Watchdog(락 잡은 동안 TTL 자동 연장) — 락 잡고 작업 길어지면 자동 TTL 연장
  • Reactive·RxJava 지원

사용

Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379");
RedissonClient redisson = Redisson.create(config);

// 분산 락 (63편 패턴)
RLock lock = redisson.getLock("my-lock");
lock.lock(30, TimeUnit.SECONDS);
try {
    // 작업
} finally {
    lock.unlock();
}

// 분산 Map
RMap<String, String> map = redisson.getMap("my-map");
map.put("key", "value");

// 분산 Queue
RQueue<String> queue = redisson.getQueue("my-queue");
queue.add("job-1");

위치

  • 단순 Redis 명령 → Jedis·Lettuce
  • 분산 락·고급 패턴 → Redisson
  • 둘 다 사용 = 일반 패턴 (Lettuce 로 명령 + Redisson 으로 락)

선택 가이드

이 프로젝트는?
├─ Spring Boot 2+ + Spring MVC + 단순 캐시
│   └─ Lettuce (기본값 그대로) ★
├─ Spring Boot 2+ + Spring WebFlux + 반응형
│   └─ Lettuce reactive ★★
├─ 기존 Jedis 사용 중 + 만족
│   └─ Jedis 유지 (마이그레이션 불필요)
├─ 분산 락·복잡한 HA 패턴 자주
│   └─ Lettuce + Redisson 조합
└─ 단순 sync + 비-Spring 환경
    └─ Jedis 도 OK

99% 신규 Spring Boot 환경 = Lettuce.

Cluster·Sentinel 통합 차이

Lettuce 의 강점

  • adaptive refresh — MOVED(Cluster 키 이동 알림 응답) 감지 시 자동 topology 갱신
  • Master/Replica 자동 라우팅 — 읽기는 replica, 쓰기는 master 자동
  • Sentinel failover 자동 감지·재연결

Jedis

  • JedisCluster·JedisSentinelPool 별도 클래스
  • 기본 동작 OK, 자동화 정도가 Lettuce 보다 약간 낮음

한계·실무 함정

1. Lettuce 공유 connection 에 blocking 명령

위에서 강조한 그 자리예요. BLPOP·SUBSCRIBE 는 별도 connection 으로 빼야 해요.

2. Jedis 의 try-with-resources 누락

Jedis jedis = pool.getResource();
jedis.set(...);
// jedis.close() 누락 → connection leak

반드시 try-with-resources 로 감싸야 해요.

3. Spring Data Redis 통한 사용 — 직접 클라이언트 API 안 쓰는 게 일반적

Spring 환경에서는 RedisTemplate 이나 @Cacheable 추상화를 거쳐서 써요. Jedis·Lettuce API 를 직접 호출하는 건 특수한 경우에만 해당해요.

4. 클라이언트 버전 + 서버 버전 호환

오래된 Jedis (~3.x) 는 Redis 7 의 신규 기능 일부를 못 따라가요. 최신 권장이에요.

5. Redisson 의 약간 더 무거움

Redisson 은 풍부한 추상화에 Netty, 그리고 여러 의존성을 함께 가져와요. 단순 캐시만 필요한 환경에는 Lettuce 가 더 가벼워요.

Part 4 Redis 마무리

시리즈 2 Part 4 — Redis 33편 끝. 지금까지 풀어 본 영역:

  • 4-1 자주 쓰는 6종 (47~54편) — String·Hash·List·Set·Sorted Set·Stream
  • 4-2 키·만료·알림 (55~57) — TTL·notifications·pipelining
  • 4-3 상호작용·프로그래밍 (58~61) — Pub/Sub·transactions·Lua·Functions
  • 4-4 패턴 (62~65) — 9가지 패턴·distributed lock·twitter clone·secondary indexing
  • 4-5 운영 (66~71) — persistence·replication·cluster·sentinel·ACL·TLS
  • 4-6 성능·확장 (72·73) — memory optimization·Spring integration
  • 4-7 모듈 (74~77) — JSON·Search·Time Series·Vector
  • 4-8 클라이언트 (78·79) — 종합·Java 깊이

Redis 의 거의 모든 영역 을 한 시리즈로. 다음 영역 — Part 5 Kafka 51편 (80~130) — 이벤트 스트리밍의 표준.

시험 직전 한 번 더 — Jedis vs Lettuce 함정 압축 노트

  • Jedis = sync 클래식, JedisPool 필수, thread-safe X
  • Lettuce = Netty 기반, 공유 connection multiplexing, thread-safe ◯, 비동기·반응형 1급
  • Spring Boot 2.0+ 기본 = Lettuce
  • Connection 모델 — Jedis 스레드당 / Lettuce 공유 multiplexing
  • 100 스레드 = Jedis 100 connection / Lettuce 1 connection
  • Lettuce 공유 connection 에 blocking 명령 = 전체 멈춤 → 별도 connection
  • 성능 — 일반 명령은 동등, 고동시성은 Lettuce 압도적
  • 기능 — 둘 다 풍부, 결정적 차이는 반응형·thread-safety·auto-reconnect
  • Spring Boot 통합 — yaml spring.data.redis.lettuce.* 또는 jedis.*
  • Jedis 마이그레이션 = pom 의존성 교체 + yaml 설정 키 변경
  • Redisson = 3번째 옵션, 분산 객체·Redlock·Watchdog
  • 위치 — 단순 = Jedis/Lettuce / 분산 락·HA = Redisson
  • Lettuce + Redisson 조합 = 일반 패턴
  • 선택 — Spring Boot 2+ MVC = Lettuce 기본 / WebFlux = Lettuce reactive / 기존 Jedis = 유지 / 분산 락 = + Redisson
  • Lettuce 강점 — adaptive refresh, Master/Replica 자동 라우팅, Auto-reconnect
  • 함정 — Jedis try-with-resources 누락 = leak
  • 함정 — Redisson 약간 더 무거움 → 단순 캐시는 Lettuce 가 가벼움
  • 함정 — 오래된 클라이언트 = 신규 기능 미지원
  • 99% 신규 Spring Boot 환경 = Lettuce

공식 문서: JedisLettuce, Redisson 에서 자세한 사양과 예제를 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!