티스토리 뷰

Spring

Redisson 분산락

soo__ 2022. 4. 27. 14:23

Redisson이란?

  • Java용 Redis Client 중 하나로, Netty를 사용하여 non-blocking I/O를 사용
  • Bucket이나 Map 같은 자료구조나 Lock 같은 특정한 구현체의 형태로 레디스의 명령어를 제공

 

분산락이란?

  • 공통된 저장소를 사용하여, 자원의 사용 여부를 체크 - 획득 - 반납하여 분산된 서버의 동기화된 처리를 지원
  • 여러 프로세스가 동시에 공유되는 하나의 자원을 다루는데, 이를 상호 배타적으로 처리해야하는 경우 사용
    • 특정 순간에 한 클라이언트에게만 락 권한을 주고, 다른 클라이언트의 접근은 락을 반환할 때 까지 막음
  • Lock을 획득하고 어떠한 문제로 인해 애플리케이션 서버가 죽었다면, Lock은 반드시 반납되어야 함
    (대기하고 있는 여러 서버들이 본인의 작업을 수행해야 하기 때문에)
  • 동시 요청이 와도, Lock을 통해 순서대로 작업이 진행되어야 함

 

Redisson의 Lock

  • Lock에 Timeout이 구현되어 있어, waitTime으로 Lock 유효성을 제어할 수 있음
  • 스핀 락 방식을 사용하지 않고, Redis의 Pub/Sub 기능을 사용하여 자원 낭비를 최소화(획득 가능한지 여부를 체크하지 않아도 됨)
    1. tryLock()을 호출하여, Lock을 획득
    2. Lock을 획득하지 못한 작업에서는 Pub/Sub을 활용하여, Lock이 해제되었다는 메시지가 오면, 대기를 풀고 Lock 획득을 시도
       Lock 획득에 실패하면, 이 과정을 Timeout 까지 반복
    3. Timeout이 지나면, 최종적으로 Lock 획득에 실패했음을 알림
  • Lock 획득 가능 여부와 Lock 획득은 원자적 단위로 수행
  • Lock 해제와 Pub/Sub 알림은 원자적 단위로 수행

 

Redisson의 분산락 주의점

  • @Transcational과 동시에 동작하지 않음!!
  • @Transcational은 트랜잭션을 AOP 기반으로 돌아가게 만들어진 선언적 트랜잭션 어노테이션이기 때문
    • proxy 객체가 메서드 종료 시 실행 결과에 따라 트랜잭션이 rollback될지 commit될지를 결정
      예외가 던져졌다면 rollback하고, 정상 종료되었다면 commit하는 형태
    • 하지만 우리는 메서드 내에서 lock.unlock()으로 잠금을 해제해주어야 하기 때문에 동시성 문제가 생긴다..!
  • 따라서, Redisson으로 분산락을 구현했을 경우, 별도로 transcational manager를 직접 주입하여 비즈니스 코드 내에서 unlock전에 rollback/commit 처리가 필요!

 

 

'Spring' 카테고리의 다른 글

JUnit 4와 5 비교  (0) 2022.05.16
JPA 영속성 컨텍스트  (0) 2022.04.28
컴포넌트 스캔과 수동 Bean 등록  (0) 2022.04.24
OSIV  (0) 2022.04.24
JPA N+1문제  (0) 2022.04.23
공지사항
«   2025/05   »
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 31