민프

[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 조회 부하 심각
    그 결과 많은 분들이 알고 계신 "캐시"를 적용하기로 하였지만, 막상 시도해보니 간단치 않았다.

https://toss.tech/article/34481 - 1만~2만 TPS

 

- 해결 전략

  1. Look-aside Redis 캐시 도입
    • 캐시 없을 시 DB 조회 후 저장
    • DB 읽기 부담 대폭 감소
  2. 캐시 무결성 보장 로직 정교화
    • @EntityListener, @TransactionalEventListener(AFTER_COMMIT) 사용
    • Commit 이후 캐시 삭제 보장
  3. Circuit Breaker 적용
    • Redis 장애 시 Circuit 열림(open) → DB로 Fallback
    • 잘못된 캐시 응답 방지
  4. Cache Evict 순서 보장 + Kafka 이벤트 동기화
    • @OrderTransactionSynchronizationManager로 캐시 삭제 후 이벤트 발행 순서 보장 

- 결과

  • TPS 20,000까지 안정 처리
  • 캐시 일관성과 정합성 모두 유지 가능
  • “완벽보단 실행”을 중시하며 이터레이션+모니터링 병행 

3. 카카오페이: 캐시 + 트랜잭션 최적화로 TPS 2.5배 업

- 문제 요약

  • 이벤트 시 TPS 급상승 (170→300+), DB CPU 과부하
  • Spring OSIV에서 트랜잭션이 긴 범위로 유지됨
  • APM 추적 누락으로 병목 파악 어려움 

- 해결 전략

  1. Redis 캐시 도입
    • 상태 조회 API 중심, DB 직접 쿼리 최소화
    • putIfAbsent, RedisCacheWriter 통해 정합성 보강 
  2. 트랜잭션 범위 최소화
    • OSIV 비활성화로 트랜잭션 범위 줄임
    • DTO 쿼리 방식 전환
  3. 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 제한적 향상 및 테스트 불안정

- 해결 전략

  1. 데드락 제거용 순서 정렬
    • 업데이트 대상(상품 코드) 순서 고정 → 교착 상태 해소 
  2. 트랜잭션 묶음 처리
    • 여러 요청을 프로시저 스타일로 묶어 commit 단위 줄임
    • TPS 320, 512 RPS까지 개선 
  3. 로그 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

 

Comments