Apache Kafka avec PHP
Diffusez des événements à haut débit avec Kafka.
Apache Kafka avec PHP est une leçon PHP Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage PHP Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours PHP Academy comprend 4 leçons au total.
Kafka avec PHP
Kafka n’est pas une file de tâches : c’est un journal de validation distribué, en ajout uniquement. Les producteurs ajoutent des enregistrements aux sujets ; les consommateurs les lisent à partir de leur propre position et peuvent relire l’historique. Kafka convient donc parfaitement aux flux d’événements à haut débit, à l’approvisionnement par événements et à l’alimentation de plusieurs groupes de consommateurs indépendants à partir d’un même flux.
En PHP, vous communiquez avec Kafka via ext-rdkafka, une liaison avec la bibliothèque C éprouvée librdkafka.
Journal, pas une file
Le changement de perspective entre RabbitMQ et Kafka :
- Les messages ne sont pas supprimés après leur consommation ; ils expirent selon une politique de rétention (durée ou taille).
- Chaque consommateur suit sa propre position — son emplacement dans le journal.
- Un sujet est divisé en partitions ; l’ordre n’est garanti qu’au sein d’une partition.
- Plusieurs groupes de consommateurs lisent le même sujet indépendamment.
Si vous avez besoin de relecture, de diffusion vers de nombreux lecteurs ou d’un débit considérable, Kafka convient. Si vous avez besoin d’un acheminement par message et de durées de vie limitées, RabbitMQ convient.
Installation de ext-rdkafka
Installez d’abord la bibliothèque native, puis l’extension PECL, et enfin, éventuellement, une enveloppe de niveau supérieur.
# Debian/Ubuntu
apt-get install -y librdkafka-dev
pecl install rdkafka
echo "extension=rdkafka.so" >> php.ini
# Optional ergonomic wrapper
composer require longlang/phpkafka # or arnaud-lb/php-rdkafka-stubs for IDEProduction d’enregistrements
Créez un RdKafka\Producer, obtenez une référence vers un sujet, puis appelez produce(). La clé détermine la partition dans laquelle un enregistrement est placé — même clé, même partition, ordre conservé. Appelez toujours flush() avant de quitter le programme, sinon vous perdrez les enregistrements mis en mémoire tampon.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$producer = new RdKafka\Producer($conf);
$topic = $producer->newTopic('orders');
// RD_KAFKA_PARTITION_UA = let the partitioner choose by key
$key = 'order-42';
$topic->produce(RD_KAFKA_PARTITION_UA, 0, json_encode(['id' => 42]), $key);
$producer->poll(0);
$result = $producer->flush(10000); // wait up to 10s
if ($result !== RD_KAFKA_RESP_ERR_NO_ERROR) {
throw new RuntimeException('Failed to flush');
}Partitionnement par clé
Le partitionnement est au cœur de la capacité de montée en charge et de l’ordre dans Kafka. Le partitionneur par défaut hache la clé de l’enregistrement : partition = hash(key) % numPartitions. Le choix d’une bonne clé est important :
- Clé basée sur
customerId→ tous les événements d’un client restent dans l’ordre et sur une seule partition. - Clé nulle → distribution à tour de rôle entre les partitions (débit maximal, sans garantie d’ordre).
Vous ne pouvez jamais réduire le nombre de partitions d’un sujet, et l’ajout de partitions remanie la correspondance des hachages — dimensionnez donc les partitions en fonction du parallélisme maximal dès le départ.
Groupes de consommateurs et positions
Utilisez le KafkaConsumer de haut niveau avec group.id. Kafka répartit les partitions entre les membres du groupe et les rééquilibre lorsque des membres rejoignent le groupe ou le quittent. Chaque membre ne lit que les partitions qui lui sont attribuées, ce qui fournit une mise à l’échelle horizontale sans effort.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$conf->set('group.id', 'order-emailers');
$conf->set('auto.offset.reset', 'earliest'); // start of log if no offset
$conf->set('enable.auto.commit', 'false'); // we commit manually
$consumer = new RdKafka\KafkaConsumer($conf);
$consumer->subscribe(['orders']);
while (true) {
$msg = $consumer->consume(5000);
if ($msg->err === RD_KAFKA_RESP_ERR_NO_ERROR) {
handle($msg->payload);
$consumer->commit($msg); // commit offset AFTER work
}
}
function handle(string $p): void {}Quand valider
La validation de la position définit votre sémantique de livraison :
- Valider après le traitement → au moins une fois (un plantage avant la validation entraîne une nouvelle lecture de l’enregistrement).
- Valider avant le traitement → au plus une fois (un plantage entraîne sa perte).
La validation automatique (enable.auto.commit=true) s’effectue selon une minuterie, que votre travail soit terminé ou non — c’est pratique, mais un plantage peut faire disparaître des enregistrements sans avertissement. Désactivez-la et validez manuellement lorsque la fiabilité est importante.
Gestion des erreurs de consommation
Chaque valeur renvoyée par consume() n’est pas forcément un message. Vous devez examiner le code d’erreur — __PARTITION_EOF et __TIMED_OUT sont des signaux de contrôle normaux, pas des échecs.
<?php
$msg = $consumer->consume(2000);
switch ($msg->err) {
case RD_KAFKA_RESP_ERR_NO_ERROR:
echo "Got: {$msg->payload} @ offset {$msg->offset}\n";
break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
echo "Reached end of partition\n"; // caught up, keep polling
break;
case RD_KAFKA_RESP_ERR__TIMED_OUT:
echo "No message this poll\n";
break;
default:
throw new \Exception($msg->errstr(), $msg->err);
}Optimisation du débit
Le débit de Kafka repose sur le regroupement des enregistrements. Principaux paramètres du producteur :
linger.ms— attendez brièvement pour regrouper davantage d’enregistrements par requête (par ex. 5–20 ms).batch.size/queue.buffering.max.messages— des tampons plus grands et moins d’allers-retours.compression.type—lz4ouzstdréduit considérablement le coût réseau.acks—allpour la durabilité,1pour une latence plus faible.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$conf->set('compression.type', 'lz4');
$conf->set('linger.ms', '10');
$conf->set('batch.size', '65536');
$conf->set('acks', 'all');
$producer = new RdKafka\Producer($conf);Rappels de rapport de livraison
Comme produce() est asynchrone, un échec d’envoi ne déclenche pas d’exception immédiatement. Enregistrez un rappel de rapport de livraison dans la configuration du producteur pour connaître le résultat de chaque enregistrement — c’est le seul moyen fiable de détecter les échecs silencieux du producteur en PHP.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$conf->setDrMsgCb(function ($producer, $msg) {
if ($msg->err) {
fwrite(STDERR, 'Delivery FAILED: ' . rd_kafka_err2str($msg->err) . "\n");
} else {
echo "Delivered to partition {$msg->partition} @ offset {$msg->offset}\n";
}
});
$producer = new RdKafka\Producer($conf);
// poll() services the callback queue; call it after producing
$producer->poll(0);Pièges propres à PHP
Kafka suppose que les clients sont de longue durée ; le cycle de vie des requêtes PHP s’y oppose :
- Les producteurs mettent les enregistrements en mémoire tampon de manière asynchrone — appelez toujours
flush()avant la fin du script, sinon les enregistrements seront perdus. - Exécutez les consommateurs comme des processus CLI persistants sous la supervision d’un superviseur, jamais dans le cadre d’une requête Web.
- Les rééquilibrages interrompent la consommation ; gardez le traitement de chaque message court ou utilisez généreusement
max.poll.interval.msafin de ne pas être exclu du groupe. - Définissez
log_levelet enregistrez le rappel de rapport de livraison du producteur pour détecter les échecs silencieux.
Vérification rapide
Garanties d’ordre dans Kafka.
Récapitulatif
Kafka, à la manière de PHP :
- Kafka est un journal relisible, pas une file ; les consommateurs suivent des positions.
- Le partitionnement par clé garantit l’ordre par clé et permet la mise à l’échelle.
- Les groupes de consommateurs se répartissent les partitions et se rééquilibrent automatiquement.
- Validez les positions après le traitement pour une livraison au moins une fois ; désactivez la validation automatique pour garder le contrôle.
- Ajustez
linger.ms,batch.sizeetcompression.type; appelez toujoursflush().
Ensuite : relier ces primitives pour créer des flux de travail pilotés par événements fiables.
Questions Fréquemment Posées
La leçon « Apache Kafka avec PHP » est-elle gratuite ?
Oui — le texte complet de « Apache Kafka avec PHP » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours PHP Academy, passe à CoddyKit PRO. Le cours PHP Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Apache Kafka avec PHP » ?
Diffusez des événements à haut débit avec Kafka. Tu pratiques PHP Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer PHP Academy ?
Aucune expérience préalable n'est requise. PHP Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Apache Kafka avec PHP » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon PHP Academy ?
Oui. Chaque leçon PHP Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Pourquoi la messagerie asynchrone
- Travailler avec RabbitMQ en PHP
- Apache Kafka avec PHP
- Créer des flux de travail orientés événements