MSA환경에서 구현하는 Redis Lock

MONA·2025년 3월 25일

나혼공

목록 보기
62/92

왜 필요한가?

  • MSA 환경에서는 여러 서비스가 각자 독립적으로 동작함
  • 동시에 같은 데이터에 접근하거나, 수정하려는 시도가 발생할 수 있음
  • Lock을 이용해서 한번에 한 서비스만 데이터 관련 작업을 할 수 있게 방지해야 함

분산 락 (Distributed Lock)

  • 여러 서버 또는 인스턴스가 동시에 같은 자원에 접근하지 않도록 막는 방법
  • MSA에서는 여러 서비스 인스턴스가 동일 자원(DB row, 파일, 재고정보 등)에 접근할 수 있으므로 데이터 충돌 방지용으로 락이 필요함

Redis와 Lock

왜 Redis로 Lock을 거는가?

  • Redis는 속도가 빠르고 중앙에서 관리 가능한 인메모리 저장소이기에, 분산 환경에서 락 관리용으로 적합함

기본 아이디어

  1. 어떤 리소스를 사용할 때
  2. Redis에 'Lock을 걸었다'는 키를 먼저 저장
  3. 다른 서비스는 키를 먼저 확인하고, 키가 있을 경우 대기하거나 실패 처리
  4. 작업이 끝날 시 키를 삭제해서 락을 해제함
  • 반드시 만료 시간을 주고, 락 해제 시 해당 락을 해제하는 게 맞는지 확인하고 해제해야 함

  • 기본적으로 SETNX 명령어로 락을 설정함

SET lock_key lock_value NX EX 10
  • NX: 키가 없을 때만 설정(중복 방지)
  • EX 10: 10초 후 자동 만료(장애 발생 시 락이 영원히 유지되는 것 방지)

락의 종류

1. 단순 락(SETNX 기반)

Boolean isLocked = redisTemplate.opsForValue().setIfAbsent("lock:order:123", "uuid", 10, TimeUnit.SECONDS);
  • 간단하고 빠른 방법
  • 클라이언트가 죽으면 락이 안 풀릴 수도 있음(만료시간 설정 필수), 여러 노드에서 동시에 락을 걸려고 하면 race condition 발생 가능

race condition

  • 경쟁 상태
  • 여러 작업(스레드/프로세스)이 공유 자원에 동시에 접근하거나 수정할 때, 실행 순서에 따라 결과가 달라지는 상황
  • 누가 먼저 실행되느냐에 따라 결과가 달라지기에 예측 불가능하고 오류가 발생할 위험이 큼. 아주 소름돋는 상황이다.
  • 멀티스레드나 분산 환경에서 자주 발생하는 문제로, 동시성 이슈의 대표적인 사례

race condition 발생 조건

  • 공유 자원이 있을 때(변수, DB row, 파일 등)
  • 둘 이상의 실행 흐름(스레드, 인스턴스, 프로세스)이 동시에 접근할 때
  • 접근 순서에 따라 결과가 달라질 수 있을 때

2. RedLock(레드락 알고리즘)

작동 방식

  • 최소 3개 이상의 Redis 인스턴스 필요
  • 클라이언트가 동일한 키를 N개의 Redis 중 과반수(Majority) 이상에서 락을 획득해야 유효
  • 락 획득 실패 시 전체 롤백

특징

  • 장애에 강함
  • 네트워크 분리나 Redis 일부 다운 시에도 안전하게 락을 관리할 수 있음

3. Redisson 기반 분산 락

Redisson : Java용 Redis 클라이언트. 분산 락을 쉽게 구현할 수 있게 도와줌

  • 분산 락을 안정적으로 구현할 수 있음
  • 락 재시도, 만료, 해제 등 자동 처리
  • 클러스터/ 싱글 Redis 모두 지원
profile
고민고민고민

0개의 댓글