분산 락과 단일 실행 보장
어디서 필요한가
- 배치 서버 3대가 같은 스케줄을 돌리면 같은 작업이 세 번 실행된다
- 정산 마감, 쿠폰 발급처럼 한 번만 실행돼야 하는 작업에 상호배제가 필요하다
최소 요구 조건
| 조건 | 이유 |
|---|---|
| 원자적 획득 | SET key value NX PX 30000 처럼 한 명령으로 획득 |
| TTL 만료 | 보유자가 죽어도 영구 잠김이 되지 않도록 |
| 소유자 확인 후 해제 | 토큰을 비교해 남의 락을 지우지 않도록 |
| 갱신 또는 충분한 TTL | 작업이 TTL보다 길어지면 두 프로세스가 동시 진입 |
락만으로 부족한 순간
프로세스A 락 획득 → GC 정지 20s → TTL 만료
프로세스B 락 획득 → 쓰기
프로세스A 깨어나 쓰기 → 결과적으로 두 번 쓰기
- 저장소가 펜싱 토큰(단조 증가 번호)을 검사해 낮은 번호의 쓰기를 거부해야 정확성이 보장된다
실무 포인트
- 성능 최적화용 락은 Redis로 충분하지만, 정확성이 돈과 직결되면 etcd, ZooKeeper 같은 합의 기반을 쓴다
- 락 구간은 최소로 잡고 외부 API 호출을 락 안에 넣지 않는다
- 락이 필요 없게 만드는 편이 낫다. 파티션 키로 단일 소비자를 만들거나, DB 유니크 제약과 낙관적 락을 쓴다