728x90
반응형
배운 것
Redis로 동시성을 제어하는 방식이 3가지가 있고, 각각 적용 범위와 사용 상황이 다르다.
1. Redis 원자 명령어 (DECR 등)
Redis 명령어 하나가 원자적으로 실행된다.
DECR coupon:stock:123
→ 읽기 + 차감 + 저장이 한 방에
→ 중간에 다른 명령어가 끼어들 수 없음
- 명령어 하나짜리 작업에만 적용 가능
- 가장 빠름
- 예시: 쿠폰 재고 차감 (DECR), 중복 발급 체크 (SISMEMBER)
2. Lua 스크립트
여러 명령어를 묶어서 원자적으로 실행한다.
-- 이 전체가 하나의 원자적 실행
if 중복이면 return -2
if 재고없으면 return -1
재고차감
선점등록
순번발급
return 순번
Redis는 Lua 스크립트 실행 중 다른 모든 명령어를 블락한다.
그래서 여러 단계가 하나처럼 실행된다.
- 명령어 여러 개를 원자적으로 묶어야 할 때 사용
- 예시: 드롭 서비스의 선점 로직 (중복체크 → 재고체크 → 선점 → 순번발급)
- 4단계 사이에 다른 요청이 끼어들면 안 되므로 Lua로 묶음
3. Redisson 분산락
Redis 원자 명령어나 Lua로 해결 못하는 Java 코드 전체를 직렬화할 때 사용한다.
RLock lock = redissonClient.getLock("lock:" + id);
lock.lock();
try {
// Java 코드 전체가 한 번에 하나만 실행
// DB 조회
// 계산 로직
// 외부 API 호출
// DB 저장
} finally {
lock.unlock();
}
Redis에서 "이 락 가진 사람만 실행 가능"이라는 플래그를 관리하면서
Java 코드 레벨에서 직렬화한다.
- DB + 외부 API 포함한 복잡한 로직 전체를 직렬화해야 할 때 사용
- 가장 넓은 범위를 잠글 수 있지만 오버헤드 있음
비교 정리
적용 범위 속도 사용처
| Redis 원자 명령어 | 명령어 1개 | 가장 빠름 | 단순 카운터 (쿠폰 재고) |
| Lua 스크립트 | 명령어 여러 개 | 빠름 | 복잡한 Redis 연산 묶음 (드롭 선점) |
| Redisson 분산락 | Java 코드 전체 | 상대적으로 느림 | DB + 외부 API 포함 복잡한 로직 |
위로 갈수록 빠르고, 아래로 갈수록 더 넓은 범위를 잠글 수 있다.
이 프로젝트에서 Redisson이 필요 없는 이유
- 쿠폰 서비스: 재고 차감은 DECR 하나로 충분
- 드롭 서비스: 복잡한 선점 로직은 Lua 스크립트로 해결
- 오더 서비스: Kafka 이벤트 기반이라 동시성 문제 자체가 없음
Redis 명령어나 Lua로 해결 가능한 범위에서 Redisson은 오버스펙이다.
반응형
'Study' 카테고리의 다른 글
| [내일배움캠프 TIL] - Lettuce Redis 명령이 Zipkin에 안 나타나는 이유 & 해결 (0) | 2026.07.06 |
|---|---|
| [내일배움캠프 TIL] - 부하 테스트 지표와 p95가 국룰인 이유 (0) | 2026.07.03 |
| [내일배움캠프 TIL] GitHub Actions에서 org 레포 ghcr.io 패키지 push 권한 (0) | 2026.07.01 |
| [내일배움캠프 TIL] Lettuce 첫 번째 Redis 호출이 3초나 걸린 이유 (Cold Start 지연) (0) | 2026.06.30 |
| [내일배움캠프 TIL] ghcr.io 이미지 태그는 소문자만 허용된다 (0) | 2026.06.29 |