프로젝트를 진행하면서 선착순 쿠폰 발급을 진행시 중복발급이 발생하여 이를 해결하기 위해 여러 고민들을 하였고 Kafka + Redis를 활용한 대기열 시스템으로 개발하였습니다.
case
이벤트성 상품 할인 쿠폰 이벤트 시 중복하여 쿠폰이 발생하는 경우
이러한 문제점이 발생했습니다, 그렇담 왜 이러한 중복 발급이 발생하는걸까요?
선착순 쿠폰 발급을 동시에 많은 사용자가 요청 시 쿠폰 수량을 줄이기전에 다른 트랜잭션이 읽을 경우 중복 발급이 발생되어집니다.
현재 프로젝트의 경우 분산환경에서 N개의 서버를 구동중에 있습니다.
이러한 락을 처리하기 위해 보편적으로 많이 사용하는 낙관적락 비관적락이 있으나 현재 저의 상황에서는 맞지 않다 판단하여 적용하지 않았습니다.
그럼에도 불구하고 낙관적 락, 비관적 락은 많은 부하가 있지 않은 경우 훌륭한 선택지가 될 수 있다고 생각합니다.
기존의 Lettuce 방식은 스핀락 기반으로 동작하여 Redis에 지속적으로 요청을 보내는 방식이었습니다. 이는 Redis 부하를 유발하는 단점이 있었기 때문에, Redisson의 Pub/Sub 기반 분산락을 적용하여 성능을 개선하였습니다.
여러 서버가 있는 분산 환경에서 분산락은 좋은 선택지가 될 수 있다 생각합니다.
앞선 문제들을 해결하기위해 Kafka + Redis를 활용한 대기열을 도입하였습니다.
아키텍처
1. Kafka를 활용한 요청 대기열 구성
2. Redis Sorted Set을 활용한 쿠폰 발급 요청 정렬
3. 쿠폰 발급 배치를 활용한 빠른 Insert 처리
쓰레드 | 호출수 | TPS | 초과발급수 |
---|---|---|---|
2 | 8,597 | 152.4 | 247 |
4 | 10,793 | 191.6 | 672 |
8 | 12,613 | 231.3 | 1353 |
10 | 13,947 | 247.3 | 1678 |
16 | 14,836 | 253.4 | 2850 |
쓰레드 | 호출수 | TPS | 초과발급수 |
---|---|---|---|
2 | 4,132 | 76.1 | 0 |
4 | 4,653 | 82.7 | 0 |
8 | 4,677 | 85.1 | 0 |
10 | 4,717 | 86.8 | 0 |
16 | 6,243 | 110.9 | 0 |
쓰레드 | 호출수 | TPS | 초과발급수 |
---|---|---|---|
2 | 27,119 | 500.9 | 0 |
4 | 32,530 | 820.0 | 0 |
8 | 37,742 | 751.1 | 0 |
10 | 39,542 | 758.4 | 0 |
16 | 46,382 | 882.3 | 0 |
선착순 쿠폰 발급 시스템의 초과 발급 문제를 해결하기 위해 Redis 기반 분산락과 Kafka 대기열 시스템을 비교해 개발을 진행해 보았습니다.
최종적으로 Kafka와 Redis Sorted Set을 활용한 대기열 시스템이 높은 성능을 보이며, 초과 발급을 방지하면서도 빠른 응답성을 유지할 수 있었습니다.
선착순 쿠폰 발급뿐만 아니라 동시 요청이 많은 서비스(티켓팅, 한정판 판매 등) 에서도 활용할 수 있다 생각하며 오늘의 글은 여기 까지 작성하도록 하겠습니다.