Comment envoyer des messages volumineux avec Kafka (plus de 15 Mo)?
J'envoie des messages String à Kafka V. 0.8 à l'aide de l'API Java Producer. Si la taille du message est d'environ 15 Mo, je reçois un MessageSizeTooLargeException
. J'ai essayé de définir message.max.bytes
à 40 Mo, mais j'obtiens toujours l'exception. De petits messages ont fonctionné sans problèmes.
(L'exception apparaît dans le producteur, je n'ai pas de consommateur dans cette application.)
Que puis-je faire pour se débarrasser de cette exception?
Mon exemple producteur config
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);
}
Journal d'erreur:
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)
Vous devez ajuster trois (ou quatre) propriétés:
- Côté consommateur:
fetch.message.max.bytes
- ceci déterminera la plus grande taille d'un message pouvant être récupéré par le consommateur. - Côté courtier:
replica.fetch.max.bytes
- cela permettra aux réplicas des courtiers d'envoyer des messages dans le cluster et de s'assurer que les messages sont répliqués correctement. S'il est trop petit, le message ne sera jamais répliqué et le consommateur ne le verra jamais car le message ne sera jamais validé (entièrement répliqué). - Côté courtier:
message.max.bytes
- il s’agit de la taille la plus grande du message pouvant être reçu par le courtier par un producteur. - Côté courtier (par sujet):
max.message.bytes
- il s’agit de la plus grande taille du message que le courtier autorisera à être ajouté au sujet. Cette taille est validée en pré-compression. (La valeur par défaut estmessage.max.bytes
. Du courtier.)
J'ai découvert la difficulté avec le numéro 2 - vous ne recevez AUCUNE exception, message ou avertissement de la part de Kafka. Veillez donc à en tenir compte lorsque vous envoyez des messages volumineux.
Changements mineurs requis pour Kafka 0.10 et le nouveau consommateur par rapport à réponse de laughing_man :
- Courtier: aucune modification, vous devez toujours augmenter les propriétés
message.max.bytes
etreplica.fetch.max.bytes
.message.max.bytes
doit être égal ou inférieur (*) àreplica.fetch.max.bytes
. - Producteur: augmentez
max.request.size
pour envoyer le message plus volumineux. - Consommateur: augmentez
max.partition.fetch.bytes
pour recevoir des messages plus volumineux.
(*) Lisez les commentaires pour en savoir plus sur message.max.bytes
<= replica.fetch.max.bytes
Vous devez remplacer les propriétés suivantes:
Configuration du courtier ($ KAFKA_HOME/config/server.properties)
- replica.fetch.max.bytes
- message.max.bytes
Configurations du consommateur ($ KAFKA_HOME/config/consumer.properties)
Cette étape n'a pas fonctionné pour moi. Je l'ai ajouté à l'application grand public et tout fonctionnait bien
- fetch.message.max.bytes
Redémarrez le serveur.
regardez cette documentation pour plus d'infos: http://kafka.Apache.org/08/configuration.html
L’idée est d’avoir le même message envoyé de Kafka Producer à Kafka Broker, puis de le recevoir par Kafka consommateur i.e.
Producteur Kafka -> Kafka Courtier -> Kafka Consommateur
Supposons que si l'exigence est d'envoyer 15 Mo de message, alors le Producteur, le Courtier et le Consommateur, les trois, doivent être synchronisés. .
Producteur Kafka envoie 15 Mo ->Courtier Kafka Permet/Stocke 15 Mo ->Kafka Consumer reçoit 15 Mo
Le réglage doit donc être:
a) sur courtier:
message.max.bytes=15728640
replica.fetch.max.bytes=15728640
b) sur le consommateur:
fetch.message.max.bytes=15728640
Une chose importante à retenir est que l'attribut message.max.bytes
doit être synchronisé avec la propriété fetch.message.max.bytes
du consommateur. la taille d'extraction doit être au moins égale à la taille maximale du message, sinon les producteurs pourraient envoyer des messages plus volumineux que ce que le consommateur peut consommer/extraire. Cela vaut peut-être la peine d'y jeter un coup d'œil.
Quelle version de Kafka vous utilisez? Fournissez également des informations supplémentaires sur la trace que vous obtenez. y a-t-il quelque chose comme ... payload size of xxxx larger than 1000000
à venir dans le journal?
La réponse de @laughing_man est assez précise. Mais je voulais quand même donner une recommandation que j’ai apprise de Kafka expert , Stephane Maarek de Quora.
Kafka n’est pas conçu pour traiter des messages volumineux.
Votre API doit utiliser le stockage en nuage (Ex AWS S3) et simplement pousser vers Kafka ou tout courtier de messages avec une référence S3. Vous devez trouver un endroit pour conserver vos données, c’est peut-être un lecteur réseau, c’est peut-être n'importe quoi, mais ce ne devrait pas être un courtier de messages.
Maintenant, si vous ne voulez pas aller avec la solution ci-dessus
La taille maximale du message est de 1 Mo (le paramètre de vos courtiers s'appelle message.max.bytes
) Apache Kafka . Si vous en aviez vraiment besoin, augmentez cette taille et augmentez la mémoire tampon du réseau pour vos producteurs et vos consommateurs.
Et si vous souhaitez vraiment diviser votre message, assurez-vous que chaque message a exactement la même clé, de sorte qu'il soit poussé sur la même partition, et que le contenu de votre message contienne un "identifiant de pièce" afin que votre consommateur puisse le reconstruire complètement. .
Vous pouvez également explorer la compression si votre message est basé sur du texte (compression gzip, snappy, lz4), ce qui peut réduire la taille des données, mais pas de façon magique.
Encore une fois, vous devez utiliser un système externe pour stocker ces données et envoyer simplement une référence externe à Kafka. C’est une architecture très courante, avec laquelle vous devriez aller et qui est largement acceptée.
N'oubliez pas que Kafka ne fonctionne mieux que si les messages sont énormes, mais pas de taille.
Source: https://www.quora.com/How-do-I-send-Large-messages-80-MB-in-Kafka