ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 분산락을 활용한 동시성 문제 대비하기 (with Redis) - 1
    Back-End/Redis 2024. 2. 5. 09:26
    728x90

    분산락이란?

     
     
     
    Redis 공식 문서를 들어가보면, 다음과 같이 설명이 되어있다.
     

    Distributed locks are a very useful primitive in many environments where different processes must operate with shared resources in a mutually exclusive way.

     
     
    즉, 다중 프로세스가 공유 자원에 접근 할 때, 데이터의 결함이 발생하지 않도록 상호 배타적인 방식으로 자원을 이용할 수 있도록 하는 기법이라고 할 수 있다.
     
     
     

    자바에서 제공하는 동시성 문제 해결 방안

     
     
    자바에서는 sychronized 기능을 제공한다. 즉, 멀티스레드 프로세스 환경에서 A스레드가 작업을 진행 하던 중 B스레드에게 제어권이 넘어가고, B 스레드가 A 스레드가 사용하던 공유 자원에 접근하여 작업을 진행한다면, 예상치 못한 결과를 얻을 수 있는데, 이러한 문제를 막을 수 있는 방법이다.
     
    추가적으로, wait() &  notify(), Lock과 Condition을 이용한 동기화 등 여러가지 기능이 존재한다. (자세한건 구글링을.!)
     
    하지만 위제 제시된 기능들은 단일 프로세스 환경, 즉 일반적인 서버 환경에서 하나의 서버 인스턴스만 띄운 경우에 유효한 방법이라고 할 수 있다. 만약 여러 개의 서버 인스턴스가 띄워진 환경인 경우, synchronized 기능을 사용하더라도 각각의 인스턴스마다의 thread-safe만을 보장하기 때문에 동시에 여러 인스턴스의 공유 자원에 대한 접근의 배타성을 보장하지는 못한다.
     
     
    분산락은 이러한 환경에서의 상호 배타적인 접근을 가능하게 한다. 대표적으로 redis java client인 redisson의 경우 '발행/구독(pub/sub)' 방식을 사용한다. 해당 방식은 락이 해제될 때마다 subscribe 중인 클라이언트들에게 '락 획득을 시도해도 된다.'는 알림을 보내게 되는데, 클라이언트 측에서는 락 획득에 실패했을 때 redis에 계속 락 획득 요청을 하는 과정이 사라지게 되며, 계속된 요청으로 인한 부하가 발생하지 않게 한다.
     
     
     

    프로젝트 적용 당위성

     
     
    현재, 개인 프로젝트에서 새로 도입 할 기능 중 '로또' 기능이 있다. 
    해당 기능을 대략적으로 설명하면, 매일 00시에 유저마다 로또 추첨 기회를 1개로 세팅하게 되며, 일정 확률로 아메리카노나 바나나우유와 같은 기프티콘이 당첨될 수 있다.
    (매우 높은 확률로 꽝)
     
    해당 기능에서 유의할 점은 만약 유저가 악의를 갖고 굉장히 짧은 시간 안에 여러 개의 요청을 보낼 시, 
    로또 추첨 일일 제한 횟수인 1번을 넘어서 사용할 수 있다는 문제가 있다. (즉 기회는 1번 뿐이었지만, 실제로는 여러 번 추첨을 진행을 하게 되는 상황)
     
    물론 유저도 사실상 거의 존재하지 않고(ㅠㅠ), 그에 따라 서버 인스턴스와 DB 또한 단 1대 뿐이기 때문에
    단순히 DB에 Lock을 거는 방법 만으로도 충분히 대비가 가능한 이슈라고 생각한다.
    하지만 추후 확장성을 고려하였을 때, 또한 TPS가 많은 서비스를 언제 운영하게 될 지 모르기 때문에
    미리 분산 락을 적용 해 보는 것도 괜찮다는 생각이 들어서 진행을 하게 되었다.
     
     
    분산락을 활용한 동시성 문제 대비하기 (with Redis) - 2(준비중)

    댓글

Designed by Tistory.