Kafka (15MB 이상)로 대용량 메시지를 보내려면 어떻게해야합니까?


118

Java Producer API를 사용하여 문자열 메시지를 Kafka V. 0.8로 보냅니다. 메시지 크기가 약 15MB이면 MessageSizeTooLargeException. message.max.bytes40MB 로 설정하려고 했지만 여전히 예외가 발생합니다. 작은 메시지는 문제없이 작동했습니다.

(프로듀서에 예외가 나타납니다.이 애플리케이션에는 소비자가 없습니다.)

이 예외를 제거하려면 어떻게해야합니까?

내 예제 생산자 구성

private ProducerConfig kafkaConfig() {
    Properties props = new Properties();
    props.put("metadata.broker.list", BROKERS);
    props.put("serializer.class", "kafka.serializer.StringEncoder");
    props.put("request.required.acks", "1");
    props.put("message.max.bytes", "" + 1024 * 1024 * 40);
    return new ProducerConfig(props);
}

오류 기록:

4709 [main] WARN  kafka.producer.async.DefaultEventHandler  - Produce request with correlation id 214 failed due to [datasift,0]: kafka.common.MessageSizeTooLargeException
4869 [main] WARN  kafka.producer.async.DefaultEventHandler  - Produce request with    correlation id 217 failed due to [datasift,0]: kafka.common.MessageSizeTooLargeException
5035 [main] WARN  kafka.producer.async.DefaultEventHandler  - Produce request with   correlation id 220 failed due to [datasift,0]: kafka.common.MessageSizeTooLargeException
5198 [main] WARN  kafka.producer.async.DefaultEventHandler  - Produce request with correlation id 223 failed due to [datasift,0]: kafka.common.MessageSizeTooLargeException
5305 [main] ERROR kafka.producer.async.DefaultEventHandler  - Failed to send requests for topics datasift with correlation ids in [213,224]

kafka.common.FailedToSendMessageException: Failed to send messages after 3 tries.
at kafka.producer.async.DefaultEventHandler.handle(Unknown Source)
at kafka.producer.Producer.send(Unknown Source)
at kafka.javaapi.producer.Producer.send(Unknown Source)

5
내 첫 번째 본능은이 거대한 메시지를 여러 개의 작은 메시지로 분할 해달라고 요청하는 것입니다 .- / 내 생각 엔 이것이 어떤 이유에서든 가능하지 않지만 그럼에도 불구하고 다시 생각하고 싶을 것입니다. 대형 메시지는 일반적으로 디자인 결함이 있음을 의미합니다 정말 고쳐야 할 곳입니다.
Aaron Digulla 2014 년

1
고맙지 만 내 논리를 훨씬 더 복잡하게 만들 것입니다. 약 15MB의 메시지에 Kafka를 사용 하는 것이 왜 나쁜 생각입니까? 1MB가 사용할 수있는 최대 메시지 크기 제한입니까? Kafka 문서에서 메시지 크기 제한에 대해 많이 찾지 못했습니다.
Sonson123

2
이것은 Kafka 또는 다른 메시지 처리 시스템과는 전혀 관련이 없습니다. 내 추론 : 15MB 파일에 문제가 발생하면 나중에 엉망을 정리하는 데 비용이 많이 듭니다. 이것이 제가 일반적으로 큰 파일을 여러 개의 작은 작업으로 분할하는 이유입니다 (일반적으로 병렬로도 실행될 수 있음).
Aaron Digulla 2014 년

압축을 사용한 적이 있습니까? 당신은 몇 가지 더 자세한 정보를 공유하시기 바랍니다 수는 좀 하드는 하나 하나의 단어에서 무엇인가 생각하는
user2720864

답변:


181

세 가지 (또는 네 가지) 속성을 조정해야합니다.

  • 소비자 측 : fetch.message.max.bytes- 소비자 가 가져올 수있는 메시지의 최대 크기를 결정합니다.
  • 브로커 측 : replica.fetch.max.bytes- 브로커 의 복제본이 클러스터 내에서 메시지를 보내고 메시지가 올바르게 복제되는지 확인할 수 있습니다. 이 값이 너무 작 으면 메시지가 복제되지 않으므로 메시지가 커밋 (완전 복제)되지 않으므로 소비자는 메시지를 볼 수 없습니다.
  • 브로커 측 : message.max.bytes-생성자로부터 브로커가 수신 할 수있는 메시지의 최대 크기입니다.
  • 브로커 측 (토픽 당) : max.message.bytes-브로커가 토픽에 추가 할 수있는 메시지의 최대 크기입니다. 이 크기는 압축 전 검증되었습니다. (기본값은 브로커의 message.max.bytes.)

2 번에 대한 어려운 방법을 찾았습니다. Kafka에서 예외, 메시지 또는 경고를 전혀받지 못하므로 대용량 메시지를 보낼 때이를 고려하십시오.


