분산락이란?
여러 서버에서 공유된 데이터를 제어하기 위해 사용하는 기술
이 이미지처럼 하나의 자원(상품 재고)에 여러 서버에서 동시에 접근을 한다면 데이터 정합성이 깨질 수 있다.
이때 레디스를 사용해서 잠금(락)을 걸어주어 한번에 하나의 서버에서만 자원에 접근하도록 제한하는것이 분산락이다.
주문서버와 정산서버가 거의 동시에 레디스에 Lock을 시도했지만 주문서버가 성공했고, 주문서버가 상품재고에 요청을 보낼 수 있는 자격이 생긴것이다.
적용 상황
다음 그림과 같이 멀티 인스턴스 환경에서 각 인스턴스마다 DB에 어떤 트랜잭션을 날리는 스케줄러가 동작하고있을 때
READ라면 상관없겠지만 DB의 상태를 변경시키는 트랜잭션을 동시다발적으로 날리면 우리가 예상한 결과와 달라질 것이다.
이 코드처럼 10초마다 디비의 count를 1씩 증가시켜주는 스케줄러가 있다고 해보자.
pm2를 사용하여 로컬에서 10개의 인스턴스를 실행시켜보면
이렇게 스케줄러가 한 번 실행될때마다 10개의 인스턴스에서 각각 count를 1씩 더하는 쿼리가 발생하게되고 결과적으로 한번에 10씩 count가 더해진다
적용하기
레디스를 추가하여 Lock을 획득한 인스턴스만 쿼리를 발생시키도록 제한해보자
레디스로 분산락은 이렇게 구현하였다.
setLock은 레디스 저장소에 key-value 하나를 추가해주는 것이고 이 동작이 10개의 인스턴스에서 동시에 실행되겠지만 그 중에서 가장 빠른 인스턴스만 성공할 것이고 나머지 9개의 인스턴스는 락에 실패할 것이다. (이미 존재하는 key이기에)
모종의 이유로 delLock()이 동작하지 않을 수 있기에 EX 설정을 하여 자동으로 expire 되도록 내부에 설정해주었다.
NX설정은 이미 key가 존재하면 생성을 막도록 하는 설정이다.
아무튼 10개의 인스턴스에서 락에 성공한 인스턴스만 쿼리를 실행하는 것을 볼 수 있다.
'NodeJS' 카테고리의 다른 글
[NodeJS] Sequelize로 마이그레이션 진행하기 (0) | 2022.03.19 |
---|---|
[NodeJS] Swagger 자동 생성 라이브러리 swagger-autogen (0) | 2021.11.12 |
[NodeJS] 기본값 파라미터(default parameter value) (0) | 2021.10.29 |
[NodeJS] Jest mock을 사용한 단위테스트 (0) | 2021.09.27 |
[NodeJS] tsconfig.json에 대해 알아보자 (0) | 2021.09.25 |