안녕하세요. 지식공유자 최상용입니다.
많은 오픈소스에 기여한 경험이 있는 현직 백엔드 개발자입니다.
- Spring Data Mongo Contributor
- querydsl Contributor
- grpc-kotlin Contributor
- ksp Contributor
- mybatis Contributor
강의
수강평
- 재고시스템으로 알아보는 동시성이슈 해결방법
게시글
질문&답변
재고 감소와 쿠폰 발급은 왜 서로 다른 방식으로 동시성을 제어하나요?
차니님 안녕하세요. 질문주셔서 감사합니다.Q1. 두 경우 모두 한정된 수량을 여러 요청이 동시에 차지한다는 점에서는 비슷해 보입니다. 그렇다면 쿠폰도 이벤트 테이블에 잔여 수량을 100개나 300개로 설정하고, 재고처럼 수량을 차감한 뒤 사용자 쿠폰을 생성하는 방식으로 구현할 수 있지 않을까요?A1. 말씀하신것처럼 쿠폰도 이벤트 테이블에 잔여수량을 설정한 후 락을 재고처럼 수량을 차감한 뒤 사용자쿠폰을 생성하는 방식으로 구현할 수 있습니다.이 강의에서 redis 를 통해 제어하고 kafka 를 활용한 이벤트방식을 사용한것은 아래와 같은 이유입니다."선착순 이벤트" 특성상 짧은순간에 많은 트래픽이 몰리게됩니다. 이벤트 테이블에 잔여수량을 설정한 후 락을 재고처럼 수량을 차감한 뒤 사용자쿠폰을 생성하는 방식을 사용할 수 있겠지만 디비의 처리속도보다 redis 의 처리속도가 빠르며 단순히 개수만 처리하면 되기에 redis 를 사용하는것이 합리적이라고 판단하였습니다.server 에서 바로 쿠폰을 생성할 수 있겠으나 많은 쓰기트래픽이 한번에 몰리게 되면 데이터베이스에 부하를 줄 수 있습니다. "선착순 이벤트" 는 발급이 되는것은 중요하지만 약간의 딜레이는 있어도 된다고 생각하여 kafka 를 활용하였습니다.kafka 를 통해 자연스럽게 처리량을 조절할 수 있게되며 오류발생시에도 재처리를 쉽게 보장할 수 있습니다."짧은 시간 에 몰릴 수 있는 트래픽" 에 대응하기 위하여 이러한 방법을 선택하였다고 생각해주시면 좋을 것 같습니다.Q2. 강의에서는 쿠폰 발급의 정합성을 위해서 전체 로직에 락을 걸 필요가 없다고 하셨는데, 그러면 반대로 재고 감소 같은 경우도 마찬가지로 재고 감소의 정합성을 위해 전체로직에 락을 걸 필요 없이 다른 방법으로 하는게 더 나은 방법 아닌가요??A2. 재고같은경우는 성능을 일부포기하더라도 "강한 정합성" 을 보장하는것이 더 중요한 도메인입니다.그렇기때문에 정합성을 보장하기 위한 락은 필수적이라고 생각됩니다.이 강의에서 쿠폰 발급의 정합성을 위해 전체로직에 락을 걸 필요가 없다는것은 redis 를 활용하여 개수를 체크함으로써 정합성을 보장할 수 있기때문입니다.설명이 부족했거나 추가적인 질문이 있으시다면 언제든 질문 주세용!감사합니다.
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 22
질문&답변
보상트랜잭션 실패시 데이터베이스 저장하는데 그것조차 실패하면 어떻게 하나요??
HJ 님 안녕하세요.Q1. 여기서 궁금한게 실무에서는 어느정도 장애상황까지 대비를 하는지 궁금합니다.A1. 실무에서는 상황마다 어디까지 대비하는지가 다릅니다.로그를 잘 남겨 실패한 기록조차 남기지 않을수도 있습니다.에러로그에 재시도를 할 수 있는정보를 남긴 후에 수동으로 처리하는 방법입니다.수동으로 처리를 하는일이 잦아져 보완이 필요할 경우 데이터를 쌓은 후 자동으로 처리할 수 있게 만들 수도 있습니다.Q2. 실무에서는 트레이드 오프를 어느정도까지 하는지 궁금합니다A2. 위 답변과 동일합니다. 서비스마다 상황이 다르므로 정답이 없습니다.규모에 따라 어느서비스에서는 당연히 해야할것들이 어느서비스에선 오버엔지니어링이 될 수 있습니다.또한 어느서비스에선 수동으로 처리를 해도 무방한것들이 어느서비스에선 수동으로 처리할 수 없을 빈도, 규모일 수 있습니다.예시로 들어주신 것중 예를들어 데이터베이스 혹은 카프카에 데이터를 못쓰는 상황을 말씀해주셨습니다.데이터베이스, 카프카에 데이터를 쓰다가 오류가 발생하는경우는 극히 드물며 이는 곧 서비스장애일 확률이 높습니다.반면 강의에서 예시로 들었던 재고차감 롤백시 실패, 포인트 차감 롤백시 실패는 외부 API 를 사용하는것이고 이때 오류가 발생하는 경우는 충분히 일어날 수 있는 일입니다.이처럼 평소에 일어날 수 있는일인가? 를 고려해본 후 평소에도 일어날 수 있는일이라면 대비를 하는게 맞고, 데이터베이스 혹은 카프카장애처럼 평소에 일어날 일이 (거의)없는 상황에서는 추후 수동으로 처리할 수 있도록 에러로그를 남기는 정도로 대비를 할 것 같습니다.Q3. 어떤 책으로 시스템 설계를 공부 하시는지도 궁금합니다A3. 시스템 설계를 특정하여 공부하지는 않았습니다만, 제가 보고 도움이 됐던 책들을 말씀드리자면데이터 중심 애플리케이션 설계가상 면접 사례로 배우는 대규모 시스템 설계 기초1가상 면접 사례로 배우는 대규모 시스템 설계 기초2이벤트 기반 마이크로서비스 구축개발자를 위한 레디스Kafka 핵심가이드추가로 읽어보진 않았지만 목차를 보았을 때 괜찮아 보였던 책들주니어 백엔드 개발자가 반드시 알아야 할 실무 지식스타트업 서비스 설계는 처음인데요정도인듯합니다.감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 44
질문&답변
레디선 테스트코드에서 채널이름은 없어도 되는건가요?
gibbs 님 안녕하세요.답변이 늦어져서 죄송합니다.redis cli 를 활용한 테스트는 pub-sub 기능이 어떻게 동작을 하는지 눈으로 확인해보는 목적이었습니다.그러기 위해선 특정 채널을 명시적으로 입력을 하여야 했습니다.자바소스로 옮겨서 테스트 할 때는 채널명을 지정하지 않은이유는 Redisson 라이브러리를 활용하여 락획득을 시도할때 키의 이름을 딴 채널명을 라이브러리내부에서 구독을 하게 되며 해제시에 해당 채널로 해제 메시지를 보내기때문에 별도로 지정하지 않아도 되는것입니다.감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 84
질문&답변
주문이벤트 발행에서 이벤트 발행을 동기적으로 처리하는 이유
발그레지는개발님 안녕하세요!2가지로 나누어볼 수 있을것 같아요.afterCommit 에서 처리를 한 이유DB 의 트랜잭션과 분리하여 이벤트는 발행되고 DB 는 롤백되는 상황을 막기 위함입니다.동기로 발송한 이유kafka 에 이벤트를 발행하는것은 소요시간이 그리크지 않은 작업으로 비동기로 할 이유가 없었기때문에 동기적으로 처리하였습니다.전송 실패처리이것은 동기, 비동기 상관없이 잘 처리가 되어야 할 것 같습니다.말씀하신대로 전송 보장이 되어야 한다면 outbox pattern 을 활용하여 처리할 수 있을 것 같습니다.추가적인 질문이 있으시다면 말씀해주세요!
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 77
질문&답변
spring-retry가 spring-core 패키지로 편입되었습니다.
도등어님 안녕하세요!트러블슈팅을 한 경험을 공유해주셔서 감사드립니다. 😃
- 좋아요수
- 2
- 댓글수
- 1
- 조회수
- 153
질문&답변
TCC 주문 도중 문제 발생 시 상태 해소 전략 관련 질문입니다.
도등어님 안녕하세요.말씀하신대로 reservation entity 가 맞습니다.product_reservation, point_reservation 을 의도했습니다.감사합니다.
- 좋아요수
- 0
- 댓글수
- 1
- 조회수
- 107
질문&답변
TCC PointService tryReserve 구현 관련 질문입니다.
도등어님 안녕하세요.지금 다시보니 로직에 버그가 있었네요 ㅠㅠ 아래와 같이 예약된금액과 예약할 금액을 모두 빼주어야 할 듯 합니다.public void reserve(Long reserveAmount) { long reservableAmount = this.amount - reserveAmount - this.reservedAmount; if (reservableAmount 말씀해주셔서 감사합니다. 강의내용은 추후 업데이트 하도록 하겠습니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 91
질문&답변
[TCC 구현하기(2) - 동시성문제 해결하기] 질문
홍승현님 안녕하세요.질문에 대한 답변이 늦어져서 죄송합니다.경합이 자주, 많이 생기는 경우에는 낙관적락보다 비관적락이 유리한것이 맞습니다.다만, 커머스의 특성상 주문이 많더라도 하나의 품목에 동시에 주문이 오는경우는 적을것이라고 생각됩니다.이러한 특성을 생각한다면 여전히 낙관적락이 유리할것 같습니다.강의에 대해 좋은말씀 해주셔서 감사합니다!
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 118
질문&답변
ApplyService와 Consumer서비스의 db공유?
차성호님 안녕하세요!말씀하신대로 consumer 와 service 에서 동일한 db 를 공유하고 있기에 가능한것입니다.감사합니다.
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 89
질문&답변
안녕하세요 강사님 질문있습니다.!!
정인호님 안녕하세요.제가 이해한게 맞다면 OrderConfirmEvent 를 발행하면 재고, 쿠폰, 적립금을 한번에 처리를 한다고 이해를 했는데요.이렇게 되면 예외를 핸들링하기가 힘들어지기때문에 순차적으로 진행을 할 것 같습니다.예를들어 OrderConfirmEvent 를 발행하면 재고를 감소시키고 재고감소에 성공하면 쿠폰을 소진시키고 주문이 정상적으로 되면 적립금을 주는식으로 개발을 할 것 같습니다.병렬로 수행하게 되면 다른작업들이 끝났는지 안끝났는지 검사를 해야하는 로직을 추가해야 하기때문에 로직이 복잡해질것 같기때문입니다.만약 병렬로 수행을 해야한다면 실패이벤트를 받았을 때 다른 이벤트들이 종료되었는가? 에 대한 체크를 해야 할 것 같습니다.쿠폰이 실패되었을 때 재고는 처리되었는지? -> 재고가 처리되어있지 않다면 기다렸다가 다시 처리 감사합니다.혹시 또 질문이 있으시다면 댓글로 남겨주세요!
- 좋아요수
- 0
- 댓글수
- 2
- 조회수
- 116