3
좋아, 당신과 user2720864가 맞았습니다. 나는 message.max.bytes소스 코드 에서만 설정했습니다 . 하지만 Kafka 서버 구성에서 이러한 값을 설정해야합니다 config/server.properties. 이제 더 큰 메시지도 작동합니다. :).
Sonson123

3
이 값을 너무 높게 설정하는 알려진 단점이 있습니까?
Ivan Balashov

7
예. 소비자 측에서는 fetch.message.max.bytes각 파티션에 대한 메모리를 할당 합니다. 즉 fetch.message.max.bytes, 많은 수의 파티션과 결합하여 많은 수를 사용하면 많은 메모리를 소비하게됩니다. 사실, 브로커 간의 복제 프로세스도 전문화 된 소비자이기 때문에 브로커의 메모리도 소모합니다.
laughing_man

3
브로커의 .NET보다 낮을 수있는 주제별max.message.bytes 구성 도 있습니다 . message.max.bytes
Peter Davis

1
공식 문서에 따르면 소비자 측의 매개 변수와 브로커 간의 복제와 관련된 매개 변수는 /.*fetch.*bytes/엄격한 한계가 아닌 것 같습니다. "이 값보다 [...] 큰 경우 레코드 배치는 진행될 수 있도록 여전히 반환됩니다. "
Bluu

56

laughing_man의 대답 과 비교하여 Kafka 0.10새로운 소비자에 필요한 사소한 변경 사항 :

  • 브로커 : 변경 사항이 없습니다. 여전히 속성 message.max.bytesreplica.fetch.max.bytes. message.max.bytes보다 작거나 (*)이어야 replica.fetch.max.bytes합니다.
  • 생산자 : max.request.size더 큰 메시지를 보내려면 늘리십시오 .
  • 소비자 : max.partition.fetch.bytes더 큰 메시지를 받으려면 늘리십시오 .

(*) message.max.bytes<=에 대해 자세히 알아 보려면 주석을 읽으십시오.replica.fetch.max.bytes


2
message.max.bytes더 작아야하는 이유를 알고 replica.fetch.max.bytes있습니까?
Kostas 2017 년

2
" replica.fetch.max.bytes (기본값 : 1MB) – 브로커가 복제 할 수있는 최대 데이터 크기.이 크기는 message.max.bytes 보다 커야합니다. 그렇지 않으면 브로커가 메시지를 수락하고 복제에 실패합니다. 잠재적 인 데이터 손실. " 출처 : handling-large-messages-kafka
Sascha Vetter

2
링크를 보내 주셔서 감사합니다. 이것은 Cloudera 가이드가 제안 하는 내용을 반영하는 것 같습니다 . 그러나이 두 가지 모두 잘못 되었습니다 . replica.fetch.max.bytes .NET보다 더 커야하는 이유에 대한 기술적 이유를 제공하지 않습니다 message.max.bytes. Confluent의 한 직원 은 오늘 제가 예상 했던 것을 확인했습니다 . 사실 두 수량이 동일 할 수 있습니다.
Kostas 2017 년

2
message.max.bytes<replica.fetch.max.bytes또는 message.max.bytes=replica.fetch.max.bytes@Kostas 에 관한 업데이트가 있습니까?
Sascha Vetter 2017

2
예, 동일 할 수 있습니다. mail-archive.com/users@kafka.apache.org/msg25494.html (Ismael은 Confluent에서 작동)
Kostas

13

다음 속성을 재정의해야합니다.

브로커 구성 ($ KAFKA_HOME / config / server.properties)

  • replica.fetch.max.bytes
  • message.max.bytes

소비자 구성 ($ KAFKA_HOME / config / consumer.properties)
이 단계는 저에게 효과적이지 않았습니다. 소비자 앱에 추가했는데 제대로 작동했습니다.

  • fetch.message.max.bytes

서버를 다시 시작하십시오.

자세한 정보는이 문서를 참조하십시오 : http://kafka.apache.org/08/configuration.html


1
명령 줄 소비자의 경우 --fetch-size = <bytes> 플래그를 사용해야합니다. consumer.properties 파일 (kafka 0.8.1)을 읽지 않는 것 같습니다. 또한 compression.codec 옵션을 사용하여 생산자 측에서 압축을 설정하는 것이 좋습니다.
Ziggy Eunicien 2014 년

Ziggy의 의견이 나를 위해 일했습니다. kafka 0.8.1.1. 감사합니다!
제임스

ConsumerConfig에서 fetch.message.max.bytes가 max.partition.fetch.bytes로 대체되었을 수 있습니까?
s_bei

12

아이디어는 Kafka Producer에서 Kafka Broker로 전송 된 메시지의 크기가 같고 Kafka Consumer가 수신하는 것입니다.

