Posts Kafka를 활용한 대용량 이벤트 처리 구조 설계와 성능 비교
Post
Cancel

Kafka를 활용한 대용량 이벤트 처리 구조 설계와 성능 비교

목적

  • 서비스에서 처리량이 증가하거나 작업 시간이 길어지는 상황에서
    기존의 동기식 직접 DB 접근방식이 가진 한계를 확인하고
    Kafka 기반 비동기 처리 구조의 성능 및 안정성을 확인하기 위함

실험환경

  • 애플리케이션Kotlin Spring Boot 기반 API 서버
  • DB: MariaDB
  • Kafka: 단일 노드
  • 트랜잭션 타임아웃: 1분
  • 인위적 딜레이: 일부 실험에서 0.3초 지연 삽입
  • 성능 측정 도구: k6
    • vus: 1000(가상 유저 1000명)
    • durations: 5m (총 5분간 실행)
    • iterations: 3000 (총 요청 수:3000)

측정 기준

  • 처리 시간 (diffSec)
    • inventory: 첫 번째 행의 createdAt과 마지막 행의 createdAt의 차이
    • order: 동일한 행의 createdAt과 updatedAt의 차이
  • 실패율 (Failure Rate)
    • 부하 테스트 도구 k6 기준
    • rate: 실패율 (0.0 = 모두 성공, 1.0 = 모두 실패)
    • passes: 실패 요청 수 (예: HTTP 오류)
    • fails: 성공 요청 수
    • 추가적으로 DB에 실제 반영된 quantity 값도 함께 검토

실험 결과 요약

Inventory 삽입 (3000건)

실험방식파티션/배치처리 시간 (초)실패율결과
inventory1직접 DB 접근-없음300.0
inventory2Kafka + 단일 파티션단건없음340.0
inventory3Kafka + 3파티션단건없음270.0
inventory4Kafka + 3파티션배치(20건)없음180.0

단일 Order UPDATE - 딜레이 없음 (최초 삽입 1건, 갱신 3000건)

실험방식Kafka 파티션처리 시간 (초)실패율결과
order1직접 DB 접근비관적 락없음490.0
order2Kafka 컨슈머없음1개520.0
order3Kafka 컨슈머비관적 락3개380.0

단일 Order UPDATE - 딜레이 0.3초 (타임아웃 1분, 최초 삽입 1건, 갱신 3000건)

실험방식Kafka 파티션처리 시간 (초)처리된 quantity실패율결과
order1직접 DB 접근비관적 락없음3033280.972
order2Kafka 컨슈머없음1개38430010.0
order3Kafka 컨슈머비관적 락3개33330010.0

실패율 상세

  • k6 실패율 계산 기준
    • rate: 실패율 (0.0 = 100% 성공, 1.0 = 100% 실패)
    • passes: 실패 요청 수 (예: HTTP 500 등)
    • fails: 성공 요청 수
    • 실패율 = passes / (passes + fails)
  • 실패 발생 실험: order1(직접 DB 접근 + 딜레이)
    • 요청 기준 성공률: 약 2.8%(84/3001)
    • 실제 DB 반영 성공 수량: 328건
      • 일부 실패 응답이 DB에는 성공적으로 반영된 것으로 추정

결론

  • Kafka 기반의 비동기 처리 구조는 직접 DB 접근 방식에 비해
    다음의 이점을 갖는다.
  • 높은 안정성
    • 직접 DB 접근 방식은 요청이 몰릴수록 트랜잭션 충돌, 락 경합, 커넥션 부족등의 이슈로 인해 실패율이 높아지는 경향이 있다.
    • 특히 급격하게 트래픽이 몰려 DB 커넥션이 부족해지고 트랜잭션 처리 시간이 길어질 경우 실패율이 급격히 올라가며, 동시에 DB 부하도 높아져 다른 기능에 영향을 준다.
    • 반면 Kafka 비동기 구조에서는 모든 요청을 큐잉하고 순차적으로 처리하기 때문에 요청량이 일시적으로 급증하더라도 상대적으로 안정적으로 처리 흐름을 유지할 수 있다.
  • 수평적 확장성
    • Kafka는 파티션을 추가 및 컨슈머 수를 늘리고,
      배치 처리(batch)를 도입함으로써
      처리 성능을 선형적으로 확장할 수 있다.
    • 실제 실험에서도 Kafka 파티션 수를 늘리고 배치 처리까지 도입하자
      처리 시간(diffSec)이 눈에 띄게 줄어들었다.
    • 즉, 트래픽이 늘어나더라도 유연하게 대응할 수 있는 구조이다.
  • DB 부하 감소 및 시스템 전반의 응답성 향상
    • Kafka 구조는 비동기 방식으로 동작하기 때문에, 사용자 요청 시점에 DB에 직접 접근하지 않는다.
    • 내부 처리 과정에서 병목이 발생하더라도, 요청을 Kafka가 우선 수신하고 처리하므로 DB에는 상대적으로 여유 있는 요청만 전달된다.
    • 이로 인해 과도한 동시 요청이 DB에 몰리는 상황을 효과적으로 방지할 수 있다.
    • 실험 결과에서도 이런 차이는 명확히 드러난다.
    • 직접 DB 접근 방식에서는 트래픽이 몰려 DB 타임아웃이 발생한 이후부터는 조회 요청까지 큰 지연을 겪었다.
    • 반면 Kafka 기반 구조는 처리 작업과 조회 요청이 서로 영향을 받지 않기 때문에, 초기 몇 초를 제외하고는 조회 응답 시간이 안정적으로 유지되었다.

번외 - 스티키 파티셔너 vs 라운드로빈 파티셔너

  • 기존 실험에서는 프로듀서에서 파티션 키를 설정하지 않았기 때문에
    기본 설정인 스티키 파티셔너를 사용했다.

  • 이번에는 파티션을 3개 사용하는 테스트 시나리오만 모아,
    프로듀서에서 랜덤 키를 설정하여 라운드로빈 파티셔너를 사용하도록 실험하였다.

  • 두 파티셔너 간의 처리 시간 차이 비교

    항목Sticky 파티셔너Round-Robin 파티셔너차이
    Order3 (딜레이 없음, 갱신)38초39초+1초
    Order3 (딜레이 있음, 갱신)333초346초+13초
    Inventory3 (파티션 3개, 삽입)27초32초+5초
    Inventory4 (배치 삽입)18초25초+7초
  • 모든 항목에서 Sticky 파티셔너가 Round-Robin 파티셔너보다 더 빠른 처리 속도를 보였다.

참고

This post is licensed under CC BY 4.0 by the author.