분산 락 개요
다중 프로세스가 상호 간섭 없이 동작하도록 하기 위해 분산 시스템에서 일관성 유지 기술이 필요합니다. 이 기술의 핵심은 **분산 락**입니다.
분산 락 요구 조건
- 동시에 하나의 머신의 스레드만 실행 가능
- 고가용성 및 고성능 획득/해제
- 재진입 가능
- 락 만료 처리 기능
- 비차단 락(락 획득 실패 시 즉시 반환)
분산 락 구현 방식
- Memcached: add 명령어 활용 (key 존재 여부 체크)
- Redis: setnx 명령어 사용 (key 존재 여부 체크)
- ZooKeeper: 순차적 일시적 노드 활용
- Chubby: Paxos 알고리즘 기반
Redis 분산 락 구현
락 획득
setNx("lock_sales_"+productId, 1)
결과 값이 1이면 락 성공, 0이면 실패
락 해제
del("lock_sales_"+productId)
작업 완료 후 반드시 호출 필요
락 타임아웃
expire("lock_sales_"+productId, 30)
락 타임아웃 설정 필수 (setnx는 타임아웃 파라미터 지원하지 않음)
종합 예제
if(setNx("lock_sales_"+productId, 1) == 1){
expire("lock_sales_"+productId, 30)
try {
executeTask()
} finally {
del("lock_sales_"+productId)
}
}
문제점
- setnx와 expire의 비원자성
- del 명령어로 인한 오류 삭제 위험
ZooKeeper 분산 락
ZooKeeper 개요
대규모 클러스터 관리를 위한 분산 협정 서비스. 데이터 모델은 트리 구조로 설계됨
Znode 구성 요소
- 데이터: 저장된 정보
- ACL: 접근 제어 목록
- stat: 메타데이터 (트랜잭션 ID, 버전 등)
- child: 자식 노드 목록
기본 연산
- create: 노드 생성
- delete: 노드 삭제
- exists: 노드 존재 여부 확인
- getData: 데이터 조회
- setData: 데이터 업데이트
- getChildren: 자식 노드 목록 조회
감시 기능(Watch)
노드 변경 시 특정 클라이언트에게 알림 전송
일관성 보장
ZAB 프로토콜을 통해 주-보조 구조로 운영. 최대 1MB 이하의 작은 데이터 저장 권장
ZAB 프로토콜
- Looking: 선거 상태
- Following: 보조 노드 상태
- Leading: 주 노드 상태
ZooKeeper 분산 락 원리
락 획득
- ParentLock 노드 생성
- 순차적 일시적 노드 생성
- 노드 정렬 후 우선순위 판단
- 앞선 노드 감시 등록
락 해제
- 명시적 해제
- 클라이언트 중단 시 자동 삭제
Redis vs ZooKeeper 비교
| 분산 락 | 장점 | 단점 |
|---|---|---|
| ZooKeeper | 구현 편리, 대기열 기능 제공 | 노드 추가/삭제 성능 저하 |
| Redis | 고성능 명령어 지원 | 복잡한 처리 필요, 대기열 기능 부족 |