본문 바로가기

Study

[내일배움캠프 TIL] - Redis 동시성 제어 3가지 방식 비교

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은 오버스펙이다.

반응형