Skip to content

Conversation

kilhyeonjun
Copy link
Contributor

@kilhyeonjun kilhyeonjun commented Oct 31, 2024

요구사항

  • 나의 시나리오에서 발생할 수 있는 동시성 이슈에 대해 파악하고 가능한 동시성 제어 방식들을 도입해보고 각각의 장단점을 파악한 내용을 정리 제출 (좌석 선점(예약), 유저 포인트 잔액)
    • 구현의 복잡도, 성능, 효율성 등
    • README 작성 혹은 외부 링크, 프로젝트 내의 다른 문서에 작성하였다면 README 에 링크 게재

작업 내용

지난 주차에 #26 좌석예약의 경우는 낙관적락을 적용을 하면서 JPA 비관적 락과 낙관적 락 및 재시도 글에서 낙관적락과 비관적락을 분석을 했습니다.

콘서트 시나리오에서 발생할 수 있는 동시성 이슈에 대해 파악하고 다양한 제어 방식을 공부하여 도입하고 테스트를 진행하여 블로그에 작성하였습니다.
Spring Boot 콘서트 예약 시나리오 동시성 문제 분석

해당 내용을 정리하자면
콘서트 시나리오에서 발생할 수 있는 case는 좌석 섬점(예약), 유저 포인트 충전/사용 총 3가지의 경우에서 발생 할 수 있습니다.
그리고 이번 보고서엔 message queue로 인한 방식은 인프라 세팅 및 러닝 커브가 높아 제외하였으며 비관적락, 낙관적락, 분산락 3가지 방법으로 진행하였습니다.
분산락의 경우엔 redis를 사용하여 작업하였습니다.
그리고 동시성 제어방식을 선택은 분산환경일 경우를 고려하여 비관적락은 제외하였습니다.

1. 좌석 선점

좌석 선점의 경우 여러사용자가 하나의 좌석을 동시에 예약할 경우 여러명에게 예약 내역이 남을 수 있습니다.
해당 경우는 최초의 요청만 성공하고 나머지 요청은 실패하게 됩니다.
충돌은 많으나 재시도가 필요없는 로직이여서 낙관적락을 사용하기로 했습니다.

2. 유저 포인트 충전

유저 포인트 충전의 경우 단일 유저에게 동시에 여러 충전 요청이 발생하는 경우입니다.
여러 충전 요청외에 포인트 사용도 동시에 발생하면 동시성 문제가 발생할 수 있으나 이번엔 어느 락이 좋을지 확인하는 경우여서 생략하겠습니다.
동시에 온 포인트 요청이 서로 다른 요청일 경우 전부 충전이 되어야하지만 갱신 손실(lost update)가 발생하여 누락될 수 있습니다.
해당 case는 발생 가능성이 낮으며 충돌 가능성도 낮습니다. 하지만 낙관적락으로 처리하기엔 실제 돈과 연관된 정보이다보니 확실하게 처리되야한다고 생각을 했으며 혹시 모를 충돌이 발생했을 경우 retry하는 비용이 비싸다고 생각하여 분산락을 사용하였습니다.

3. 유저 포인트 사용 (예약 내역 결제)

유저 포인트 사용 (예약 내역 결제)의 경우 동시에 여러 사용 요청이 발생하는 경우입니다.
2. 유저 포인트 충전와 마찬가지로 같은 공유 자원이기에 같이 고려해야되나 락을 선택하기 위한 분석이라 생략하였습니다.
동시에 온 포인트 사용 요청이 위와 같이 갱신 손실이 발생하여 누락될 수 있습니다.
분산락을 사용하여 처리하기로 했으며 사유도2. 유저 포인트 충전과 동일합니다.

리뷰 포인트

  • 분산환경에선 분산된 DB에서 동시성 제어를 위해 분산락을 쓰는데 이땐 비관적락을 별도로 안쓰는게 맞을까요?
  • 분산락의 경우 Redis를 사용해서 Redisson라이브러리로 pub/sub구조로 가져갔는데 이건 별도의 커넥션을 유지하지 않고 이벤트를 수신했을때 재 요청 거는 구조라 일반 비관적락에 비해 시간이 많이 지연되는 게 맞는 걸까요?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant