본문으로 바로가기

https://www.inflearn.com/course/동시성이슈-재고시스템/dashboard

 

재고시스템으로 알아보는 동시성이슈 해결방법 - 인프런 | 강의

동시성 이슈란 무엇인지 알아보고 처리하는 방법들을 학습합니다., - 강의 소개 | 인프런

www.inflearn.com

강의소개 및 환경세팅

작업환경 세팅
 

작업환경 세팅

작업환경 세팅 docker 설치 brew install docker brew link docker docker version mysql 설치 및 실행 docker pull mysql docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 --name mysql mysql docker ps docker: no matching manifest for linux/arm64

docs.google.com

재고시스템 만들어보기

소스코드
 

GitHub - sangyongchoi/stock-example

Contribute to sangyongchoi/stock-example development by creating an account on GitHub.

github.com

 

프로젝트 생성
재고 감소 로직작성 & 문제점
 

Java] ExecutorService란?

❓ ExecutorService란? 병렬 작업 시 여러 개의 작업을 효율적으로 처리하기 위해 제공되는 JAVA 라이브러리이다. ❔ ExecutorService가 없었다면? 각기 다른 Thread를 생성해서 작업을 처리하고, 처리가 완

simyeju.tistory.com

 

Java - CountDownLatch 사용 방법

CountDownLatch는 어떤 쓰레드가 다른 쓰레드에서 작업이 완료될 때 까지 기다릴 수 있도록 해주는 클래스입니다. countDown()이 호출되면 Latch의 수가 1개씩 감소하며, await()은 Latch의 숫자가 0이 될 때

codechacha.com

 

Synchronized 이용해보기

Synchronized 이용해보기
  • Java 언어로 동시성 메소드에 synchronized 를 붙여준다.
  • Transactional 어노테이션 때문에 정상적으로 되지 않음 , 없을 경우에는 정상적임
    - 싱글톤 서비스에 대해 여러 스레드가 하나의 메소드에 접근하여 진행할 경우, 정상적으로 처리됨
    - Transaction 어노테이션 으로 AOP 가 작동하여 프록시 객체를 만들어 진행한다.
      - Transaction 을 시작하고 끝날때에 대한 동시성 처리가 되지 않음
      - 서비스 메소드에 대해 동시성으로 처리가 되더라도, 트랜잭션이 끝날때 동시성 처리가 되지 않아 문제가 발생한다.

문제점
  • 여러 서버가 있을 경우에 대해, 데이터에 대해 동시성 문제가 발생할 가능성이 있음 (synchronized 로 해결안됨)

 

Database 이용해보기

다양한 방법 알아보기
  • Pessimistic Lock
    - 서버1 이 데이터를 가져가면, 서버 2,3,4,5 는 접근할 수 없음
    - 데드락 발생할 수 있음
    - row나 테이블 단위로 lock을 걸음
  • Optimistic Lock
    - 실제로 Lock 을 이용하지 않고, 버전을 이용함으로써 정합성을 맞춤
    - 업데이트 쿼리에 where 절로 버전 표시
  • Named Lock
    - 이름을 가진 metadata locking
    - transaction 종료시 자동으로 해지가 되지 않아 별도로 수행해줘야함
    - 메타데이터 단위로 락을 걸음
Pessimistic Lock 활용해보기
  • 조회 쿼리에 LOCK 선언

  • 조회문에 for update 가 걸리는데 락이 걸리는 부분임

  • 충돌이 빈번하면 Optimistic Lock 보다 성능이 좋음
  • Lock 을 잡기때문에 성능 저하 발생 
Optimistic Lock 활용해보기
  • 엔티티에 Version 을 추가해줘야함
  • 호출시 버전으로 관리하여 락을 걸지 않기때문에 PessimisticLock 보다 성능상 이점이 있을 수 있음
  • 다만 실패시 재호출하는 로직을 사용자가 만들어줘야하고, 이 떄문에 빈번하게 발생한다면 오래걸릴수도 있음

Named Lock 활용해보기
  • native query의 get_lock, release_lock 활용
  • Spring boot 2.7.9 로 테스트시 아래 문제로 에러 발생

  • NameLock 은 분산락을 구현할때 사용
    PessimisticLock 은 timeout 구현이 어려움

  • 락 해제와 세션관리를 잘 해줘야함
    실제 사용시 구현방법이 복잡함

Redis 이용해보기

Redis 라이브러리 알아보기
  • Lettuce
    - setnx 명령어를 활용하여 분산락 구현
      - setnx : set if not exist
    - spin lock 방식
      - retry 로직을 개발자가 작성해야함
      - lock 획득을 반복적으로 시도하는 로직
  • Redisson
    - pub-sub 기반으로 Lock 구현 제공
    - lock 해제를 구독자에게 알려줌
      - 별도의 retry 로직을 작성하지 않아도 됨
Lettuce를 작성하여 재고감소 로직 작성하기
  • Redis Template 으로 setnx 활용하여 lock 관리
      
Redisson 을 활용하여 재고 로직 작성하기
  • Rlock 로직 사용
장단점
  • Lettuce 는 구현이 간단함 (spring data redis 는 default 가 lettuce 사용)
  • sprin-lock 이라 redis 에 부하가 감
  • Redisson 은 pub-sub 이라 redis에 부하가 덜감
  • redisson 라이브러리에 대해 공부해야함

 

Mysql과 Redis 비교하기

MySql
  • Redis 보다는 성능이 좋지않다.
Redis
  • Mysql 보다 성능이 좋다.
  • 인프라 관리 비용이 든다.