inflearn logo
강의

講義

知識共有

障害を許容する堅牢なシステム作り

카프카 질문

92

ssunn0812

投稿した質問数 1

1

안녕하세요 카프카 관련하여 질문드립니다.

카프카로 DB Insert 요청을 비동기 처리할 경우 트래픽이 급증하면 데이터베이스가 감당할 수 있는 QPS를 초과하여 과부하가 발생할 수 있습니다. 실무에서는 이러한 상황을 어떻게 대응하는지 궁금합니다.

감사합니다.

spring-boot kafka resilience4j data-consistency transaction

回答 2

0

foo

ssunn0812님 안녕하세요~

우선 답변이 늦어서 죄송합니다. (_ _)

 

질문 주신 내용에 대해 답변드려보겠습니다.

 

실무에서는 이 문제를 해결하기 위해 여러 가지 전략을 조합해서 사용합니다.

 

1. 컨슈머의 '처리 속도' 자체를 조절하기

가장 기본적이고 직접적인 방법입니다. DB가 처리할 수 있는 양만큼만 컨슈머가 작업을 수행하도록 조절하는(Throttling) 것입니다.

  • 배치 크기 조절 (max.poll.records): 카프카 컨슈머는 한 번에 여러 개의 메시지(배치)를 가져와서 처리합니다. 이 max.poll.records 옵션 값을 의도적으로 낮게 설정(예: 500개 -> 50개)하면, 한 번의 루프에서 DB로 보내는 INSERT 쿼리의 수가 줄어듭니다. 이는 DB의 부하를 즉각적으로 낮춰주는 가장 간단한 튜닝 방법입니다.

  • 컨슈머 사이드 Rate Limiting: 컨슈머 애플리케이션 코드 내에 Google Guava의 RateLimiter 같은 라이브러리를 사용하여 "초당 1000개의 트랜잭션만 처리"하도록 명시적으로 제한을 걸 수 있습니다.

 

2. 'Backpressure'를 구현하여 능동적으로 방어하기

단순히 속도를 줄이는 것을 넘어, DB의 '상태'를 확인하고 컨슈머의 동작을 일시적으로 멈추는, 더 지능적인 방법입니다.

  • Circuit Breaker 적용 : 강의의 핵심 주제인 '견고한 시스템'과 직결됩니다. 컨슈머가 DB에 INSERT를 시도할 때, DB에서 커넥션 타임아웃이나 응답 지연 같은 오류가 일정 비율 이상 발생하면 Circuit Breaker를 'Open' 상태로 전환합니다.

  • pause()resume()의 활용: Circuit Breaker가 Open이 되었을 때가 중요합니다. 이때 컨슈머는 단순히 에러를 로그에 남기고 다음 메시지를 처리하려 하면 안 됩니다. (그러면 DB는 계속 공격당하겠죠.) 대신, 카프카 컨슈머의 pause() 메서드를 호출해야 합니다.

    • consumer.pause()가 호출되면, 컨슈머는 브로커에게 "나 지금 바쁘니(혹은 내 뒷단이 아프니) 메시지를 더 이상 주지 마"라고 신호를 보냅니다.

    • 컨슈머는 브로커로부터 새로운 메시지를 받아오지 않고(poll X), Circuit Breaker가 닫힐 때까지(예: 1분 뒤) 대기합니다.

    • 이후 DB 상태가 정상으로 돌아와 Circuit Breaker가 'Close'되면, 그때 consumer.resume()을 호출하여 다시 메시지 처리를 시작합니다.

pause()/resume()와 Circuit Breaker의 조합이 DB 과부하를 막는 가장 세련되고 효과적인 실무 기법입니다.

 

3. 실패한 메시지 처리 및 재시도 전략

트래픽 급증으로 인해 DB가 처리하지 못한 메시지는 어떻게 해야 할까요?

  • 재시도 최대 횟수 제한: DB가 아파서 실패한 요청을 컨슈머가 곧바로 재시도(retry)하면, 이는 불난 집에 부채질하는 격입니다. DB 부하를 더욱 가중시켜 '재시도 폭풍(Retry Storm)'을 일으킵니다.

  • Dead Letter Queue (DLQ): 일반적으로 3회 정도의 재시도(exponential backoff 적용) 후에도 실패하는 메시지는, 처리를 포기하고 별도의 'Dead Letter Queue (DLQ)' 토픽으로 보냅니다.

    • 이렇게 하면 컨슈머는 일단 해당 메시지의 오프셋을 커밋(commit)하고 다음 메시지를 처리할 수 있게 되어, 전체 파이프라인이 막히는 것을 방지합니다.

    • DLQ로 간 메시지들은 나중에 개발자가 원인을 분석하거나, DB 부하가 적은 새벽 시간에 별도의 배치 작업으로 재처리할 수 있습니다.

 

요약하자면,

실무에서는 1) max.poll.records 같은 옵션으로 기본 처리량을 튜닝하고, 2) DB 상태를 모니터링하는 Circuit Breaker를 구현하며, 3) DB 장애 시 pause()를 호출하여 컨슈머를 능동적으로 멈추는(Backpressure) 방식을 가장 많이 사용합니다. 그리고 4) 반복적으로 실패하는 메시지는 DLQ로 격리하여 시스템 전체의 안정성을 확보합니다.

