|
| 1 | +--- |
| 2 | +title: 분산 락(Distributed Lock)이란? |
| 3 | +date: 2025-08-06 19:35:00 +0900 |
| 4 | +categories: [Backend, Database] |
| 5 | +tags: [distributed-lock, redis, zookeeper] |
| 6 | +--- |
| 7 | + |
| 8 | +## 분산 락(Distributed Lock)이란 무엇일까요? |
| 9 | + |
| 10 | +분산 시스템 환경에서는 여러 서버가 공유된 자원(데이터, 파일 등)에 동시에 접근하려고 할 때 데이터의 일관성과 무결성을 해치는 문제가 발생할 수 있습니다. 예를 들어, 여러 사용자가 동시에 상품 재고를 수정하려고 하면, 실제 재고와 데이터베이스의 값이 달라지는 문제가 생길 수 있습니다. |
| 11 | + |
| 12 | +이러한 문제를 해결하기 위해 **분산 락**이 사용됩니다. 분산 락은 여러 서버에 분산된 시스템에서 공유 자원에 대한 동시 접근을 제어하는 동기화 메커니즘입니다. 즉, 특정 자원에 대해서는 한 번에 하나의 프로세스(또는 스레드)만 접근할 수 있도록 보장하여 데이터의 일관성을 유지합니다. |
| 13 | + |
| 14 | +## 분산 락은 왜 필요할까요? |
| 15 | + |
| 16 | +하나의 서버에서 동작하는 애플리케이션에서는 `synchronized` 키워드나 `ReentrantLock`과 같은 자바의 동시성 제어 도구를 사용하여 스레드 간의 동시 접근을 제어할 수 있습니다. 하지만 서버가 여러 대로 확장된 분산 환경에서는 이러한 방식이 동작하지 않습니다. 각 서버는 자신만의 메모리(JVM)를 가지고 있기 때문에, 한 서버의 락은 다른 서버에 영향을 주지 못합니다. |
| 17 | + |
| 18 | +따라서 분산 환경에서는 모든 서버가 공통으로 참조할 수 있는 외부의 락 관리 시스템이 필요합니다. 이것이 바로 분산 락의 역할입니다. |
| 19 | + |
| 20 | +## 분산 락 구현 방법 |
| 21 | + |
| 22 | +분산 락을 구현하는 데는 여러 가지 방법이 있지만, 주로 다음과 같은 외부 시스템을 활용합니다. |
| 23 | + |
| 24 | +### 1. Redis를 이용한 분산 락 |
| 25 | + |
| 26 | +[Redis](https://redis.io/)는 인-메모리 데이터 저장소로, 빠른 속도와 간단한 명령어(SETNX)를 제공하여 분산 락을 구현하는 데 널리 사용됩니다. |
| 27 | + |
| 28 | +- **SETNX (SET if Not eXists)**: `SETNX` 명령어는 키가 존재하지 않을 때만 값을 설정합니다. 이 명령어의 원자성(atomic)을 이용하여 락을 구현할 수 있습니다. |
| 29 | + - 프로세스가 락을 획득하려면 `SETNX lock_key "locked"`와 같은 명령어를 실행합니다. |
| 30 | + - 명령어가 성공하면(1을 반환), 락을 획득한 것입니다. |
| 31 | + - 이미 다른 프로세스가 락을 가지고 있다면 명령어는 실패합니다(0을 반환). |
| 32 | + |
| 33 | +- **단점**: |
| 34 | + - **락 유실**: 락을 획득한 클라이언트가 처리를 완료하고 락을 해제하기 전에 비정상적으로 종료되면, 락이 영원히 해제되지 않는 **데드락(deadlock)** 상태에 빠질 수 있습니다. 이를 방지하기 위해 락에 유효 시간(TTL, Time-To-Live)을 설정해야 합니다. |
| 35 | + - **Redis 단일 장애점(SPOF)**: 단일 Redis 인스턴스를 사용하면 해당 인스턴스에 장애가 발생했을 때 전체 시스템의 락 기능이 마비될 수 있습니다. 이를 해결하기 위해 **Redis Sentinel**이나 **Redis Cluster**와 같은 고가용성 구성을 사용해야 합니다. |
| 36 | + |
| 37 | +### 2. ZooKeeper를 이용한 분산 락 |
| 38 | + |
| 39 | +[Apache ZooKeeper](https://zookeeper.apache.org/)는 분산 시스템의 코디네이션을 위해 설계된 서비스로, 분산 락을 구현하는 데 매우 안정적인 기능을 제공합니다. |
| 40 | + |
| 41 | +- **영구 노드(Persistent Nodes)와 임시 노드(Ephemeral Nodes)**: ZooKeeper는 파일 시스템과 유사한 계층적인 ZNode 구조를 가집니다. |
| 42 | + - 락을 표현하기 위해 특정 경로에 **임시 노드(ephemeral node)**를 생성합니다. |
| 43 | + - 임시 노드는 해당 노드를 생성한 클라이언트의 세션이 활성 상태일 때만 존재합니다. 만약 클라이언트가 비정상적으로 종료되면, 세션이 끊어지고 해당 임시 노드는 자동으로 삭제됩니다. 이 특성 덕분에 데드락을 방지할 수 있습니다. |
| 44 | + - **순차 노드(Sequential Nodes)**: ZooKeeper는 노드를 생성할 때 순번을 붙여주는 기능을 제공합니다. 이를 이용하면 모든 요청이 락을 기다리게 하는 것이 아니라, 순서대로 락을 획득하도록 하여 "Thundering Herd" 문제를 방지하고 공정한 락 획득 순서를 보장할 수 있습니다. |
| 45 | + |
| 46 | +- **단점**: |
| 47 | + - **성능**: Redis에 비해 상대적으로 느릴 수 있습니다. ZooKeeper는 데이터의 일관성과 안정성을 보장하기 위해 복잡한 프로토콜(ZAB)을 사용하기 때문입니다. |
| 48 | + - **운영 복잡성**: Redis에 비해 설치 및 운영이 더 복잡합니다. |
| 49 | + |
| 50 | +## 분산 락 사용 시 고려사항 |
| 51 | + |
| 52 | +- **데드락 방지**: 락을 획득한 클라이언트가 어떤 이유로든 락을 해제하지 못하는 상황을 반드시 방지해야 합니다. TTL 설정이나 ZooKeeper의 임시 노드와 같은 메커니즘이 필수적입니다. |
| 53 | +- **성능**: 분산 락은 시스템의 전체 성능에 큰 영향을 미칠 수 있습니다. 락을 획득하고 해제하는 과정이 빈번하게 발생한다면, Redis와 같이 빠른 솔루션이 적합할 수 있습니다. |
| 54 | +- **안정성 및 고가용성**: 락을 관리하는 시스템 자체가 장애의 원인이 되어서는 안 됩니다. Redis Cluster, ZooKeeper 앙상블(ensemble) 등 고가용성 구성이 필요합니다. |
| 55 | + |
| 56 | +## 결론 |
| 57 | + |
| 58 | +분산 락은 분산 시스템에서 데이터의 일관성을 보장하기 위한 필수적인 도구입니다. 각 구현 방식은 장단점이 명확하므로, 시스템의 요구사항(성능, 안정성, 복잡성 등)을 신중하게 고려하여 적절한 방법을 선택해야 합니다. |
0 commit comments