4P by neo 2달전 | favorite | 댓글 1개

분산 잠금 구현하기

  • Redis 웹사이트에서 Redlock 알고리듬을 발견하고, 이 알고리듬이 Redis 위에서 내결함성 분산 잠금을 구현한다고 주장함.
  • Redlock에 대한 여러 독립적인 구현이 이미 존재하며, 이 알고리듬에 의존하는 사람이 있을 수 있어 필자의 노트를 공유하기로 결정함.
  • Redis는 일시적이고 빠르게 변하는 데이터를 서버 간에 공유할 때 유용하지만, 강한 일관성과 내구성이 요구되는 데이터 관리 영역으로 확장되는 것은 우려됨.

잠금의 목적

  • 잠금은 여러 노드 중 하나만 특정 작업을 수행하도록 보장하는 역할을 함.
  • 효율성을 위해 잠금을 사용하는 경우, 단일 Redis 인스턴스를 사용하는 것이 더 나을 수 있음.
  • 정확성을 위해 잠금을 사용하는 경우, Redlock은 적합하지 않음.

자원을 잠금으로 보호하기

  • 분산 시스템에서의 잠금은 멀티스레드 애플리케이션의 뮤텍스와 다름.
  • 클라이언트가 파일을 읽고 수정 후 다시 쓰는 동안 다른 클라이언트가 동일한 작업을 수행하지 못하도록 방지함.

펜싱을 통한 안전한 잠금 구현

  • 펜싱 토큰을 사용하여 쓰기 요청에 포함시킴으로써 안전한 잠금을 구현할 수 있음.
  • Redlock은 펜싱 토큰을 생성하는 기능이 없어 안전하지 않음.

합의를 위한 시간 사용

  • Redlock은 비동기 모델에서의 알고리듬과 달리 시간에 대한 가정을 많이 함.
  • 시스템 시계가 이상하게 작동하면 키의 만료가 예상보다 빠르거나 느려질 수 있음.

Redlock의 시간 가정 깨기

  • Redlock은 동기 시스템 모델을 가정하며, 네트워크 지연, 프로세스 일시 중지, 시계 오류가 제한적일 때만 올바르게 작동함.
  • GitHub의 90초 패킷 지연 사건과 같은 사례가 Redlock의 안전성을 위협할 수 있음.

결론

  • Redlock은 효율성 최적화 잠금에는 불필요하게 무겁고, 정확성을 요구하는 상황에는 충분히 안전하지 않음.
  • 정확성을 위해 잠금이 필요한 경우, ZooKeeper와 같은 적절한 합의 시스템을 사용하는 것이 좋음.

GN⁺의 정리

  • Redlock 알고리듬은 분산 시스템에서의 잠금 구현에 대한 중요한 논의를 제공함.
  • 이 글은 분산 시스템에서의 시간 가정과 안전성 문제를 강조하며, 올바른 잠금 구현의 중요성을 설명함.
  • ZooKeeper와 같은 대안 시스템을 추천하며, 분산 시스템의 복잡성을 이해하는 데 도움이 됨.
Hacker News 의견
  • Temporal을 사용하여 분산 잠금을 구현한 경험이 있으며, 현재까지 잘 작동하고 있음. Temporal의 기능을 활용하여 분산 잠금의 구현이 간단함
  • 블로그 댓글에서 알고리즘의 중요한 점을 놓쳤다는 의견을 남겼으며, 이로 인해 알고리즘의 거부가 약한 점에 기반하고 있다는 점을 지적함
  • 현대 컴퓨터와 API를 사용하면 대략적인 시간 대기를 할 수 있으며, GC 일시 중지는 제한적이고 단조로운 시계가 작동함. 이는 수용 가능한 가정임
  • 자동 해제 메커니즘을 비판하는 것과 알고리즘의 목표와 시스템 모델을 비판하는 것은 다른 문제임
  • Redlock은 다양한 사용 사례에서 성공적으로 사용되었으며, 타임아웃을 적절히 설정하면 경합 조건을 유발하기 어려움. 작은 타임아웃 설정은 설계 오류임
  • 저수준 및 알고리즘 지식을 업데이트 중이며, 재미로 무언가를 만들고 싶지만 대부분의 자료가 장난감 수준이거나 매우 복잡함
  • PostgreSQL을 사용하여 분산 잠금을 구현하며, 트랜잭션을 시작하고 조언 잠금을 얻어 트랜잭션이 해제될 때까지 잠금 상태를 유지함
  • 데이터베이스 연결 상태를 확인하지 않았다는 점을 깨달았으며, 데이터베이스 관련 작업이 아닌 경우 잠금을 잃었을 가능성이 있음
  • Deno와 Deno KV를 사용하여 분산 잠금을 구현했으며, FoundationDB를 기반으로 함
  • Redis를 검토했으나 PostgreSQL을 사용하여 요청을 SET 작업으로 변환하여 정확성을 해결함
  • 많은 엔지니어들이 정확성 문제를 중요하게 여기지 않으며, 메시지가 손실되거나 순서가 잘못될 수 있는 경계 사례가 존재함
  • 잠금에 타임아웃을 설정하는 것이 좋은 아이디어이며, 클라이언트가 충돌할 경우 OS나 감독자가 잠금을 해제함
  • 잠금이 필요 없는 경우, 버전 토큰을 사용하여 데이터 무결성을 유지할 수 있음. UUID와 같은 고유한 값이 사용될 수 있음