Kafka 생산자-> Kafka Broker-> Kafka 소비자

요구 사항이 15MB의 메시지를 보내는 것이라면 Producer , BrokerConsumer , 세 가지 모두가 동기화되어야합니다.

Kafka Producer가 15MB 전송 -> Kafka Broker 허용 / 저장 15MB- > Kafka 소비자 수신 15MB

따라서 설정은 다음과 같아야합니다.

a) 브로커 :

message.max.bytes=15728640 
replica.fetch.max.bytes=15728640

b) 소비자 :

fetch.message.max.bytes=15728640

2
ConsumerConfig에서 fetch.message.max.bytes가 max.partition.fetch.bytes로 대체되었을 수 있습니까?
s_bei

7

message.max.bytes속성은 소비자의 속성 과 동기화 되어야 한다는 점을 기억 해야합니다 fetch.message.max.bytes. 페치 크기는 최소한 최대 메시지 크기만큼 커야합니다. 그렇지 않으면 생산자가 소비자가 소비 / 페치 할 수있는 것보다 큰 메시지를 보낼 수있는 상황이있을 수 있습니다. 한 번 살펴볼 가치가 있습니다.
사용중인 Kafka 버전은 무엇입니까? 또한 얻고있는 몇 가지 세부 사항 추적을 제공하십시오. payload size of xxxx larger than 1000000로그에 ...와 같은 것이 있습니까?


1
더 많은 정보로 질문을 업데이트했습니다. Kafka 버전 2.8.0-0.8.0; 이제는 프로듀서 만 필요합니다.
Sonson123

6

@laughing_man의 대답은 매우 정확합니다. 그래도 나는 Quora의 Kafka 전문가 Stephane Maarek 에게서 배운 추천을하고 싶었습니다 .

Kafka는 대용량 메시지를 처리하기위한 것이 아닙니다.

API는 클라우드 스토리지 (예 : AWS S3)를 사용해야하며 Kafka 또는 모든 메시지 브로커에 S3 참조를 푸시해야합니다. 데이터를 유지할 어딘가를 찾아야합니다. 네트워크 드라이브 일 수도 있고, 무엇이든 상관 없지만 메시지 브로커가 아니어야합니다.

자, 위의 솔루션으로 가고 싶지 않다면

메시지 최대 크기는 1MB (브로커의 설정을라고 함 message.max.bytes) Apache Kafka 입니다. 정말로 필요하다면 그 크기를 늘리고 생산자와 소비자를 위해 네트워크 버퍼를 늘릴 수 있습니다.

그리고 메시지 분할에 대해 정말로 관심이 있다면 각 메시지 분할에 정확히 동일한 키가 있는지 확인하여 동일한 파티션으로 푸시되도록하고 메시지 콘텐츠는 "부분 ID"를보고해야 소비자가 메시지를 완전히 재구성 할 수 있습니다. .

메시지가 텍스트 기반 (gzip, snappy, lz4 압축) 인 경우 압축을 탐색 할 수도 있습니다. 이는 데이터 크기를 줄일 수 있지만 마술처럼 보이지는 않습니다.

다시 말하지만, 외부 시스템을 사용하여 해당 데이터를 저장하고 외부 참조를 Kafka에 푸시해야합니다. 이것은 매우 일반적인 아키텍처이며 함께 가야하며 널리 받아 들여 져야합니다.

Kafka는 메시지의 양이 많지만 크기가 아닌 경우에만 가장 잘 작동합니다.

출처 : https://www.quora.com/How-do-I-send-Large-messages-80-MB-in-Kafka



Kafka는 큰 메시지와 함께 작동하며 전혀 문제가 없습니다. Kafka 홈 페이지의 소개 페이지에서는이를 스토리지 시스템으로도 참조합니다.
calloc_org

3

landoop kafka를 사용하는 사람들의 경우 : 다음과 같은 환경 변수에 구성 값을 전달할 수 있습니다.

docker run -d --rm -p 2181:2181 -p 3030:3030 -p 8081-8083:8081-8083  -p 9581-9585:9581-9585 -p 9092:9092
 -e KAFKA_TOPIC_MAX_MESSAGE_BYTES=15728640 -e KAFKA_REPLICA_FETCH_MAX_BYTES=15728640  landoop/fast-data-dev:latest `

그리고 rdkafka를 사용하는 경우 다음과 같이 생산자 구성에 message.max.bytes를 전달합니다.

  const producer = new Kafka.Producer({
        'metadata.broker.list': 'localhost:9092',
        'message.max.bytes': '15728640',
        'dr_cb': true
    });

마찬가지로 소비자의 경우

  const kafkaConf = {
   "group.id": "librd-test",
   "fetch.message.max.bytes":"15728640",
   ... .. }                                                                                                                                                                                                                                                      
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.