web-dev-qa-db-fra.com

Quand le client Apache Kafka lance-t-il une exception "Batch Expired"?

En utilisant le client Apache Kafka Java (0.9)), j'essaie d'envoyer une longue série d'enregistrements au courtier à l'aide de la commande Kafka Producer classe .

La méthode asynchrone méthode d'envoi renvoie immédiatement pendant un moment, puis commence à bloquer chaque appel pendant une courte période. Après environ trente secondes, le client commence à lancer des exceptions ( TimeoutException ), avec le message "Lot expiré" .

Quelles circonstances ont provoqué cette exception?

36
James Thomas

Cette exception indique que vous mettez en file d'attente des enregistrements plus rapidement qu'ils ne peuvent être envoyés.

Lorsque vous appelez la méthode send , le ProducerRecord sera stocké dans une mémoire tampon interne pour l'envoi au courtier. La méthode retourne immédiatement une fois que ProducerRecord a été mis en mémoire tampon, qu'il ait été envoyé ou non.

Les enregistrements sont regroupés dans lots à envoyer au courtier afin de réduire le transport entendu par message et d'augmenter le débit.

Une fois qu'un enregistrement est ajouté à un lot, il existe une limite de temps pour l'envoi de ce lot afin de s'assurer qu'il a été envoyé dans une durée spécifiée. Ceci est contrôlé par le paramètre de configuration Producer, request.timeout.ms , qui est défini par défaut sur trente secondes.

Si le lot a été mis en file d'attente plus longtemps que la limite de délai d'attente, l'exception sera levée. Les enregistrements de ce lot seront supprimés de la file d’envoi.

L'augmentation du délai d'attente, à l'aide du paramètre de configuration, permettra au client de mettre les lots en file d'attente plus longtemps avant leur expiration.

47
James Thomas

J'ai eu cette exception dans un contexte complètement différent.

J'ai mis en place un mini cluster composé d'un zookeeper vm, d'un courtier vm et d'un producteur/consommateur vm. J'ai ouvert tous les ports nécessaires sur le serveur (9092) et sur le zookeeper (2181), puis j'ai essayé de publier un message du consommateur/éditeur vm au courtier. J'ai eu l'exception mentionnée par l'OP, mais comme je n'avais jusqu'à présent publié qu'un seul message (ou du moins, j'ai essayé de le faire), la solution ne pourrait pas être d'augmenter le délai d'attente ou la taille du lot. J'ai donc cherché et trouvé cette liste de diffusion décrivant un problème similaire que j'ai rencontré lors de la tentative de consommation de messages provenant du consommateur/producteur vm (ClosedChannelException): http://grokbase.com/t/kafka/users/152jsjekrm/kafka-config distant Le dernier message de cette liste de diffusion décrit comment résoudre le problème.

Longue histoire courte, si vous affrontez à la fois le ChannelClosedException et le Batch Expired _ exception, vous devrez probablement changer cette ligne comme suit dans le server.config fichier et redémarrez le courtier:

advertised.Host.name=<broker public IP address>

S'il n'est pas défini, il retourne à la Host.name propriété (qui n'est probablement pas non plus définie) puis revient au nom d'hôte canonique de la classe InetAddress Java, qui n'est finalement pas correcte, bien sûr et prêtant ainsi à confusion les nœuds distants.

31
Roberto

Le paramètre qui contrôle l'heure avant l'envoi au courtier est linger.ms. Sa valeur par défaut est 0 (pas de délai).

3
S. Sar

J'utilise Kafka Java du client 0.11.0.0. J'ai également commencé à voir le même modèle dans l'incapacité de produire des messages volumineux de manière cohérente. les messages, et échouant pour certains autres. (Bien que les messages réussis et échoués aient été de la même taille) .Dans mon cas, la taille de chaque message était d'environ 60 Ko, ce qui est beaucoup plus élevé que la valeur par défaut de Kafka batch.size de 16 Ko, mon linger.ms a également la valeur 0 par défaut. Cette erreur est générée car le client Producer arrive à expiration avant de pouvoir recevoir une réponse du serveur. En gros, dans mon code, cet appel a expiré: kafkaProd.send(pr).get(). Pour résoudre ce problème, je devais augmenter la valeur par défaut request.timeout.ms du client Producer à 60000

2
Binita Bharati

Avait un problème similaire avec Kafka s'exécutant dans un docker-compose. Mon docker-compose.yml était réglé avec

 KAFKA_ADVERTISED_Host_NAME: kafka
 ports:
        - 9092:9092

Mais quand j'ai essayé d'envoyer un message avec un chameau de l'extérieur du docker

to("kafka:test?brokers=localhost:9092")

J'ai une TimeoutException. Je l'ai résolu en ajoutant

127.0.0.1 kafka

windows\System32\drivers\etc\hosts puis modifiez mon URL de chameau en

to("kafka:test?brokers=kafka:9092")
1
Rory G