인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

조익현님의 프로필 이미지

작성한 질문수

카프카 완벽 가이드 - 코어편

acks 값 설정에 따른 Producer의 전송 방식 차이 이해

acks 1 이면 비동기가 아니지 않나요?!

작성

·

58

0

제가 공부하다가 든 의문에 대해서 자문자답?을 해봤습니다!
혹시 제가 잘못 이해하거나 틀린 개념이 있다면 알려주실 수 있을까요?

나의 의문!

비동기 전송할 때, acks = 1 설정이면 Producer는 Leader broker가 메시지 A를 정상적으로 받았는지에 대한 ==Ack 메시지를 받은 후 다음 메시지인 메시지 B를 바로 전송==. 이러면 async 전송이 아닌거 아니야?

내 생각

  • 어디까지 비동기 처리인지에 대한 경계가 불분명해서 생긴 오해!!

1. Main Thread (producer.send() 호출하는 thread)

 

for (seq in 0..19) {
    producer.send(topic, seq, record)
}
  • 메인 스레드는 blocking 없이 연속적으로 메시지 전송!

    -> 비동기 전송!

producer 내부

[main thread] -> [RecordAccumulator] -> [sender thread] -> [broker]

  • RecordAccumulator는 메시지들을 버퍼링하고 배치로 모음

2. sender thread 동작 (acks 1 기준)

  1. 0번 메시지 전송 -> ack 대기 -> ack 수신 완료

  2. 1번 메시지 전송 -> ack 대기 -> ack 수신 완료

  3. ...

  • sender thread는 이젠 메시지의 ack를 받을 때가지 다음 메시지를 보내지 않는다

  • 하지만 main thread는 이와 무관하게 계속해서 메시지를 RecordAccumulator에 추가할 수 있다!

 

결론

  • main thread 입장에서는 메시지 응답을 기다리지 않고 계속 보낼 수 있으니까 비동기 전송 -> 메시지는 batch에 차곡차곡 쌓임

  • 실제 메시지를 전송하는 sender thread는 acks 1 설정으로 leader broker가 보낸 ack를 수신해야 다음 메시지 전송

 

 

이렇게 이해했는데 제가 이해한게 맞을까요,,,?

 

답변 2

1

권 철민님의 프로필 이미지
권 철민
지식공유자

안녕하십니까,

좋은 질문 감사합니다. 비슷한 질문에 대한 답변이 있어서 먼저 해당 답변 URL 보내드립니다.

https://www.inflearn.com/community/questions/1146961/%ED%94%84%EB%A1%9C%EB%93%80%EC%84%9C-%EC%A0%84%EC%86%A1%EA%B3%BC-ack-%EA%B4%80%EA%B3%84%EC%97%90-%EB%8C%80%ED%95%B4-%EC%A7%88%EB%AC%B8%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4

내용은 아래와 같습니다. 읽어 보시고, 원하시는 답변이 아니시면 다시 글 부탁드립니다.

==========================================================

sync 방식, 즉 producer.send().get() 과 async 방식(callback 적용)에 따라 acks=0/1 이 살짝 달라지는 부분이 있습니다.

강의에서 설명드리는 부분은 sync 방식에서 acks 적용이라고 보시면 될 것 같습니다.

먼저 sync 방식은 send()가 return받는 future 객체가 만들어져서 get()이 반환될때까지 wait가 되면서 순차적인 동기 방식을 유지하게 되는데, 이게 acks=0 일 경우는 get() 이 broker로 부터 ack를 기다리지 않고 바로 반환이 됩니다. 순차적으로는 보내는데, acks를 기다리지 않고 보내기 때문에 해당 메시지가 유실될 수 있습니다.

sync 방식에서 acks=1 이면 acks가 와서 get()이 반환될 때까지 기다리게 됩니다. acks가 일정 기간동안 오지 않으면 다시 해당 메시지를 보내게 됩니다.

async 방식에서 acks=0은 sync 방식과 거의 동일합니다. 다만 acks를 받으면 Callback이 수행된다는 점만 다릅니다.

async 방식에서 acks=1은 조금 헷갈리는 부분이 있습니다. async 방식에서 acks=1 인 경우는, 이전 메시지의 acks를 받지 않았지만, 다음 메시지를 보낼 수 있습니다. 즉 비 순차적으로 메시지를 보낼 수 있습니다. 하지만 이전 메시지의 acks가 특정 기간동안 오지 않는다면 해당 메시지를 다시 보냅니다. 때문에 중복이 발생할 가능성이 있습니다.

강의에서는 acks=1인 경우는 sync 방식으로 보낸 설명으로 생각해 주시면 될 것 같습니다. async 방식의 경우는 메시지를 보내고, acks를 기다리지 않고, 다음 메시지를 보내지만, acks가 오지 않는 경우 해당 메시지를 다시 보내게 됩니다.

생각해 보니, 이 설명을 원래 강의 기획에서는 하려고 했었는데, 어쩌다 보니 빠진 것 같군요. 아마 이 설명을 하면 수강생 분들이 많이 헷갈릴 것 같아서 쉽게 결정을 못하다가 잊어버리고 넘어간 것 같습니다.

 

 

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 조익현님, 카프카에서의 비동기 메시지 전송에 대한 이해를 돕기 위해 몇 가지 추가 설명을 드리겠습니다.

Kafka Producer의 메커니즘은 메인 스레드(Main Thread)와 전송 스레드(Sender Thread)로 나뉘어져 있습니다. 이 구조 덕분에 메시지를 비동기로 처리할 수 있습니다. 다음은 각각의 역할에 대한 설명입니다:

  1. 메인 스레드 (Main Thread):

    • producer.send() 호출 시 메시지가 RecordAccumulator에 추가 됩니다. 이는 비동기적으로 이루어지므로, 메인 스레드는 다음 메시지를 전송하기 위해 대기할 필요가 없습니다.
    • 이로 인해 메인 스레드는 “비동기” 방식으로 작동하며, 메시지 전송이 연속적으로 수행됩니다.
  2. 전송 스레드 (Sender Thread):

    • acks=1 설정의 경우, Leader Broker가 메시지를 수신했다는 확인(Ack)을 Sender Thread가 기다립니다.
    • 즉, 메시지가 Broker에 도달했다는 확인을 받고 나서야 다음 메시지를 전송합니다. 하지만 이 과정은 Sender Thread 내부의 비동기 처리로 진행되므로 메인 스레드에는 영향을 미치지 않습니다.

전체적으로 보면, 메인 스레드는 메시지를 차례대로 전송하고, 메시지가 RecordAccumulator에 누적되어 Sender Thread가 전송 작업을 수행합니다. 이로 인해 프로듀서가 동기적으로 메시지의 응답 대기를 하지 않아도 되며, 비동기 메시지 전송이 가능합니다.

관련된 질문과 답변이 있는 게시물을 소개드립니다:
- Kafka Producer의 메시지 전송 메커니즘에 대한 설명
- Producer와 Consumer의 동작 방식 이해하기

조익현님께서 설명하신 바와 같이, Producer의 메커니즘을 이해하고 후속 작업들이 비동기로 처리되는 부분에서 그 정확성을 인지하고 계셨기에 잘 이해하고 계신 것 같습니다.

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