민프
[Backend][기타] TPS를 어떻게 끌어올리면 좋을까? 카카페이팀과 마켓컬리, 토스는 어떻게 대처하였는지 알아보자 본문
Backend/[기타]
[Backend][기타] TPS를 어떻게 끌어올리면 좋을까? 카카페이팀과 마켓컬리, 토스는 어떻게 대처하였는지 알아보자
민프야 2025. 6. 25. 21:00이번에 TIPS 2차 발표를 성공적으로 마치면서 결제 안정성에 대해 고민을 해보게 되었다.
이번 글에서는 실제 대규모 트래픽을 경험한 세 기업, 카카오페이, 토스와 마켓컬리가 어떻게 TPS 문제를 해결했는지를 살펴보고, 우리 시스템에 어떻게 적용할 수 있을지 정리해보자.
1. TPS란 무엇일까?
TPS (Transaction Per Second).
'초당 처리할 수 있는 트랜잭션'
서비스가 커질수록 이 숫자는 단순한 숫자를 넘어 비즈니스 신뢰성과 확장성의 기준이 된다.
“우리 서비스 TPS는 얼마나 나오고 있을까?”
“갑자기 몰려드는 사용자 요청에도 견딜 수 있을까?”
결론 - 핵심 비교 표
구분 | Toss | 카카오페이 | 마켓컬리 |
주요 병목 | DB 조회 부하, 캐시 무결성 | DB CPU, 긴 트랜잭션, APM 누락 | 데드락, I/O 병목, 로그 저장 |
최적화 전략 | Redis 캐시 + Evict 보장 + CB | Redis + OSIV 제거 + APM 강화 | 정렬 트랜잭션 + 묶음 처리 + DB 분리 |
목표 TPS | ~20,000 | 300 → 400+ | 300 → 1,500+ |
구조 개선 | 캐시 일관성 강화 | 캐시+트랜잭션 범위 축소, APM | 트랜잭션 정리 + DB 구조 개선 |
2. Toss: “TPS 1만, 서버 증설 없이 캐시 먼저”
- 문제 상황
- 약관 동의 서버 TPS 평균 10,000, 최대 20,000까지 폭증
- 동의 여부에 대한 Strong Consistency 필요 (즉시 일관성)
- 새로운 서비스를 배포하면서 TPS가 급증하며 DB 조회 부하 심각
그 결과 많은 분들이 알고 계신 "캐시"를 적용하기로 하였지만, 막상 시도해보니 간단치 않았다.
- 해결 전략
- Look-aside Redis 캐시 도입
- 캐시 없을 시 DB 조회 후 저장
- DB 읽기 부담 대폭 감소
- 캐시 무결성 보장 로직 정교화
- @EntityListener, @TransactionalEventListener(AFTER_COMMIT) 사용
- Commit 이후 캐시 삭제 보장
- Circuit Breaker 적용
- Redis 장애 시 Circuit 열림(open) → DB로 Fallback
- 잘못된 캐시 응답 방지
- Cache Evict 순서 보장 + Kafka 이벤트 동기화
- @Order와 TransactionSynchronizationManager로 캐시 삭제 후 이벤트 발행 순서 보장
- 결과
- TPS 20,000까지 안정 처리
- 캐시 일관성과 정합성 모두 유지 가능
- “완벽보단 실행”을 중시하며 이터레이션+모니터링 병행
3. 카카오페이: 캐시 + 트랜잭션 최적화로 TPS 2.5배 업
- 문제 요약
- 이벤트 시 TPS 급상승 (170→300+), DB CPU 과부하
- Spring OSIV에서 트랜잭션이 긴 범위로 유지됨
- APM 추적 누락으로 병목 파악 어려움
- 해결 전략
- Redis 캐시 도입
- 상태 조회 API 중심, DB 직접 쿼리 최소화
- putIfAbsent, RedisCacheWriter 통해 정합성 보강
- 트랜잭션 범위 최소화
- OSIV 비활성화로 트랜잭션 범위 줄임
- DTO 쿼리 방식 전환
- APM 고도화
- @ApmMethod 삽입으로 비동기/코루틴 추적 강화
- Redis 호출 수 감소 노력 병행
- 성과
- TPS 170 → 400+, QPS 53K → 80K 증가
- DB CPU 사용률 74% → 50% 감소 → 2.5배 효율 향상
4. 마켓컬리: 데드락 제거 + 트랜잭션 묶음 처리로 TPS 수배 확장
- 문제 요약
- TPS 목표인 300에서 데드락 발생, 실제 TPS는 120 수준
- DB I/O 과다(commit/lock) → 처리 정체
- TPS 제한적 향상 및 테스트 불안정
- 해결 전략
- 데드락 제거용 순서 정렬
- 업데이트 대상(상품 코드) 순서 고정 → 교착 상태 해소
- 트랜잭션 묶음 처리
- 여러 요청을 프로시저 스타일로 묶어 commit 단위 줄임
- TPS 320, 512 RPS까지 개선
- 로그 DB 분리
- RDS → MongoDB 로그 저장 분리 → RDS 부담 감소
- TPS 1,500 이상 유지
- 성과
- TPS 120 → 1,500+ 증가
- 11시간 동안 6000만 건 이상 안정 처리
참고링크
https://helloworld.kurly.com/blog/vsms-performance-experiment/
신규 서비스 배포 전에 실험과 개선을 반복한 이야기
성능 테스트로 데드락을 찾아 없애고 TPS를 끌어올리자!
helloworld.kurly.com
https://tech.kakaopay.com/post/improve-service-performance/
카카오페이 온라인 결제 서비스 2.5배 성능 개선기 | 카카오페이 기술 블로그
카카오페이 온라인 결제 시스템의 성능 개선 기록을 공유합니다.
tech.kakaopay.com
https://toss.tech/article/34481
캐시를 적용하기 까지의 험난한 길 (TPS 1만 안정적으로 서비스하기)
TPS가 평균 1만, 최대 2만까지 늘어난 약관(terms) 서버에 안정적인 서비스 제공을 위해 캐시를 적용한 이야기를 들려드리려고 해요.
toss.tech
'Backend > [기타]' 카테고리의 다른 글
[Backend][기타] 등록 전에 ID가 필요한 구조, 어떻게 해결할까?” - 상품 등록 흐름에서의 Draft 전략 (0) | 2025.05.22 |
---|
Comments