개발자

멱등성 카프카 프로듀서 질문

2024년 04월 12일조회 910

멱등성 프로듀서에서 동일한 토픽 파티션에 A레코드 전송 시 실패로 retry에 의해 재전송하는데 그와중에 B레코드가 전송되면 A, B레코드는 순서가 바껴서 저장되는게 맞을까요? 원하는건 A ,B 레코드 순으로 저장되는건데 이 경우라면 어떤 방식으로 처리해야 하나요?

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 1

인기 답변

이양일님의 프로필 사진

안녕하세요! 말씀하신 멱등성 프로듀서가 Producer 의 설정 중, "enable.idempotence" 를 "true" 로 설정한 프로듀서라고 이해하고 답변드리겠습니다. 프로듀서 설정을 크게 변경하지 않으셨다면 default 로 프로듀서의 retry 설정(retries)은 Max Integer 값인 2147483647 로 설정이 되고, "delivery.timeout.ms" 가 120000(2분)으로 설정되어 실패한 레코드는 2분까지 계속 retry 를 하도록 동작합니다. (말씀하신 retry 가 client 가 직접 하는 retry 가 아닌, 프로듀서 내부적으로 수행하는 retry 를 말씀하신거로 이해하여 이에 대한 동작을 설명드렸습니다.) 카프카 프로듀서는 내부적으로 파티션별로 레코드를 담아두는 배치를 따로 두고, Sender 라는 모듈을 통해 각 파티션별 배치에 담긴 레코드를 전송하는 구조인데요 이때 각 레코드가 담긴 배치를 최대 몇개까지 보낼지에 대한 설정이 "max.in.flight.requests.per.connection"(https://kafka.apache.org/documentation/#producerconfigs_max.in.flight.requests.per.connection) 입니다. 멱등성 카프카 설정을 하지 않는다면, 해당 값을 1로 해야 재시도에 대한 순서 보장이 유지가 되고 멱등성 카프카를 설정할 경우 최대 5까지 설정을 해도 순서 보장이 가능하게 해줍니다. 이게 가능한 이유는, 멱등성 카프카를 설정할 경우 내부적으로 메세지에 대한 시퀀스 번호를 부여했기 때문인데요, 예를 들어주신 상황처럼 A 레코드가 실패하여 B 레코드가 먼저 전송이 되면 기대하고 있던 시퀀스 번호(A)가 아닌 그 다음번호(B) 가 들어왔기 때문에 Broker 단에서 B 레코드도 실패처리를 하게 됩니다. 즉, 먼저 유입된 레코드가 성공을 해야 그 다음 레코드가 성공할 수 있는 형태로 순서보장을 지원하고 있다 라고 이해해주시면 되겠습니다. 저의 짧은 지식이 작게나마 도움이 되시면 좋겠습니다.

profile picture

익명

작성자

2024년 04월 15일

안녕하세요. 답변 감사합니다. 제가 이해한게 맞는지 궁금합니다. 1. A레코드가 센더를 통해 먼저 전송 후 실패 > 재시도 2. B레코드가 A레코드 재전송 중 먼저 센더를 통해 전송 멱등성 프로듀서는 항상 순서 보장 이런 상황이면 A레코드가 성공 전까지(재시도가 끝날 때까지) 전송되고 있는 레코드들은 전부 순서 보장을 위해 실패 및 재시도를 하는걸까요? A레코드 전송이 최종 실패하면 후속 레코드들은 어떻게 되는건가요? 멱등성 프로듀서라고 해도 각 서버 마다 Spring 애플리케이션에서 전송하게 되면 pid가 서로 다르기 때문에 이때는 전체 레코드에 대한 순서보장은 안되는게 맞을까요?

이양일님의 프로필 사진

이양일

NaverCloud 백엔드 개발자2024년 04월 15일

오 저도 생각해보지 못했던 질문이라 오랜만에 카프카 코드를 다시 좀 까보았습니다. 이런 상황이면 A레코드가 성공 전까지(재시도가 끝날 때까지) 전송되고 있는 레코드들은 전부 순서 보장을 위해 실패 및 재시도를 하는걸까요? -> Record 를 Batch 에 기록하고 이를 Sender 로 전달하는 역할을 하는 RecordAccumulator 로직을 살펴보면, 다음 Batch 전송시 같은 topic partition 에 속한 Batch 가 아직 전송중일 경우 Sender 로 전달을 하지 않도록 막고 있습니다. 이를 통해 같은 Topic Partition 에 속한 Batch 중 Retry 를 계속 하고 있을 경우 다음 Batch 는 Sender 로 전달을 하지 않도록 막게 됩니다.(해당 파티션에 한해 max.in.flight.requests.per.connection 설정이 1인것과 동일한 효과를 줌) 관련 코드는 https://github.com/apache/kafka/blob/3617dda9a5415ee1597967f754985fb73a5350c6/clients/src/main/java/org/apache/kafka/clients/producer/internals/RecordAccumulator.java#L857 를 참고해주세요. A레코드 전송이 최종 실패하면 후속 레코드들은 어떻게 되는건가요? -> Sender 는 주기적으로 RecordAccumulator 로부터 전송할 Batch 를 조회함과 동시에 Sequence 정보를 재조정해야하는지를 체크하는데요, 이를 통해 질문하신 내용처럼 최종 실패한 레코드가 발생할 경우 Sequence 정보를 재조정함으로써 후속 레코드 전송에 이슈가 없도록 조치를 취합니다.(근데 "delivery.timeout.ms" 만큼 실패가 계속 발생했다면 브로커에 뭔가 치명적인 이슈가 발생한것일 가능성이 크기 때문에 최종 실패한 레코드 이후의 후속 레코드가 성공할 케이스는 별로 없을것 같습니다.) 관련 코드는 https://github.com/apache/kafka/blob/3617dda9a5415ee1597967f754985fb73a5350c6/clients/src/main/java/org/apache/kafka/clients/producer/internals/TransactionManager.java#L730 를 참고해주세요. 멱등성 프로듀서라고 해도 각 서버 마다 Spring 애플리케이션에서 전송하게 되면 pid가 서로 다르기 때문에 이때는 전체 레코드에 대한 순서보장은 안되는게 맞을까요? -> 네 맞습니다. Kafka 에서 얘기하는 프로듀서의 멱등성은 하나의 프로듀서 객체에서만 보장됩니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 04월 12일

멱등성 프로듀서를 사용하면, 동일한 토픽 파티션에 레코드를 다시 전송함과 동시에 순서가 변경되는 문제(즉, 원래의 A-B 순서가 B-A로 바뀌는 문제)는 발생하지 않을 것입니다. Kafka의 멱등성 프로듀싱은 정확히 한 번의 레코드 전달을 가능하게 하고, 재전송된 메시지에 대한 중복 쓰기를 방지합니다. 이것은 Kafka의 프로듀서 API가 내부적으로 메시지 재전송을 처리하면서, 서버 측에서 각 프로듀서와 토픽-파티션에 대한 시퀀스 번호를 추적함으로써 보장됩니다. 이 시퀀스 번호는 메시지 순서를 유지하는데 사용되므로, 메시지 전송의 실패 및 재전송이 발생하더라도 원래의 순서가 유지됩니다. 그러므로 A 레코드의 전송이 실패하여 재전송되는 경우에도, 그사이에 B레코드가 성공적으로 전송된다 하더라도 최종적으로 저장되는 순서는 여전히 A-B일 것입니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!