Redis와 Redisson
Redis는 메모리 기반 Key-Value NoSQL 데이터베이스이다.
데이터를 메모리에 저장하기 때문에 매우 빠른 읽기/쓰기 성능을 제공하며 캐시, 세션 저장소, Pub/Sub, 분산 락 등에 자주 사용된다.
Redisson은 Java 환경에서 Redis를 쉽게 사용할 수 있도록 제공하는 Client 라이브러리이다.
Client 라이브러리란 애플리케이션과 외부 시스템 사이의 통신을 추상화하여 개발자가 쉽게 사용할 수 있도록 도와주는 라이브러리를 의미한다.
예를 들어 개발자는
lock.lock();
만 호출하지만 실제로는 Redisson이 Redis 명령어를 생성하여 Redis 서버와 통신한다.
Java Application
↓
Redisson
↓
Redis Command
↓
Redis
참고 문서
- Redis 공식 문서
https://redis.io/docs/latest/ - Redisson 공식 문서
https://redisson.pro/docs/
Redis 분산 락과 SET NX
Redis 분산 락은 일반적으로 SET NX 명령을 이용하여 구현된다.
SET lock:product:1 serverA NX
NX(Not Exists)는
“해당 Key가 존재하지 않을 때만 저장”
이라는 의미이다.
A 서버와 B 서버가 동시에 락 획득을 시도하면
A 서버 → 성공
B 서버 → 실패
가 된다.
이미 A가 Key를 생성했기 때문이다.
즉
Key 생성 성공
=
락 획득 성공
으로 이해할 수 있다.
참고 문서
- Redis SET Command
https://redis.io/docs/latest/commands/set/
EX(PX)를 사용하는 이유
만약 TTL 없이 락을 생성했다면
SET lock:product:1 serverA NX
A 서버가 장애로 종료되었을 때 락이 영구적으로 남을 수 있다.
A 서버 락 획득
↓
서버 장애
↓
unlock() 실패
↓
락 영구 유지
이를 방지하기 위해 TTL을 설정한다.
SET lock:product:1 serverA NX EX 30
EX는 초(second),
PX는 밀리초(milliseconds) 단위 TTL을 의미한다.
TTL이 지나면 Redis가 자동으로 락을 제거한다.
참고 문서
- Redis SET Command (EX, PX 옵션 포함)
https://redis.io/docs/latest/commands/set/
Redisson Watchdog
TTL만 설정하면 또 다른 문제가 발생한다.
TTL : 30초
실제 작업 시간 : 60초
작업이 끝나기 전에 TTL이 만료되면 다른 서버가 락을 획득할 수 있다.
이를 해결하기 위해 Redisson은 Watchdog 기능을 제공한다.
Watchdog은 락을 보유한 스레드가 살아있는 동안 TTL을 자동으로 연장한다.
작업 중
↓
TTL 연장
↓
작업 중
↓
TTL 연장
덕분에 작업 시간이 예상보다 길어져도 락이 중간에 해제되지 않는다.
참고 문서
- Redisson Locks and Synchronizers
https://redisson.pro/docs/data-and-services/locks-and-synchronizers/
Polling이란?
Polling은 특정 자원의 상태를 주기적으로 확인하는 방식이다.
예를 들어
문 열렸어?
↓
아직
↓
문 열렸어?
↓
아직
처럼 계속 확인하는 것이다.
여기서 Resource는 상태를 확인하려는 대상이다.
Redis 분산 락에서는
lock:123
이라는 락 자체가 Resource가 된다.
참고 문서
Redis를 계속 조회한다는 의미
Polling 방식에서는 락 획득에 실패하면 반복적으로 Redis에 명령을 보낸다.
예를 들어
while(true){
tryLock();
Thread.sleep(100);
}
와 비슷한 형태이다.
실제로는
SET lock:123 NX
명령을 계속 보내면서 락 획득을 시도한다.
즉 “Redis를 계속 조회한다”는 말은
Redis에 반복적으로 명령을 보내 락 상태를 확인하거나 락 획득을 시도한다는 의미이다.
참고 문서
- Redis SET Command
https://redis.io/docs/latest/commands/set/
Redis Pub/Sub
Redis는 Publish / Subscribe 메시징 모델을 제공한다.
구성 요소는 다음과 같다.
Publisher
메시지를 발행하는 주체
Subscriber
메시지를 구독하는 주체
Channel
메시지가 전달되는 통로
Subscriber는
SUBSCRIBE lock:123
명령을 통해 채널을 구독한다.
이후 Publisher가
PUBLISH lock:123 unlock
명령을 실행하면 Redis는 해당 채널을 구독하고 있는 클라이언트에게 메시지를 전달한다.
참고 문서
- Redis Pub/Sub
https://redis.io/docs/latest/develop/interact/pubsub/ - Redis SUBSCRIBE Command
https://redis.io/docs/latest/commands/subscribe/ - Redis PUBLISH Command
https://redis.io/docs/latest/commands/publish/
락 채널을 구독한다는 의미
Redisson은 락 획득에 실패하면 Polling 방식으로 Redis를 계속 조회하지 않는다.
대신 해당 락과 연결된 Pub/Sub 채널을 구독한다.
즉
락 획득 실패
↓
"락이 해제되면 알려줘"
↓
대기
상태가 된다.
이것이 “락 채널을 구독한다”는 의미이다.
참고 문서
- Redisson Locks and Synchronizers
https://redisson.pro/docs/data-and-services/locks-and-synchronizers/
Publish는 누가 수행하는가?
많은 사람들이 Redis가 Publish를 수행한다고 생각하지만 정확히는 다르다.
실제 흐름은 다음과 같다.
lock.unlock();
↓
Redisson
↓
PUBLISH lock-channel unlock
명령 실행
↓
Redis
↓
구독자에게 메시지 전달
즉
Publish 명령 실행
=
Redisson
메시지 전달
=
Redis
이다.
참고 문서
- Redis PUBLISH Command
https://redis.io/docs/latest/commands/publish/ - Redisson Locks and Synchronizers
https://redisson.pro/docs/data-and-services/locks-and-synchronizers/
Redisson이 재시도 로직을 구현할 수 있는 이유
Redisson은 락 획득에 실패하면 Polling 방식으로 Redis를 계속 조회하지 않는다.
대신 Pub/Sub 채널을 구독하고 대기한다.
이후 락을 보유한 클라이언트가 unlock()을 호출하면 Redisson이 Publish를 수행한다.
Redis는 해당 메시지를 구독 중인 클라이언트에게 전달한다.
메시지를 받은 클라이언트는 다시 SET NX 기반의 락 획득을 시도한다.
락 획득 실패
↓
Subscribe
↓
대기
↓
unlock()
↓
Publish
↓
메시지 수신
↓
SET NX 재시도
↓
락 획득 성공
결국 Redisson은 Redis Pub/Sub을 이용하여 Polling 없이 효율적인 재시도 구조를 구현할 수 있다.
참고 문서
- Redisson Locks and Synchronizers
https://redisson.pro/docs/data-and-services/locks-and-synchronizers/ - Redis Pub/Sub
https://redis.io/docs/latest/develop/interact/pubsub/
'Projects > hub-eleven' 카테고리의 다른 글
| [트러블슈팅] Redisson 분산 락 적용 중 트랜잭션 커밋 순서 문제를 해결한 과정 (2) (0) | 2026.06.23 |
|---|---|
| [트러블슈팅] Redisson 분산 락 적용 중 트랜잭션 커밋 순서 문제를 해결한 과정 (1) (0) | 2026.06.22 |
| [동시성 처리] 재고 감소 락 추상화 및 Redisson 락 구현 (아키텍처 구조 보완 필요) (0) | 2026.06.02 |
| [동시성 처리] RedissonClient Bean 설정 클래스 추가 (2) (리소스 보완 필요) (0) | 2026.05.28 |
| [동시성 처리] RedissonClient Bean 설정 클래스 추가 (1) (0) | 2026.05.27 |