분산락(redis) vs Optimistic locking

도메인

optimistic locking은 db를 사용하는 애플리케이션 <-> db 사이의 동시성 관리 전략이다.

distributed locking은 분산 시스템에서 사용하는 동시성 관리 전략이다.


사용 case

optimistic locking은 같은 데이터 레코드를 여러 세션이 동시에 갱신할 때 사용한다.

distributed locking은 공유 자원을 여러 노드(다른 machine)에서 접근할 때 사용한다.


작동원리

optimistic locking은 데이터 버저닝/타임스탬프, 예외처리를 사용한다.

distributed locking은 centralized, token, quorum 등 다양한 알고리즘을 사용한다.


충돌 가정

optimistic locking은 충돌이 드문 상황을 가정한다.
(사용자들이 같은 Data를 동시에 수정하지 않을 것)

distributed locking은 잦은 충돌을 염두에 둔다.




이상적인 분산락 조건

1. 상호 배제
- 한 번에 하나의 노드만 lock을 얻을 수 있다. 

2. Fault tolerance
- node가 실패한다면 lock은 사용불가능한 상태가 돼야함.

3.효율성
- lock을 acquire/release 과정이 효율적일 것.

4.공평성
- 노드들은 lock을 공평하게 획득해야함.


분산락 알고리즘

centralized locking

single node가 central lock manager 역할.

- 구현 쉬움
- single point of failure 문제



token-based locking

node에 unique한 token이 전달되고

token을 들고있는 node만 공유 리소스에 접근 가능.

- fault tolerance

- complex to implement
  (token expiration, token 유실을 대비해야함)


quorum based locking(Redlock: redis 알고리즘)

1. T1 값 획득( = 클라이언트의 현재 시각 기록)


2. SETNX를 사용하여 lock 획득 <set if not exists for acquiring a lock>

- lock 획득에 성공하면 instance가 클라이언트에 OK 응답.

- 다른 클라이언트에 의해 사용중인 instance는 NO 응답.

- 도중에 client에서 crash 발생시, lock이 stale되는 것을 방지하기 위해 setnx 시, TTL값을 첨부한다.


3. 경과시간 ( T2 - T1 ) 계산

단계1로부터 경과한 시간을 계산한다.

elapsed time < lock 유효 시간

을 만족해야한다.


4. quorum 값 계산

n개의 redis instance가 존재한다면

n/2 + 1= 5/2 +1 = 3 -> 3개의 lock 필요 .


5. Unlock

사용이 끝나면 DEL을 사용하여 lock 해제.

del로 lock을 정상적으로 release하기 전에 client에 오류가 생기면,

TTL을 이용하여 자동으로 lock을 release 한다.


이렇게 함으로서 dead lock을 방지하고

다른 client가 자원을 점유할 수 있게한다.


- high fault tolerance, availability

- more complex, potential for isuues 


SETNX : set if not exists for acquiring a lock

EXPIRE : 무기한 점유를 막기 위해 lock에 timeout을 설정한다. 


leader election

node가 leader를 선택하고, leader가 lock을 설정하는 책임을 짐.

- single point of failure 회피

- take time, resources, hard to implement









댓글

이 블로그의 인기 게시물

실무진 면접 경험으로 정리하는 백엔드 (1) : 에듀 테크 기업 면접

노마드코더 개발자북클럽 Clean code TIL 6 : 6장. 객체와 자료구조

백엔드 개발자가 Djnago fullstack 사이드 프로젝트를하며 ( html, css, vanillaJS 그리고 JS프레임워크 )