| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Graph
- 알기쉬운 알고리즘
- 혼자 공부하는 C언어
- 이것이 자바다
- Selection Sorting
- JSON
- 윤성우의 열혈 자료구조
- buffer
- coding test
- R
- 메모리구조
- Algorithm
- C 언어 코딩 도장
- Serialization
- datastructure
- stream
- list 컬렉션
- Stack
- ㅅ
- 이스케이프 문자
- insertion sort
- 윤성우 열혈자료구조
- C programming
- s
- Today
- Total
Engineering Note
[SW Engineering] Redis 분산락 구현 과정, 짧은 lease time으로 발생가능한 동시성 문제 해결 + Pub/Sub 동작 원리 본문
[SW Engineering] Redis 분산락 구현 과정, 짧은 lease time으로 발생가능한 동시성 문제 해결 + Pub/Sub 동작 원리
Software Engineer Kim 2025. 12. 28. 10:13분산락이란?
분산된 서버에서 공유 자원(DB)에 동시에 접근 요청시 발생할 수 있는 문제를 해결하기 위해 사용하는 방식이다.
Lock에 대한 정보를 분산 서버가 접근 가능한 공통 저장소에 저장하고 분산 서버들은 저장된 Lock을 보고 접근 여부를 결정한다.
공통 저장소로 일반적인 DB가 될수도 있고, 인메모리 기반의 NoSQL인 Redis가 될수도 있다.
분산락을 구현하기 위해 Redisson 사용
의사결정 과정
Redis 클라이언트 라이브러리로는 Redisson, Lettuce이 있는데 Redisson은 분산락을 구현할 때 Pub/Sub 방식을 사용하고 Lettuce는 Spin Lock 방식을 사용하도록 권장하는데 Spin Lock 방식은 클라이언트(Spring Applicaiton)가 반복해서 Redis에 락해제, 락점유를 체크하는 방식으로 Spring 인스턴스의 CPU 자원와 네트워크 자원을 사용해야 하므로 Pub/Sub 방식으로 구현하였습니다.
Pub/Sub 방식 구현에서는 Rlock의 tryLock으로 락과 관련된 시간을 설정하였는데 두 번째 파라미터 lease Time을 비활성화 하여 watch dog 방식을 선택했습니다. 만약 lease time을 1초 등 짧게 설정할 경우 먼저 점유한 쓰레드의 트랜잭션이 마무리 되지 않았을 경우에도 락이 해제되어 다른 쓰레드가 DB 접근이 가능해지고 동시성 이슈가 발생할 수 있습니다.
Redission trylock 코드 분석 => Pub/Sub으로 동작
Spin Lock vs Pub/Sub
Redis로 분산락을 구현하는 방식은 Pub/Sub기반과 Spin Lock 방식이 있다. Pub/Sub방식으로 분산락을 구현했다.
그리고 leaseTime을 없애 락이 일시적으로 풀리는 상황을 방지했습니다. WatchDog 방식은 tryLock의 파라미터에서 leasTime(두번째 파라미터)를 작성하지 않으면 자동으로 설정된다.
leaseTime을 지정할 수도 있는데 leasTime으로 지정한 시간이 지나면 락이 자동으로 해제된다. 만약 락을 요청한 서버가 장애로 인해 동작하지 않는 다면, 락이 계속되어 데드락 상태에 빠질 수 있는데 Redisson의 락을 요청한 서버가 살아 있는 동안만 락 만료 시간을 연장하는 방식으로 데드락에 빠지는 상황을 방지한다. leasTime을 지정하지 않는다면, WatchDog 타임아웃시간이 지나면 자동으로 해제되어 데드락 상황을 막을 수 있다.
락을 지정한 쓰레드만이 락을 해제할 수 있다.
waitTIme은 락을 얻기위해 기다리는 최대 시간
RLock lock = redissonClient.getLock(lockKey);
boolean available = lock.tryLock(5, 3, TimeUnit.SECONDS);
```
이 코드는 **Pub/Sub 방식**으로 동작합니다.
---
## ⚙️ 실제 동작 과정
### Thread-1 (락 획득)
```
1. Redis에 락 생성
SETNX lock:event:1 "uuid-thread-1"
2. TTL 설정
PEXPIRE lock:event:1 3000
```
### Thread-2 (대기)
```
1. 락 획득 시도 실패
SETNX lock:event:1 "uuid-thread-2"
→ 0 (실패)
2. Pub/Sub 채널 구독 ⚠️
SUBSCRIBE redisson_lock__channel:{lock:event:1}
→ Block 상태로 메시지 대기
❌ Spin Lock이라면: while(true) { Redis 계속 확인 }
✅ Pub/Sub이라서: 조용히 메시지 대기 (CPU 안 씀)
```
### Thread-1 (락 해제)
```
1. 락 삭제
DEL lock:event:1
2. Pub/Sub 메시지 발행 ⚠️
PUBLISH redisson_lock__channel:{lock:event:1} "0"
→ Thread-2에게 "락 풀렸어!" 알림
```
### Thread-2 (깨어남)
```
1. 메시지 수신
< "락 해제됨"
2. 락 재획득 시도
SETNX lock:event:1 "uuid-thread-2"
→ 1 (성공!)
```
---
## 🎯 정리
**질문**: 내 코드가 Pub/Sub이라는거지?
**답**:
```
✅ 맞습니다!
✅ Redisson의 tryLock()은 Pub/Sub 기반입니다
✅ Spin Lock이 아닙니다
참고 자료 : https://redisson.pro/docs/data-and-services/locks-and-synchronizers/#__tabbed_1_1
Locks and synchronizers - Redisson Reference Guide
Locks and synchronizers Lock Valkey or Redis based distributed reentrant Lock object for Java and implements Lock interface. Uses pub/sub channel to notify other threads across all Redisson instances waiting to acquire a lock. If Redisson instance which ac
redisson.pro
https://hstory0208.tistory.com/entry/분산락을-적용해-동시성-문제-해결하기 [< Hyun / Log >:티스토리]
'SW Engineering > 선착순 이벤트' 카테고리의 다른 글
| Redis 도입 여부 결정하기 (0) | 2026.01.01 |
|---|---|
| [Redis] Redisssion 락 사용 방법, RLock Class, tryLock()메서드 (0) | 2025.12.28 |
| [SW Engineering] @Transactional과 Redis 분산락, 왜 같이 쓰면 안 될까? (feat. Facade 패턴) (0) | 2025.12.27 |
| [SW Engineering] Redis 분산락을 통한 동시성 문제 해결 과정 (0) | 2025.12.25 |
| [SW Engineering] Redis 분산락을 사용하는 이유와 기본적인 사용 방법 (0) | 2025.12.25 |