이론 정리/Spring boot

spring boot에서 redis를 사용한 동시성 이슈 처리

철매존 2022. 12. 26. 00:26
728x90

Redis를 활용해서 동시성 이슈를 방지하는 두 가지 방법이 있다.

  • Lettuce
    • setnx 명령어를 활용하여 분산락 구현
      • set if not exist의 줄입말이다.
        • key와 value를 set할 때 기존의 값이 없을 때에만 set하기
    • spin lock 방식
      • 락을 사용하는 쓰레드가 이걸 사용할 수 있는지 매번 시도하는 방식
      • retry 로직을 개발자가 직접 구현해야 한다.
  • Redisson
    • pub-sub 기반으로 Lock 구현 제공
      • 앞선 쓰레드가 자신이 끝나면 다음 쓰레드에 접근하라고 할려줌

Lettuce

요런 식으로 lock을 사용하고 setnx를 써서 하면

  • 이전에 만들어둔게 없음
    • 1 -> 만들어짐
  • 이전에 만들어둔게 있음
    • 0 -> 안됨

이전에 있던걸 지우고 다시하면 잘 되는것도 확인 가능

구현이 간단하다는 장점이 있다.

하지만 spin lock 방식이므로 redis에 부하를 줄 수 있다.
그래서 thread.sleep을 사용해서 텀을 주는것이 좋다.

Redisson

일단 터미널에서 cli를 두개 띄운다.

하나의 cli에서 이렇게 ch1을 구독해주고

다른 cli에서 ch1에 hello를 발행해주면

기존 cli에서 이렇게 메세지를 받을 수 있다.

redisson은 자신이 점유하는 lock을 해제할 때 ch에 메세지를 보내주어서 그걸 구동 중인 쓰레드에 보내준다.

그래서 다른 쓰레드는 이 메세지를 받은 후에 획득을 시도한다.

이 방식은 lock해제가 되었을 때 한 번 / 몇 번만 시도해서 redis에의 부하를 줄여준다.

pub-sub기반의 구현 방식이기 때문에 redis에의 부하를 줄여준다는 장점이 있다.
하지만 구현이 조금 복잡하고, 별도의 라이브러리를 사용해야 한다는 단점이 있다.

그래서 둘중 뭐가 좋냐?

  • Lettuce
    • 구현이 간단하다.
    • spring data redis를 이용하면 lettuce가 기본이기 때문에 별도의 라이브러리 사용이 불필요
    • spin lock방식이기 때문에 동시에 많은 쓰레드가 대기중이라면 redis에의 부하가 간다.
  • Redisson
    • 락 획득 재시도 기본 제공
    • pub-sub 방식으로 구현되어 lettuce와 비교했을 때 redis에 부하가 덜 간다.
    • 별도의 라이브러리를 사용해야 한다.
    • lock을 라이브러리 차원에서 제공해주어서 사용법에 대한 공부가 필요하다.

실무에서?

  • 재시도가 필요하지 않은 lock은 lettuce 활용
  • 재시도가 필요한 경우에는 redisson 활용