분산 락

동작 방식

요구사항

redis 구현

redission을 통한 분산 락 구현

zookeeper 구현

분산 락

여러 대의 서버나 시스템에서 동시에 실행되는 프로세스/스레드가 접근하는 공유 자원에 대해 제어하기 위한 락이다

분산 시스템에서는 여러 개의 노드가 동일한 자원에 동시에 접근할 수 있기 때문에 락을 통해 공유 자원을 동기화한다

동작 방식

주로 락을 관리하는 클러스터 환경(중앙 서버나 스토리지 시스템)에서 분산 락을 구현한다

여러 노드 간에 락이 공유되며 다음과 같은 방식으로 동작한다

락 획득

프로세스/스레드가 자원에 접근하기 위해 락을 획득한다

락을 얻은 노드만 해당 자원에 접근할 수 있으며 이미 락이 사용 중이라면 대기한다

자원 접근

락을 얻은 노드가 자원에 접근한다

락 해제

작업이 끝나면 락을 해제하야 다른 노드가 자원에 접근할 수 있도록 한다

요구사항

원자성

타임아웃

자동 해제

redis 구현

lettuce 스핀 락 부하 문제

redis lettuce 클라이언트를 사용하여 분산 락을 구현하면 SETNX 명령 또는 lua 스크립트를 호출하여 락을 얻을 때 까지 반복적으로 락 획득을 시도한다

이런 방식으로 분산 락을 구현하게 되면 레디스 서버가 받는 부하가 커지게 된다

스핀 락 부하 문제 완화 방법

1. 지수 백오프(exponential backoff) 또는 고정 대기 시간

락 획득 시도 사이에 대기 시간을 두는 방법이다

일정 시간 대기 후 다시 시도하거나, 대기 시간을 점점 늘리는 지수 백오프 전략을 사용한다

while(!tryLock(redisKey)) {
    Thread.sleep(100);
}

2. 락 시도 제한

무한 반복 대신 최대 시도 횟수를 제한하고 일정 횟수 이상 실패하면 락 획득을 포기하도록 구현한다

3. redis lua 스크립트 사용

레디스는 lua 스크립트를 통해 복잡한 작업을 원자적으로 실행할 수 있는 기능을 제공한다

lua 스크립트는 레디스 서버에서 실행되며 여러 명령을 하나의 작업으로 처리하여 성능과 일관성을 높인다

4. redisson 사용

lettuce 대신 레디스 기반의 분산 락 구현 라이브러리인 redisson을 사용한다

redisson은 기본적으로 락 재시도와 대기 시간을 관리해주는 메커니즘을 제공한다

이후 내용