강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

DongA Shin님의 프로필 이미지
DongA Shin

작성한 질문수

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

@KafkaListener에 대해서

해결된 질문

작성

·

82

0

안녕하세요 강의 잘보고 있습니다.

알아보니까 @KafkaListener가 비동기로 실행되는 줄 알았는데 동기로 실행이 되네요
강의를 보면서 느낀점이 카프카로부터 구독할 때 비동기로 실행되어야 하지 않나싶은데 어떤지 알려주시면 감사합니다

답변 2

0

쿠케님의 프로필 이미지
쿠케
지식공유자

DongA Shin님, 안녕하세요!

강의 잘 수강해주셔서 감사합니다!

 

“구독할 때 비동기”로 실행되어야 한다는건, 어떤 이유에서 그렇게 동작해야 한다고 느끼셨을까요?!

일반적으로 카프카가 비동기로 이벤트를 처리한다는건,

프로듀서가 이벤트를 발행한 후 결과를 기다리지 않고, 이후에 컨슈머가 처리한다는 것을 의미합니다.

 

프로듀서는 특정 토픽에 이벤트를 발행하고, 원한다면 각 이벤트의 파티션 키를 지정할 수 있습니다.

파티션 키가 동일하면, 카프카의 동일한 파티션으로 이벤트가 발행됩니다.

보통 파티션 키를 지정한다는 것(=단일 파티션에 보낸다는 것)은, 순서를 보장하기 위한 경우가 많습니다.

(순서에 대한 이야기는 고려할게 더 많을 수 있지만 생략)

 

그리고 컨슈머는 카프카의 토픽을 구독하여 데이터를 처리하는데요, 각 파티션은 N개의 컨슈머에 적절히 분산 할당되어 병렬로 처리됩니다.

개별 파티션은 단일 스레드에 할당되어서 순서대로 처리할 수 있는 것이고요.

이벤트가 순서대로 처리되었으면, 확실히 처리된 이벤트는 정상적으로 처리되었다고 커밋할 수 있습니다.

만약 순서를 보장할 필요 없고 병렬로 처리될 필요가 없다면, 그냥 이벤트를 컨슘하자마자 비동기로 태스크를 실행시킬 수도 있습니다.

“구독할 때 비동기”로 실행을 해도 되지만, 상황마다 요구사항이 다를 수 있기 때문에 적절히 판단해볼 수 있을 것 같습니다.

 

혹시 더 궁금한 점 있으시면 편히 문의 주세요!

DongA Shin님의 프로필 이미지
DongA Shin
질문자

답변감사합니다 제가 비동기로 읽는다는것을 왜 그렇게 느꼈는지 찾아봤는데 강의에서 outbox이벤트를 통해 카프카에 전송한다고 했는데 이때 비동기로 전송이 된다고 제가 기록을 했는데 만약에 비동기로 전송한다고해서 꼭 비동기로 읽어들이라는 것은 아니지요? 아까 답변해주신대로 상황에 따라 설정하는 걸로 이해하면 될까요?

쿠케님의 프로필 이미지
쿠케
지식공유자

음 정확히 어떤 구간과 관점에서 비동기를 말씀하시는건지 헷갈리네요..!

  1. 프로듀서가 발행한 이벤트를 컨슈머가 컨슘하는 구간

  2. 프로듀서가 카프카 이벤트 발행 코드를 호출하는 구간

  3. 컨슈머가 이벤트를 컨슘하고 커밋하는 구간

1번은 비동기가 맞습니다. 프로듀서와 컨슈머 관계에 대해 시스템 전체적으로 보면 아무튼 비동기라는 의미입니다.

2번은 강의에서는 동기적으로 처리됩니다. 이벤트 유실 방지를 위해 Future.get()으로 확실히 전송이 완료되었는지 확인하기 때문입니다. 하지만 필요하다면 비동기로 처리할 수도 있습니다. publishEvent 코드를 별도 비동기 스레드에서 실행시킬 수도 있는 것입니다.

3번도 강의에서는 이벤트를 모두 완료한 뒤에 커밋하기 때문에 동기적으로 처리된다고 볼 수 있습니다. 하지만 병렬 처리가 필요하고 유실되어도 상관 없다면 비동기로 처리할 수 있습니다. 예를 들어, 이벤트 컨슘하자마자 비동기 스레드에 태스크를 실행하고, 레코드는 즉시 커밋하는 경우를 말하는겁니다.

 

정리하면, 시스템 전체적으로는 비동기가 맞습니다.

이 말은, 프로듀서는 컨슈머가 이벤트 처리를 완료할때 까지 기다리지 않는다는 것을 의미합니다.

그리고 각 구간에 대해서는 상황에 따라 적절히 설정할 수 있습니다!

 

0

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

KafkaListener 어노테이션을 사용해 Kafka 메시지를 소비할 때, 메시지 처리는 기본적으로 단일 스레드로 동작하게 됩니다. 그러나, 비동기 처리가 필요한 경우에는 스레드 풀을 활용해 비동기적으로 메시지를 처리할 수 있습니다. KafkaListener의 기본 설정은 동기 처리를 통해 메시지 중복 소비를 방지하고 메시지 순서를 유지하는 데 유리하지만, 성능 향상을 위해 여러 스레드를 활용하고 싶다면 @KafkaListener 컨테이너 팩토리에서 컨슈머 팩토리의 ConcurrentKafkaListenerContainerFactory 설정을 튜닝하는 것이 좋습니다.

Kafka에서는 소비자가 메시지를 빠르게 처리하지 못할 경우, 컨슈머 랙(consumer lag)의 문제가 발생할 수 있습니다. 이를 해결하기 위해 같은 컨슈머 그룹 내 여러 스레드를 활용하여 메시지 병렬 처리를 수행할 수 있습니다. 스레드 풀을 사용하여 메시지를 비동기적으로 처리하면, 소비 속도를 올리고 시스템 성능을 개선하는 데 도움이 될 수 있습니다.

관련 코드를 보시면서 아래 게시글들을 참고하시면 추가적인 정보를 얻으실 수 있습니다:

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

DongA Shin님의 프로필 이미지
DongA Shin

작성한 질문수

질문하기