- Publier ou s’abonner à des flux de données.
- Mettre en place un stockage tolérant aux pannes.
- Traiter les flux dès qu’ils sont disponibles.
Créer une table
kafka_broker_list— Une liste de brokers séparés par des virgules (par exemple,localhost:9092).kafka_topic_list— Une liste de topics Kafka.kafka_group_name— Un groupe de consommateurs Kafka. Les offsets de lecture sont suivis séparément pour chaque groupe. Si vous ne souhaitez pas que les messages soient dupliqués dans le cluster, utilisez partout le même nom de groupe.kafka_format— Format des messages. Utilise la même notation que la fonction SQLFORMAT, par exempleJSONEachRow. Pour plus d’informations, consultez la section Formats.
kafka_security_protocol- Protocole utilisé pour communiquer avec les brokers. Valeurs possibles :plaintext,ssl,sasl_plaintext,sasl_ssl.kafka_sasl_mechanism- Mécanisme SASL à utiliser pour l’authentification. Valeurs possibles :GSSAPI,PLAIN,SCRAM-SHA-256,SCRAM-SHA-512,OAUTHBEARER.kafka_sasl_username- Nom d’utilisateur SASL à utiliser avec les mécanismesPLAINetSASL-SCRAM-...kafka_sasl_password- Mot de passe SASL à utiliser avec les mécanismesPLAINetSASL-SCRAM-...kafka_schema— Paramètre à utiliser si le format nécessite une définition de schéma. Par exemple, Cap’n Proto requiert le chemin vers le fichier de schéma ainsi que le nom de l’objet racineschema.capnp:Message.kafka_schema_registry_skip_bytes— Nombre d’octets à ignorer au début de chaque message lors de l’utilisation du registre de schémas avec des en-têtes d’enveloppe (par ex., AWS Glue Schema Registry, qui inclut une enveloppe de 19 octets). Plage :[0, 255]. Valeur par défaut :0.kafka_num_consumers— Nombre de consumers par table. Indiquez-en davantage si le throughput d’un consumer est insuffisant. Le nombre total de consumers ne doit pas dépasser le nombre de partitions du topic, puisqu’un seul consumer peut être attribué par partition, et ne doit pas non plus être supérieur au nombre de cœurs physiques du server sur lequel ClickHouse est déployé. Valeur par défaut :1.kafka_max_block_size— Taille maximale du batch (en messages) pour le poll. Valeur par défaut : max_insert_block_size.kafka_skip_broken_messages— Tolérance de l’analyseur de messages Kafka aux messages incompatibles avec le schéma par block. Sikafka_skip_broken_messages = N, le moteur ignore N messages Kafka qui ne peuvent pas être analysés (un message équivaut à une ligne de données). Valeur par défaut :0.kafka_commit_every_batch— Effectue un commit pour chaque batch consommé et traité, au lieu d’un seul commit après l’écriture d’un block entier. Valeur par défaut :0.kafka_client_id— Identifiant du client. Vide par défaut.kafka_poll_timeout_ms— Timeout pour un poll Kafka unique. Valeur par défaut : stream_poll_timeout_ms.kafka_poll_max_batch_size— Nombre maximal de messages pouvant être récupérés en un seul poll Kafka. Valeur par défaut : max_block_size.kafka_flush_interval_ms— Timeout pour le flush des données depuis Kafka. Valeur par défaut : stream_flush_interval_ms.kafka_consumer_reschedule_ms— Intervalle de replanification lorsque le stream processing Kafka est bloqué (par ex., lorsqu’aucun message n’est disponible à la consommation). Ce paramètre contrôle le délai avant que le consumer ne réessaie de poll. Ne doit pas dépasserkafka_consumers_pool_ttl_ms. Valeur par défaut :500millisecondes.kafka_thread_per_consumer— Fournit un thread indépendant pour chaque consumer. Lorsqu’elle est activée, chaque consumer flush les données indépendamment, en parallèle (sinon, les rows de plusieurs consumers sont squashed pour former un block). Valeur par défaut :0.kafka_handle_error_mode— Gestion des errors pour le Kafka engine. Valeurs possibles : default (une exception est levée si l’analyse d’un message échoue), stream (le message d’exception et le message brut sont enregistrés dans les virtual columns_erroret_raw_message), dead_letter_queue (les données liées à l’error sont enregistrées dans system.dead_letter_queue).kafka_commit_on_select— Effectue un commit des messages lorsqu’une requêteSELECTest exécutée. Valeur par défaut :false.kafka_consumer_acquire_timeout_ms— Timeout en millisecondes pour l’acquisition d’un consumer Kafka lors de requêtesSELECTdirectes sur une tableKafka2(avec stockage des offsets basé sur Keeper). Lorsque plusieurs requêtesSELECTdirectes concurrentes s’exécutent sur la même table, chacune doit attendre que des consumers deviennent disponibles. Ce timeout évite les deadlocks lorsque des requêtes détiennent différents sous-ensembles de consumers. Valeur par défaut :30000.kafka_max_rows_per_message— Nombre maximal de rows écrites dans un message Kafka pour les formats basés sur les lignes. Valeur par défaut :1.kafka_autodetect_client_rack— Définit automatiquement le paramètreclient.rackpourlibrdkafkaafin de privilégier les répliques Kafka les plus proches. Sources prises en charge :AWS_ZONE_IDpour l’ID de zone de disponibilité AWS IMDSv2, par exempleeuc1-az1;AWS_ZONE_NAMEpour le nom de zone de disponibilité AWS IMDSv2, par exempleeu-central-1a;GCP_ZONEpour la zone du service de métadonnées GCP, par exempleeurope-central2-a;CLICKHOUSEpour utiliser la détection interne de ClickHouse, qui peut s’appuyer sur les métadonnées du cloud ou sur la configuration ;AWS_ZONE_NAME_THEN_GCP_ZONEpour essayerAWS_ZONE_NAME, puisGCP_ZONE. Par défaut : chaîne vide, désactivé. Conseil : les formats de zone de disponibilité varient selon les environnements. Amazon MSK utilise généralement des ID de zone, privilégiez doncAWS_ZONE_ID. Confluent Cloud utilise généralement des noms de zone, privilégiez doncAWS_ZONE_NAME. En cas de doute, utilisezAWS_ZONE_NAME_THEN_GCP_ZONEou vérifiez la valeurbroker.racksur votre cluster. Remarque : les brokers Kafka doivent être configurés avecbroker.racketreplica.selector.class=org.apache.kafka.common.replica.RackAwareReplicaSelector.kafka_compression_codec— Codec de compression utilisé pour produire les messages. Valeurs prises en charge : chaîne vide,none,gzip,snappy,lz4,zstd. Si la chaîne est vide, le codec de compression n’est pas défini par la table ; les valeurs des fichiers de configuration ou la valeur par défaut delibrdkafkaseront alors utilisées. Par défaut : chaîne vide.kafka_compression_level— Paramètre de niveau de compression pour l’algorithme sélectionné par kafka_compression_codec. Des valeurs plus élevées offrent une meilleure compression, au prix d’une utilisation du CPU plus importante. La plage de valeurs utilisables dépend de l’algorithme :[0-9]pourgzip;[0-12]pourlz4; uniquement0poursnappy;[0-12]pourzstd;-1= niveau de compression par défaut dépendant du codec. Par défaut :-1.kafka_map_virtual_columns_on_write— Si cette option est activée, les colonnes portant les noms spéciaux_key,_timestamp,_headers.nameet_headers.valuedans le schéma de la table sont associées aux métadonnées correspondantes du message Kafka lors deINSERTet sont exclues du corps du message. Voir Correspondance entre les colonnes et les métadonnées des messages Kafka. Par défaut :false.
Le moteur de table Kafka ne prend pas en charge les colonnes avec une valeur par défaut. Si vous avez besoin de colonnes avec une valeur par défaut, vous pouvez les ajouter dans une vue matérialisée (voir ci-dessous).
Description
SELECT n’est pas particulièrement utile pour lire les messages (sauf pour le débogage), car chaque message ne peut être lu qu’une seule fois. Il est plus pratique de créer des flux en temps réel à l’aide de vues matérialisées. Pour cela :
- Utilisez le moteur pour créer un consumer Kafka et considérez-le comme un flux de données.
- Créez une table avec la structure souhaitée.
- Créez une vue matérialisée qui convertit les données du moteur et les insère dans une table créée précédemment.
MATERIALIZED VIEW se connecte au moteur, elle commence à collecter les données en arrière-plan. Cela vous permet de recevoir en continu des messages de Kafka et de les convertir au format requis à l’aide de SELECT.
Une table Kafka peut avoir autant de vues matérialisées que vous le souhaitez : elles ne lisent pas directement les données de la table Kafka, mais reçoivent les nouveaux enregistrements (par blocs). Vous pouvez ainsi écrire dans plusieurs tables avec des niveaux de granularité différents (avec regroupement - agrégation ou sans).
Exemple :
ALTER, nous vous recommandons de désactiver la vue matérialisée afin d’éviter tout écart entre la table cible et les données de la vue.
Configuration
<kafka>) et une au niveau du topic (sous <kafka><kafka_topic>). La configuration globale est appliquée en premier, puis la configuration au niveau du topic est appliquée (si elle existe).
_) à la place d’un point. Par exemple, check.crcs=true deviendra <check_crcs>true</check_crcs>.
Prise en charge de Kerberos
security_protocol avec la valeur sasl_plaintext. Cela suffit si le ticket d’octroi de tickets Kerberos est obtenu et mis en cache par les mécanismes du système d’exploitation.
ClickHouse peut gérer les informations d’identification Kerberos à l’aide d’un fichier keytab. Tenez compte des éléments enfants sasl_kerberos_service_name, sasl_kerberos_keytab et sasl_kerberos_principal.
Exemple :
Colonnes virtuelles
_topic— Topic Kafka. Type de données :LowCardinality(String)._key— Clé du message. Type de données :String._offset— Offset du message. Type de données :UInt64._timestamp— Horodatage du message. Type de données :Nullable(DateTime)._timestamp_ms— Horodatage du message en millisecondes. Type de données :Nullable(DateTime64(3))._partition— Partition du topic Kafka. Type de données :UInt64._headers.name— Tableau des clés d’en-tête du message. Type de données :Array(String)._headers.value— Tableau des valeurs d’en-tête du message. Type de données :Array(String).
kafka_handle_error_mode='stream' :
_raw_message- Message brut qui n’a pas pu être analysé correctement. Type de données :String._error- Message d’exception généré lors d’une erreur d’analyse. Type de données :String.
_raw_message et _error sont renseignées uniquement en cas d’exception pendant l’analyse ; elles sont toujours vides lorsque le message a été analysé correctement.
Correspondance entre les colonnes et les métadonnées des messages Kafka
INSERT INTO, le moteur Kafka utilise toujours une colonne nommée _key (de type String) comme clé du message Kafka et une colonne nommée _timestamp (de type DateTime) comme horodatage du message Kafka — si ces colonnes existent dans la table. Par défaut, ces colonnes apparaissent également dans la charge utile du message produit, aux côtés des autres colonnes.
Avec kafka_map_virtual_columns_on_write = 1, le comportement change :
_key(typeString) — associé à la clé du message Kafka._timestamp(typeDateTime) — associé à l’horodatage du message Kafka._headers.name(typeArray(String)) et_headers.value(typeArray(String)) — associés aux en-têtes des messages Kafka. Chaque paire(_headers.name[i], _headers.value[i])devient un en-tête Kafka. Comme_headers.nameet_headers.valuepartagent le préfixe Nested_headers, ClickHouse exige que les deux tableaux aient la même taille pour chaque ligne.
{"event_json":"{\"a\":1}"}, la clé session-42, l’horodatage actuel et deux en-têtes source=api et trace_id=abc-123.
Prise en charge des formats de données
- Pour les formats basés sur les lignes, le nombre de lignes dans un message Kafka peut être contrôlé en définissant
kafka_max_rows_per_message. - Pour les formats basés sur les blocs, il n’est pas possible de diviser un bloc en parties plus petites, mais le nombre de lignes dans un bloc peut être contrôlé par le paramètre général max_block_size.
Moteur pour stocker les offsets validés dans ClickHouse Keeper
allow_experimental_kafka_offsets_storage_in_keeper est activé, deux paramètres supplémentaires peuvent être spécifiés pour le moteur de table Kafka :
kafka_keeper_pathspécifie le chemin vers la table dans ClickHouse Keeperkafka_replica_namespécifie le nom de la réplique dans ClickHouse Keeper
Limites connues
- Supprimer puis recréer rapidement la table, ou spécifier le même chemin ClickHouse Keeper pour différents moteurs, peut entraîner des problèmes. Comme bonne pratique, vous pouvez utiliser
{uuid}danskafka_keeper_pathpour éviter les conflits de chemins. - Pour garantir des lectures répétables, les messages ne peuvent pas être consommés à partir de plusieurs partitions sur un seul thread. En revanche, les consommateurs Kafka doivent être interrogés régulièrement pour être maintenus actifs. En raison de ces deux contraintes, nous avons décidé d’autoriser la création de plusieurs consommateurs uniquement si
kafka_thread_per_consumerest activé, sinon il est trop compliqué d’éviter les problèmes liés à l’interrogation régulière des consommateurs.