이러한 장치들을 통해 트래픽이 급증하더라도 카프카 토픽에 메시지가 좀 쌓일지언정(Lag 발생), 최종 관문인 DB가 다운되는 최악의 장애 상황을 방지할 수 있습니다.

 

다만 시스템 요구사항에 따라 위 내용이 적용 불가능한 상황도 있을겁니다. 상황에 따라 적절한 방식을 도입해야하고, 필요하다면 DB가 받는 부하를 분산하는 방법도 적용해보면 좋습니다.

 

DB 부하 분산 전략을 위한 핵심 키워드들은 다음과 같습니다.

  • Read / Write 분리 (CQRS)

  • 데이터베이스 복제 (Replication): Read 부하 분산을 위한 'Read Replica(읽기 전용 복제본)' 활용

  • 데이터베이스 샤딩 (Sharding / Partitioning): Write 부하의 근본적인 분산

  • 캐시 (Cache) 활용: Redis, Memcached 등을 이용해 DB 조회 자체를 줄이기

 

혹시 질문에 대한 답변이 됐을까요?

추가적으로 궁금한 내용 있으면 질문 남겨주세요.

감사합니다.

0

communityai8509

안녕하세요, 인프런 AI 인턴입니다. ssunn0812님.

카프카를 통해 DB Insert 요청을 비동기 처리하는 상황에서 트래픽이 급증할 경우, 데이터베이스 과부하를 방지하기 위한 여러 가지 방법이 있습니다. 다음의 방법들을 통해 실무에서 이러한 문제를 해결할 수 있습니다:

  1. Throttling: 처리할 수 있는 최대 QPS를 초과하지 않도록 카프카 컨슈머 레벨에서 데이터를 제한합니다. 즉, 한 번에 많은 양의 데이터를 처리하지 않고 일정 수만큼의 데이터만 처리하도록 합니다.

  2. Batch Processing: 여러 개의 Insert 요청을 모아서 한 번에 처리하는 방식을 사용합니다. 이렇게 하면 네트워크 호출의 횟수를 줄이고 데이터베이스의 부하를 줄일 수 있습니다.

  3. Backpressure: 시스템의 현재 상태를 고려하여 생산자와 소비자의 속도를 조절하는 기법입니다. 과부하 시에는 카프카 컨슈머가 데이터를 느리게 소비하거나 일시 중지하도록 합니다.

  4. Load Balancing: 여러 데이터베이스 인스턴스를 사용하여 데이터베이스 부하를 분산시키는 방법입니다. 이를 통해 한 데이터베이스 인스턴스의 과부하를 방지할 수 있습니다.

  5. Hystrix 사용: ‘서킷 브레이커’ 패턴을 적용하여, 데이터베이스 과부하 발생 시 요청을 차단하고 시스템을 보호할 수 있습니다.

관련 주제에 대해 더 깊이 있는 논의를 확인할 수 있는 유사한 질문과 답변 링크도 공유합니다:

  • Redis를 활용한 캐시와 트랜잭션 관리: 이 링크는 Redis 및 트랜잭션 관리 방식에 대한 논의들을 포함하고 있으며, 데이터 일관성과 멱등성을 어떻게 보장할 수 있는지 좋은 포인트들을 제공합니다.

  • 비동기 분리에 관한 논의: 비동기 처리 방식에서의 데이터 일관성 및 장애 해결 방안에 대한 여러 가지 접근 방법을 확인할 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

패키지 구분에 대해 궁금한게 있습니다

0

10

1

섹션4 AWS NAT Instance생성하는 과정에서 오류가 지속해서 발생합니다.

0

13

1

스프링부트 서버 에러나요

0

17

1

2026.04에 추가된 강의 시청 불가

0

28

1

Service Create/Update Record 운용과 Delete Record 미운용의 차이 질문

0

20

1

인가 코드 발급(프론트 vs 백)

0

28

2

인텔리제이 MCP 서버 설정 관련

0

26

1

Sequence 관련 질문

1

32

2

Image Only Query

1

29

2

프롬프트, 스킬, sub-agent

0

31

1

도메인 모델에서 관계와 규칙을 구분하는 방법

0

37

2

16 강의 메세지 retryCount의 의도

0

23

2

user-service jwt

0

32

2

안녕하세요 강사님 질문 있습니다.

0

58

1

bitnami/kafka 말고 다른 이미지를 사용하는 방법 알려주세요.

0

167

2

안녕하세요. 타임아웃 시간에 관하여 질문있습니다.

1

108

2

분산 시스템 인증/인가 관련 질문 ..

1

79

2

안녕하세요 주문처리에 관하여 질문있습니다 ㅠ ㅁ ㅜ

2

157

2

[데이터 버저닝을 활용한 멱등성 처리] 멱등성 보장을 위한 version 비교 질문

1

117

2

데이터 버저닝 질문

1

106

2

복제 관련 질문입니다!

2

107

2

@Transactional선언 메서드 정상동작하는건가요?

1

99

2

영상 편집이 잘못된 것 같아요. (순서가 중간에 계속 바뀜)

0

76

3

혹시 강의자료랑 강의 안에 나오는 pdf와 같은거가요?

1

100

2