티스토리 뷰
Redisson이란?
- Java용 Redis Client 중 하나로, Netty를 사용하여 non-blocking I/O를 사용
- Bucket이나 Map 같은 자료구조나 Lock 같은 특정한 구현체의 형태로 레디스의 명령어를 제공
- (참고) Lettuce, Jedis과의 비교
- redisson vs jedis
- redisson vs lettuce
분산락이란?
- 공통된 저장소를 사용하여, 자원의 사용 여부를 체크 - 획득 - 반납하여 분산된 서버의 동기화된 처리를 지원
- 여러 프로세스가 동시에 공유되는 하나의 자원을 다루는데, 이를 상호 배타적으로 처리해야하는 경우 사용
- 특정 순간에 한 클라이언트에게만 락 권한을 주고, 다른 클라이언트의 접근은 락을 반환할 때 까지 막음
- Lock을 획득하고 어떠한 문제로 인해 애플리케이션 서버가 죽었다면, Lock은 반드시 반납되어야 함
(대기하고 있는 여러 서버들이 본인의 작업을 수행해야 하기 때문에) - 동시 요청이 와도, Lock을 통해 순서대로 작업이 진행되어야 함
Redisson의 Lock
- Lock에 Timeout이 구현되어 있어, waitTime으로 Lock 유효성을 제어할 수 있음
- 스핀 락 방식을 사용하지 않고, Redis의 Pub/Sub 기능을 사용하여 자원 낭비를 최소화(획득 가능한지 여부를 체크하지 않아도 됨)
- tryLock()을 호출하여, Lock을 획득
- Lock을 획득하지 못한 작업에서는 Pub/Sub을 활용하여, Lock이 해제되었다는 메시지가 오면, 대기를 풀고 Lock 획득을 시도
→ Lock 획득에 실패하면, 이 과정을 Timeout 까지 반복 - Timeout이 지나면, 최종적으로 Lock 획득에 실패했음을 알림
- Lock 획득 가능 여부와 Lock 획득은 원자적 단위로 수행
- Lock 해제와 Pub/Sub 알림은 원자적 단위로 수행
Redisson의 분산락 주의점
- @Transcational과 동시에 동작하지 않음!! ★★★
- @Transcational은 트랜잭션을 AOP 기반으로 돌아가게 만들어진 선언적 트랜잭션 어노테이션이기 때문
- proxy 객체가 메서드 종료 시 실행 결과에 따라 트랜잭션이 rollback될지 commit될지를 결정
→ 예외가 던져졌다면 rollback하고, 정상 종료되었다면 commit하는 형태 - 하지만 우리는 메서드 내에서 lock.unlock()으로 잠금을 해제해주어야 하기 때문에 동시성 문제가 생긴다..!
- proxy 객체가 메서드 종료 시 실행 결과에 따라 트랜잭션이 rollback될지 commit될지를 결정
- 따라서, 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 |