2017-10-05 6 views
1

Voici le flux de messagerie entrant dans notre plate-forme IdO:Kafka Quotas de producteurs

Device ---(MQTT)---> RabbitMQ Broker ---(AMQP)---> Apache Storm ---> Kafka 

Je cherche à mettre en œuvre une solution qui effectivement des limites/étrangle la quantité de données publiées à Kafka par seconde sur un per- base de client.

La stratégie actuelle en place utilise le RateLimiter de Guava où chaque périphérique obtient sa propre instance mise en cache localement. Lorsqu'un message de périphérique est reçu, le RateLimiter mappé à cet ID de périphérique est extrait du cache et la méthode tryAquire() est appelée. Si un permis a été acquis avec succès, le tuple est transmis comme d'habitude à Kafka, sinon, le quota est dépassé et le message est rejeté en silence. Cette méthode est plutôt lourde et à un moment donné condamnée à échouer ou devenir un goulot d'étranglement. J'ai lu sur les quotas de byte-rate de Kafka et je crois que cela fonctionnerait parfaitement dans notre cas, d'autant plus que les clients Kafka peuvent être configurés dynamiquement. Lorsqu'un périphérique virtuel est créé dans notre plate-forme, un nouveau client.id doit être ajouté à client.id == deviceId.

Supposons le cas d'utilisation suivante comme exemple:

  1. Administrateur crée 2 périphériques virtuels: humidité & capteur de température
  2. Une règle est déclenchée pour créer de nouvelles entrées utilisateur/clientId dans Kafka pour les dispositifs ci-dessus
  3. définir leurs valeurs de quota de production par l'intermédiaire de Kafka CLI
  4. les deux appareils émettent un message d'événement entrant
  5. ...?

Voici ma question. Si vous utilisez une seule instance Producer, est-il possible de spécifier un client.id dans ProducerRecord ou quelque part dans Producer avant d'appeler le send()? Si un Producteur n'est autorisé qu'à un seul client.id, cela signifie-t-il que chaque appareil doit avoir son propre Producteur? Si seulement un mappage un-à-un est autorisé, serait-il sage de mettre en cache potentiellement des centaines, sinon des milliers, d'instances Producer, une pour chaque périphérique? Y a-t-il une meilleure approche dont je ne suis pas encore au courant? Remarque: Notre plate-forme est un «système de porte ouverte», ce qui signifie que les clients ne reçoivent jamais une réponse d'erreur telle que «Taux dépassé» ou toute erreur d'ailleurs. Tout est transparent pour l'utilisateur final. Pour cette raison, je ne peux pas interférer avec les données dans RabbitMQ ou rediriger les messages vers des files d'attente différentes. Ma seule option pour intégrer ce truc se situe entre Storm ou Kafka.

Répondre

0

Bien que vous puissiez spécifier client.id sur l'objet Producer, n'oubliez pas qu'ils sont lourds et que vous ne souhaiterez peut-être pas en créer plusieurs instances (en particulier un par appareil). En ce qui concerne la réduction du nombre de Producer, avez-vous envisagé de créer un par utilisateur, et non par périphérique, ou même d'en avoir un pool partagé fini? Les en-têtes de message Kafka pourraient alors être utilisés pour discerner quel périphérique a réellement produit les données. L'inconvénient est que vous devez limiter la production de messages de votre côté, de sorte qu'un périphérique n'empare pas toutes les ressources des autres.

Cependant, vous pouvez limiter les utilisateurs sur le côté du courtier Kafka, avec la configuration par défaut l'application utilisateur/client:

> bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type clients --entity-default 
Updated config for entity: default client-id. 

Voir https://kafka.apache.org/documentation/#design_quotas pour plus d'exemples et explications en profondeur.

Comment les messages sont discernées dépend de votre architecture, les solutions possibles sont les suivantes:

+0

_ _ Pourriez-vous préciser cette s'il vous plaît et EXPOSÉ « têtes de message Kafka pourraient alors être utilisés pour discerner quel appareil réellement produit les données. » dans la façon de le mettre en œuvre? Même si je l'ai fait par utilisateur, j'ai encore besoin de savoir comment dire à Kafka que le message X provient du client 1, le message Y provient du client 2, et ainsi de suite .. qui sont tous publiés via un * * single **, instance Producer partagée. – user2208562