Vue d’ensemble
- Utilise
serdepour l’encodage/décodage des lignes. - Prend en charge les attributs
serde:skip_serializing,skip_deserializing,rename. - Utilise le format
RowBinaryvia HTTP.- Il est prévu de passer à
Nativevia TCP.
- Il est prévu de passer à
- Prend en charge TLS (via les fonctionnalités
native-tlsetrustls-tls). - Prend en charge la compression et la décompression (LZ4).
- Fournit des API pour interroger ou insérer des données, exécuter des DDLs et faire du batching côté client.
- Fournit des mocks pratiques pour les tests unitaires.
Installation
Cargo.toml :
Fonctionnalités de Cargo
lz4(activée par défaut) — active les variantesCompression::Lz4etCompression::Lz4Hc(_). Si elle est activée,Compression::Lz4est utilisée par défaut pour toutes les requêtes, sauf pourWATCH.native-tls— prend en charge les URL dont le schéma estHTTPSviahyper-tls, qui s’appuie sur OpenSSL.rustls-tls— prend en charge les URL dont le schéma estHTTPSviahyper-rustls, qui ne s’appuie pas sur OpenSSL.inserter— activeclient.inserter().test-util— ajoute des mocks. Voir l’exemple. À utiliser uniquement dansdev-dependencies.watch— active la fonctionnalitéclient.watch. Voir la section correspondante pour plus de détails.uuid— ajouteserde::uuidpour fonctionner avec le crate uuid.time— ajouteserde::timepour fonctionner avec le crate time.
Compatibilité des versions de ClickHouse
wa-37420 pour résoudre ce problème. Remarque : cette fonctionnalité ne doit pas être utilisée avec des versions plus récentes de ClickHouse.
Exemples
Utilisation
Le crate ch2rs permet de générer un type de ligne à partir de ClickHouse.
Création d’une instance de client
Connexion HTTPS ou à ClickHouse Cloud
rustls-tls ou native-tls.
Ensuite, créez le client comme d’habitude. Dans cet exemple, les variables d’environnement sont utilisées pour stocker les informations de connexion :
- Exemple HTTPS avec ClickHouse Cloud dans le dépôt du client. Cet exemple devrait également s’appliquer aux connexions HTTPS on-premise.
Sélection de lignes
- L’espace réservé
?fieldsest remplacé parno, name(champs deRow). - L’espace réservé
?est remplacé par les valeurs dans les appelsbind()suivants. - Les méthodes pratiques
fetch_one::<Row>()etfetch_all::<Row>()peuvent être utilisées pour obtenir respectivement la première ligne ou l’ensemble des lignes. sql::Identifierpeut être utilisé pour lier des noms de table.
query(...).with_option("wait_end_of_query", "1") afin d’activer la mise en tampon des réponses côté serveur. Plus de détails. L’option buffer_size peut également être utile.
Insertion de lignes
- Si
end()n’est pas appelé, l’INSERTest annulé. - Les lignes sont envoyées progressivement sous forme de flux afin de répartir la charge réseau.
- ClickHouse n’effectue des inserts par lot de manière atomique que si toutes les lignes tiennent dans la même partition et que leur nombre est inférieur à
max_insert_block_size.
Async insert (batching côté serveur)
async_insert à la méthode insert (ou même directement à l’instance Client, afin qu’elle s’applique à tous les appels à insert).
- Exemple d’insert asynchrone dans le dépôt du client.
Fonctionnalité Inserter (batching côté client)
inserter.
Insertertermine l’insertion active danscommit()si l’un des seuils (max_bytes,max_rows,period) est atteint.- L’intervalle entre la fin des
INSERTactives peut être décalé à l’aide dewith_period_biasafin d’éviter des pics de charge dus à des inserters parallèles. Inserter::time_left()peut être utilisé pour détecter la fin de la période en cours. Appelez à nouveauInserter::commit()pour vérifier les limites si votre flux émet rarement des éléments.- Les seuils temporels sont implémentés à l’aide de la crate quanta pour accélérer
inserter. Ils ne sont pas utilisés sitest-utilest activé (le temps peut ainsi être géré partokio::time::advance()dans des tests personnalisés). - Toutes les lignes entre les appels à
commit()sont insérées dans la même instructionINSERT.
Exécution des DDLs
wait_end_of_query. Voici comment procéder :
Paramètres ClickHouse
with_option. Par exemple :
query, cela fonctionne de la même manière avec les méthodes insert et inserter ; de plus, cette même méthode peut être appelée sur l’instance Client pour définir des paramètres globaux pour toutes les requêtes.
ID de requête
.with_option, vous pouvez définir l’option query_id afin d’identifier les requêtes dans le journal des requêtes de ClickHouse.
query, cela fonctionne de façon similaire avec les méthodes insert et inserter.
Si vous définissez
query_id manuellement, assurez-vous qu’il est unique. Les UUIDs sont un bon choix pour cela.ID de session
query_id, vous pouvez définir session_id pour exécuter les instructions dans une même session. session_id peut être défini soit globalement, au niveau du client, soit pour chaque appel à query, insert ou inserter.
Avec les déploiements en cluster, en l’absence de “sticky sessions”, vous devez être connecté à un nœud précis du cluster pour utiliser correctement cette fonctionnalité, car, par exemple, un équilibreur de charge round-robin ne garantit pas que les requêtes suivantes seront traitées par le même nœud ClickHouse.
En-têtes HTTP personnalisés
Client HTTP personnalisé
Types de données
Voir aussi les exemples supplémentaires :
(U)Int(8|16|32|64|128)correspond, dans les deux sens, aux types(u|i)(8|16|32|64|128)correspondants ou à des newtypes qui les encapsulent.(U)Int256ne sont pas pris en charge directement, mais il existe une solution de contournement.Float(32|64)correspond, dans les deux sens, aux typesf(32|64)correspondants ou à des newtypes qui les encapsulent.Decimal(32|64|128)correspond, dans les deux sens, aux typesi(32|64|128)correspondants ou à des newtypes qui les encapsulent. Il est plus pratique d’utiliserfixnumou une autre implémentation de nombres signés à virgule fixe.Booleancorrespond, dans les deux sens, àboolou à des newtypes qui l’encapsulent.Stringcorrespond, dans les deux sens, à n’importe quel type de chaîne ou d’octets, par exemple&str,&[u8],String,Vec<u8>ouSmartString. Les newtypes sont également pris en charge. Pour stocker des octets, envisagez d’utiliserserde_bytes, car c’est plus efficace.
FixedString(N)est pris en charge en tant que tableau d’octets, par exemple[u8; N].
Enum(8|16)sont pris en charge viaserde_repr.
UUIDest converti depuis et versuuid::Uuidà l’aide deserde::uuid. Nécessite la fonctionnalitéuuid.
IPv6est converti depuis/versstd::net::Ipv6Addr.IPv4est converti depuis/versstd::net::Ipv4Addrà l’aide deserde::ipv4.
Datese convertit depuis/versu16ou unnewtypel’encapsulant, et représente un nombre de jours écoulés depuis1970-01-01.time::Dateest également pris en charge viaserde::time::date, ce qui nécessite l’activation de la fonctionnalitétime.
Date32se convertit vers/depuisi32ou unnewtypel’encapsulant, et représente un nombre de jours écoulés depuis1970-01-01.time::Dateest également pris en charge viaserde::time::date32, ce qui nécessite la fonctionnalitétime.
DateTimese convertit en/depuisu32ou un newtype qui l’encapsule, et représente un nombre de secondes écoulées depuis l’époque Unix.time::OffsetDateTimeest également pris en charge viaserde::time::datetime, ce qui nécessite la featuretime.
DateTime64(_)se convertit en/depuisi32ou un newtype qui l’encapsule, et représente le temps écoulé depuis l’époque UNIX. De plus,time::OffsetDateTimeest pris en charge viaserde::time::datetime64::*, ce qui nécessite la fonctionnalitétime.
Tuple(A, B, ...)se convertit vers/depuis(A, B, ...)ou un newtype qui l’encapsule.Array(_)se convertit vers/depuis n’importe quel slice, par ex.Vec<_>,&[_]. Les nouveaux types sont également pris en charge.Map(K, V)se comporte commeArray((K, V)).LowCardinality(_)est pris en charge de manière transparente.Nullable(_)se convertit vers/depuisOption<_>. Pour les helpersclickhouse::serde::*, ajoutez::option.
Nestedest pris en charge en fournissant plusieurs tableaux avec changement de nom.
- Les types
Geosont pris en charge.Pointse comporte comme un tuple(f64, f64), et les autres types ne sont que des slices de points.
- Les types de données
Variant,DynamicetJSON(nouveau) ne sont pas encore pris en charge.
Simulation
SELECT, INSERT et WATCH. Cette fonctionnalité peut être activée avec la fonctionnalité test-util. Ne l’utilisez que comme dépendance de développement.
Voir l’exemple.
Dépannage
CANNOT_READ_ALL_DATA
CANNOT_READ_ALL_DATA est que la définition de la ligne côté application ne correspond pas à celle de ClickHouse.
Considérez la table suivante :
EventLog est défini côté application avec des types incompatibles, par exemple :
EventLog :
Limitations connues
- Les types de données
Variant,DynamicetJSON(nouveau) ne sont pas encore pris en charge. - Le binding de paramètres côté serveur n’est pas encore pris en charge ; voir ce ticket pour en suivre l’avancement.