• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

Redis 를 이용한 분산 락 구현의 성능 관련 질문

23.05.31 10:50 작성 조회수 855

0

[상황 예시]
한정판 상품 A의 재고 수량 : 2000개 (1인당 1개씩만 구매 가능)

[구매 로직]
1. 데이터 베이스에서 상품 A를 조회
2. A의 재고 수량 확인
3. 재고 수량이 0보다 큰 경우 재고를 1 감소시키고 구매 완료 처리

[테스트]
2000개 스레드 생성해서 동시에 구매 요청 후 잔여 재고 확인
테스트 코드에서 2000개의 스레드가 동작하기 전 System.nanoTime() 과 모두 동작이 끝난 후 System.nanoTime() 을 통해 처리 시간을 계산하여 비교해보고 있습니다.
테스트 환경 - h2 database

 

위와 같은 방식으로 현재 프로젝트를 구현 중에 있습니다. 한정판 상품 구매의 특성 상 충돌이 잦을 것이라고 생각해서 다음과 같은 후보군으로 실험을 하고 있습니다.

1. 비관적 락
2. Lettuce 를 이용한 분산락
3. Redisson 을 이용한 분산락

제가 알아본 바나 다른 사례들을 봤을 때 Redis를 거친다고 해서 DB에서 제공해주는 락 기능을 사용하는 것과 속도면에서 차이가 거의 없는 것으로 알고 있었는데 실제 실험 결과가 다음과 같습니다.

1. 비관적 락 - 평균 6초
2. Lettuce - 평균 34초
3. Redisson - 평균 12초

Redis를 이용한 분산락 구현 코드는 강사님의 강의를 따라했는데 혹시 이런 결과가 나오는 이유가 무엇일까요?

제 추측으로는 Lettuce 를 이용하는 방식에서는 2000개의 스레드가 반복적으로 락 획득 요청을 보냄에 따라 Redis에 부하가 심해서 속도가 느려질 수 있을 것 같은데 Redisson 을 이용한 방식은 왜 느린지 전혀 모르겠습니다.

답변 2

·

답변을 작성해보세요.

0

W-Hand 님 안녕하세요.

데이터의 양, 요청수의 양에 따라서 성능이 다를 수 있습니다.

데이터와 요청수가 적다면 보시는 것과 같이 비관적락이 성능이 더 좋을 수 있으며 데이터 수가 많고 요청수가 많아질수록 redis 의 성능이 우수할 것입니다.

2000개의 스레드는 사실 많은 요청이 아니라 redis 가 느리게 보일수도 있습니다.

감사합니다.

W-Hand님의 프로필

W-Hand

질문자

2023.06.02

답변 감사합니다.
말씀해주신 바로는 요청 수의 양이 많이질수록 DB에서 제공하는 비관적 락 보다는 Redis 를 이용해 분산 락을 구현하는 것이 더 성능면에서 뛰어날 것이라고 이해됩니다.

그럼 현업에서 동시성 문제를 해결하기 위해 적용 가능한 수단들을 놓고 비교할 때 우리 서비스에서 동시에 발생 가능한 최대 트래픽이 많지 않고 서비스 로직이 단순해 데드락 발생 가능성이 없다고 판단되면 비관적 락을 이용하기도 하나요?

최대 트래픽이 많지 않을 때는 비관적락 또는 낙관적락을 고려해볼 수 있을 것 같습니다 :)

W-Hand님의 프로필

W-Hand

질문자

2023.06.03

염치 불구하고 질문 하나만 더 드리겠습니다.

Redis를 이용한 분산 락 구현 시
1. Redis 를 통해 락 획득
2. 트랜잭션 시작
3. 서비스 로직 수행
4. 트랜잭션 종료
5. 락 반납

DB를 이용한 비관적 락 구현 시
1. 트랜잭션 시작
2. 락 획득
3. 서비스 로직 수행
4. 트랜잭션 종료
5. 락 반납

과 같은 과정을 거칠 것으로 예상이 됩니다.

결국 Redis 를 이용한 방식은 인 메모리 저장소라고 하더라도 Redis 에 접근하는 과정이 추가되는 것이고 아주 약간의 시간 소요라도 있을 것으로 생각됩니다.

그럼에도 요청이 많아질 수록 Redis 를 이용하는 것이 성능 면에서 우수한 것은
'DB 락 획득-반납 소요 시간' > 'Redis 락 획득-반납 소요 시간' 이기 때문인 건가요?

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.06.02

안녕하세요, 인프런 AI 인턴이에요.

Redis를 이용한 분산락 구현의 성능 개선을 원하신다면 다음과 같은 방법들을 고려해보실 수 있습니다.

  1. Redis 클러스터를 사용하는 것을 고려해보세요. 클러스터를 사용하면 Redis에 대한 부하가 분산되어 더욱 효과적으로 분산락을 사용할 수 있습니다.
  2. Redis 클라이언트 풀링을 도입하여 클라이언트의 수를 제어해보세요. 클라이언트 수가 너무 많아질 경우 Redis에 대한 부하가 크게 증가할 수 있습니다.
  3. Redis 클러스터 내의 레플리카를 사용하여 성능을 개선할 수 있습니다. 레플리카를 사용하면 Redis 클러스터 내의 여러 노드에서 데이터의 일관성을 유지하면서 부하를 분산할 수 있습니다.

또한, 성능 향상을 위해 Redis 클러스터의 구성과 관리 방법에 대해 잘 고민하고 구현하셔야 합니다. 이를 위해 Redis 공식 문서와 관련 책 등을 참고하시면 도움이 될 것입니다.

성능 향상에 대한 시도를 하시다가 문제가 생길 경우 Redis의 설정도 살펴봐야 합니다. Redis의 설정을 최적화하면 더욱 원활한 분산락 구현이 가능할 것입니다.

추가적으로, 코드에서 사용하는 Redis 클라이언트 라이브러리와 버전에 따라 성능이 차이가 날 수 있으니 해당 부분도 신경써보세요.

마지막으로, Redisson을 사용할 경우 Lettuce보다는 성능이 향상되지만 Redisson이 제공하는 다양한 기능들로 인해 추가적인 리소스가 필요할 수 있습니다. 이 부분도 고려하셔서 적절한 구현 방법을 선택하시면 될 것 같습니다.

저희가 도움이 되었길 바랍니다. 감사합니다.