동시성 제어방법 개념 정리

dojinyou·2023년 4월 23일
2

Java - Synchronized

  • 설명
    • 자바에서 제공하는 Synchronized 키워드를 이용하여 쓰레드 간의 동시성을 제어합니다.
    • Synchronized 키워드는 크게 함수에 적용하거나 문(statements)에 적용하여 사용합니다.
    • 모든 개체들은 연결된 고유한 잠금이 존재하고 이를 획득하고 작업이 완료되면 해제하는 방식으로 접근을 제어할 수 있습니다. 동기화된 메서드는 메서드가 호출될 때 대응하는 개체의 고유한 잠금을 획득하고 메서드가 반환할 때 고유한 잠금을 해제합니다.
  • 특징
    • 쓰레드 접근을 제어하는 기술이기 때문에 동시성을 제어할 수 있는 범위가 서버 한대. 따라서 복수의 서버에서 작업할 경우 원하는 동시성 제어가 이루어지지 않을 수 있습니다.
    • 잠금 획득을 위해 쓰레드가 대기하기 때문에 성능적으로 많은 손해가 발생할 수 있습니다.
  • 이외에도 volatile 키워드나 Atomic package의 클래스들을 이용해서 제어할 수도 있습니다.

DB - Pessimistic Lock

  • 설명
    • 비관적 락(Pessimistic Lock)은 실제 데이터베이스에서 제공하는 Lock을 사용하여 동시성을 제어하는 방법입니다.
    • MySQL에서 쓰기 작업을 위한 exclusive_lock 을 제공합니다. 쓰기 작업을 위해 해당 행에 대한 다른 트랜잭션의 읽기를 방지합니다. InnoDB의 기본 격리 수준인 REPEATABLE READ에서는 일관된 읽기로 인해 해당 행에 대한 읽기를 허용합니다.
  • 특징
    • DB의 락을 이용하기 때문에 교착 상태에 빠질 수 있습니다.
    • 물리적으로 DB가 분리되어 있다면 락을 걸 수 없습니다.

DB - Optimistic Lock

  • 설명
    • 낙관적 락(Optimistic Lock)은 Version이란 필드를 통해 동시성을 제어하는 방법입니다.
    • UPDATE 시에 조회한 Version 정보를 이용하여 업데이트 요청을 보내고, 해당 데이터가 이미 업데이트되어 Version이 변경되었다면, 대상을 찾지 못하게 되어 업데이트가 되지 않도록 합니다.
  • 특징
    • 업데이트 실패 이후 별다른 조치가 없다면 해당 요청이 버려지게 되므로, 재시도 혹은 재시도 요청 메세지를 보내는 등의 적절한 사후 조치가 필요합니다.

DB - Named Lock

  • 설명
    • 이름 있는 락(Named Lock)은 실제 데이터가 아닌 고유한 이름으로 식별되는 락을 사용하여 동시성을 제어하는 방법입니다.
    • MySQL에서 제공하는 Locking FunctionsGET_LOCK()RELEASE_LOCK()을 통해 named lock을 이용할 수 있습니다.
  • 특징
    • 트랜잭션의 종료나 롤백과는 별개로 named lock에 대한 해제를 해주어야 합니다.

Redis - Lettuce 활용

  • 설명
    • Setnx(Set if not exist) 명령어를 이용하여 락을 구현하여 동시성을 제어하는 방법입니다.
    • Setnx 명령어는 특정 Key가 존재하지 않을 경우에 set을 하는 명령어로 value가 없을 때만 값을 셋팅하기 때문에 값을 셋팅하고 삭제하는 방식을 통해 락의 효과를 만들어냅니다.
  • 특징
    • 트랜잭션의 종료나 롤백과는 별개로 named lock에 대한 해제를 해주어야 합니다.
    • Spin Lock 방식으로 retry 로직을 개발자가 작성해주어야 하며, 부하를 줄이기 위해 반복 시도의 적절한 갭을 주어야 합니다.

Redis - Redisson 활용

  • 설명
    • Redisson이라는 라이브러리를 이용하여 락을 구현하여 동시성을 제어하는 방법입니다.
    • RLock.tryLock 메서드를 통해 락 획득을 요청 후 대기 시간 내 획득할 경우 임대 시간만큼 임대 할 수 있으며, 작업 종료 후 unlock 메서드를 통해 락을 해제할 수 있습니다.
  • 특징
    • 라이브러리에서 재시도에 대한 작업을 제공하여 별도로 구현하지 않아도 됩니다.
    • pub/sub 형태로 구현되어 있어 redis에 부하가 적게 걸립니다.

reference

profile
더 좋은 세상을 만드는 데 기술로 기여하고 싶습니다

0개의 댓글