Redis를 활용한 분산락 구현
Redis의 SET 명령어를 사용해서 분산 잠금을 구현할 수 있습니다. 가령, 1대 이상의 서버가 특정 Key에 대해서 SET 명령어에 NX 옵션(Not eXists)을 추가하여 Redis에 전달하여 잠금 획득을 시도합니다. NX 옵션을 사용하면 특정 Key에 해당하는 값이 존재하지 않는 경우에만 값 추가 작업이 성공합니다. SET 작업을 성공적으로 수행한 서버는 잠금을 획득합니다. 잠금을 획득한 서버는 작업이 끝난 이후, Key에 해당하는 값을 제거하여 잠금을 해제합니다.
✔️ 잠금(lock)이 유실될 가능성이 있지 않을까?
만약, 레플리케이션 구성으로 이루어져 있으면 잠금이 유실될 가능성이 존재합니다. 예를 들어, 마스터 노드가 존재하고 레플리카 노드에 주기적으로 데이터를 복제하는 구성이라고 가정하겠습니다. 이때, 특정 서버가 잠금을 획득하고 작업을 수행하는 도중에 마스터 노드에 장애가 발생하는 경우에는 레플리카 노드가 마스터 노드로 승격될 수 있습니다. (failover)
위와 같은 가정에서 기존 마스터 노드가 가지고 있던 잠금용 데이터를 레플리카 노드가 가지고 있지 않은 상태라면, 작업을 처리하고 있는 서버의 잠금이 유실됩니다. 즉, 복제 지연으로 인해 분산 잠금의 상호 배제라는 특성을 잃게 됩니다. 이러한 문제를 해결하기 위해서 RedLock 알고리즘이 등장했습니다.
✔️ RedLock 알고리즘은 어떻게 동작할까?
RedLock 알고리즘은 1대 이상의 단일 레디스 노드들을 이용하여 분산 잠금을 구현하는데요. 과반수 이상의 노드에 잠금을 획득한다면 잠금을 획득하는 것으로 간주합니다. 만약, 5개의 단일 레디스 노드가 존재한다고 가정하겠습니다. 작업 서버가 모든 노드에게 잠금 획득을 시도했는데, 3개(과반수) 노드에서 잠금을 획득다면, 분산 잠금을 획득한 것으로 판단합니다.
✔️ RedLock 구성 요건
- 서로 독립된 Redis 인스턴스(Master 노드) 5개 이상
이들은 서로 네트워크나 스토리지 장애로부터 독립적이어야 합니다.
예: 서로 다른 서버, 가용 영역, 데이터센터에 위치
- 각 인스턴스에 동일한 Lock Key를 시도
클라이언트는 가능한 한 동시에 각 인스턴스에 Lock을 시도하고, 과반수(예: 5개 중 3개) 이상 성공하면 Lock을 획득한 것으로 간주합니다.
- 복제본(Replica) 사용 여부는 별개
Redis Sentinel이나 Cluster 구조 내에서 레플리카는 가능하지만, RedLock 자체는 복제본이 아닌, 마스터 인스턴스들 간의 독립성에 의존합니다.