Estado experimental
Las interfaces del Client principal, del origen de datos, de sesión y de operaciones, así como las extensiones de inyección de dependencias, generan la advertencia del compiladorCHTCP0001. Para reconocerla mientras evalúa la API, añada CHTCP0001
a NoWarn en el archivo de su proyecto:
Versiones de .NET compatibles
El Client TCP nativo es compatible con las siguientes versiones de .NET:- .NET 8.0
- .NET 9.0
- .NET 10.0
Versiones de ClickHouse compatibles
El Client TCP es oficialmente compatible con las 2 últimas versiones LTS, así como con las 3 últimas versiones publicadas del servidor de ClickHouse.Instalación
El Client TCP nativo se incluye en el paqueteClickHouse.Driver. Instálelo desde NuGet:
Inicio rápido
Migración desde el Client HTTP
La API TCP es independiente deIClickHouseClient; no es una opción de transporte para
ClickHouseClient ni para ClickHouseConnection. Puede reutilizar la mayor parte del SQL, pero debe crear un
ClickHouseTcpClient y migrar cada operación a su equivalente para TCP.
Métodos equivalentes
Por ejemplo, un bucle de lectura con el Client HTTP:
Opciones y parámetros
Las clases HTTPQueryOptions y ClickHouseParameterCollection no son intercambiables con sus equivalentes
para TCP. Mueva los valores a ClickHouseTcpQueryOptions, donde los ajustes se expresan como cadenas y
los parámetros forman parte del objeto de opciones:
{name:Type}, pero no reescribe
los marcadores de posición @name al estilo de ADO.NET. Tampoco admite, por consulta, base de datos, rol, token Bearer, encabezado
personalizado, resolvedor de parámetros o formateador, ni convertidor de lectura. Consulte limitaciones para conocer las
funcionalidades que siguen estando disponibles solo a través de HTTP.
Duración de la conexión y de los resultados
Ambos Clients de alto nivel son seguros para subprocesos y deben reutilizarse. El Client TCP gestiona conexiones nativas persistentes en lugar de conexiones HTTP, implementaIAsyncDisposable y, por lo general, debe
liberarse de forma asíncrona al cerrarse la aplicación.
Las filas de QueryAsync pertenecen al llamador. Los bloques de StreamAsync y sus columnas son prestados y solo son válidos
durante la iteración actual; copie los valores que deban conservarse más allá de ella. Finalice o libere siempre una
enumeración para que su conexión vuelva al grupo. Use OpenSessionAsync cuando varias operaciones
deban ejecutarse en la misma conexión y conservar el estado de la sesión.
Consulte el
ejemplo completo de migración de HTTP a TCP,
en el que se usan ambos Clients sobre la misma tabla.
Configuración
Hay dos formas de configurar un Client TCP nativo:- Cadena de conexión: pares clave/valor separados por punto y coma que especifican el endpoint del servidor, las credenciales de autenticación y otras opciones de conexión.
- Objeto
ClickHouseTcpClientOptions: un objeto de configuración inmutable y fuertemente tipado que se define en el código.
ClickHouseTcpClient. Utilice
ClickHouseTcpConnectionStringBuilder para analizar o generar una cadena de conexión y convertirla en
ClickHouseTcpClientOptions.
Configuración de la conexión
Los valores de las propiedadesTimeSpan en la cadena de conexión se expresan en segundos.
Formato de datos y serialización
Agrupación de conexiones
Cada conexión ejecuta una sola operación a la vez. El grupo permite ejecutar operaciones simultáneamente y reutilizar las conexiones entre ellas.Seguridad
El protocolo nativo seguro es un endpoint independiente del servidor, no una actualización dentro de la misma conexión. Un Client
TLS debe conectarse a un puerto nativo seguro; nunca recurre a una conexión sin cifrar.
ConfigureTls se
aplica en último lugar y puede sobrescribir la validación del certificado y del nombre del host, así que revise con atención los callbacks
personalizados.
Registro y depuración
El logger del Client registra los eventos del ciclo de vida y de las operaciones del lado del Client. En cambio, los paquetes de log del servidor se envían
a
ClickHouseTcpQueryCallbacks.OnLog. El texto de las sentencias puede contener datos sensibles, por lo que, de forma predeterminada,
se excluye de las etiquetas de actividad y se trunca considerablemente en los logs de depuración.
Ajustes personalizados
ClickHouseTcpClientOptions.CustomSettings aplica ajustes del servidor de ClickHouse a todas las consultas y
operaciones de inserción. Los valores de ClickHouseTcpQueryOptions.Settings definidos para cada operación prevalecen sobre los valores del
Client con el mismo nombre.
set_ a cada configuración del servidor:
set_ al añadir una configuración a CustomSettings o a los Settings
de cada operación.
ClickHouseTcpQueryOptions
ClickHouseTcpQueryOptions permite configurar cada operación por separado. Todas las propiedades son opcionales.
ClickHouseTcpInsertOptions
ClickHouseTcpInsertOptions extiende ClickHouseTcpQueryOptions con opciones de configuración para inserciones de bloques nativos. También están disponibles todas las propiedades de las opciones de consulta.
ClickHouseTcpClient
ClickHouseTcpClient es la API de alto nivel para el protocolo TCP nativo. Ejecuta sentencias y
consultas escalares, transmite los resultados como bloques columnares, filas u objetos POCO, inserta datos columnares o datos organizados en filas
y abre sesiones fijadas a una conexión.
El Client es seguro para subprocesos y mantiene un grupo de conexiones. Cree un Client por cada punto de conexión, compártalo
en toda la aplicación y libere sus recursos al cerrarla. Pueden ejecutarse operaciones simultáneas hasta el límite de
MaxPoolSize; las demás esperan hasta PoolTimeout para obtener una conexión.
Creación de un Client
Cree un Client mediante una cadena de conexión oClickHouseTcpClientOptions. Consulte
Configuración para ver las opciones disponibles.
Con una cadena de conexión:
PoolTimeout a que terminen las operaciones activas antes de cancelarlas.
Inyección de dependencias
AddClickHouseTcpDataSource registra una única instancia de origen de datos y expone su Client compartido como
IClickHouseTcpClient e IClickHouseTcpOperations:
LoggerFactory,
el registro utiliza el ILoggerFactory del contenedor. Con un serviceKey se pueden registrar varios
orígenes de datos independientes.
Ejecutar consultas
UseExecuteAsync para las sentencias que no devuelven filas, como las sentencias DDL y las mutaciones:
ExecuteAsync las lee y las descarta. Para
INSERT INTO ... VALUES, utilice InsertAsync o InsertRowsAsync y termine la sentencia SQL en
VALUES, sin incluir valores en línea.
Lectura de datos
Elija la API de lectura según el formato de datos que necesite la aplicación:Lecturas escalares
ExecuteScalarAsync devuelve la primera columna de la primera fila como object:
NULL como si la consulta
no devuelve ninguna fila, el resultado es null.
Lectura por filas
QueryAsync transmite cada fila como un object[] independiente, con los valores ordenados según las columnas del resultado:
Lectura de datos en objetos POCO
QueryAsync<T> asigna las columnas a propiedades públicas con un método de asignación. La correspondencia entre nombres no distingue mayúsculas de minúsculas ni tiene en cuenta los
guiones bajos; usa ClickHouseTcpColumn para especificar un nombre y ClickHouseTcpNotMapped para
excluir una propiedad.
Lectura de bloques columnares
StreamAsync expone el resultado columnar nativo como una secuencia de valores Block. Es la forma más rápida de leer datos.
Complete siempre la enumeración o libere el enumerador para que su conexión vuelva al grupo.
Block.Column<T> permite acceder al tipo CLR que produce el decodificador. Utilice Block.ReadAs<T> o una interfaz especializada como IDateTimeColumn cuando sea necesario realizar una conversión.
Inserción de datos
Las inserciones nativas envían los datos en bloques columnares en formato wire. La sentencia SQL debe serINSERT INTO ... VALUES
sin una lista de valores en la propia sentencia. Use columnas con tipos definidos para reducir al mínimo el procesamiento en el cliente, o las sobrecargas para filas y
POCO si la aplicación ya dispone de datos organizados por filas.
Inserciones columnares
InsertAsync acepta datos ya agrupados en columnas con tipos definidos. Es la forma más rápida de insertar datos.
InsertAsync, siempre que la
inserción finalice antes de que se libere ese bloque.
Inserción de filas
InsertRowsAsync acepta filas de tipo object[]. Los valores se asignan a las columnas de la lista SQL según su posición:
Variant o Dynamic. No modifique las filas hasta que termine la operación.
Inserciones con objetos POCO
La sobrecarga genéricaInsertRowsAsync<T> asocia las columnas de destino con propiedades públicas de lectura según
las mismas reglas de nomenclatura y atributos que se aplican al leer objetos POCO:
ClickHouseTcpNotMapped evita que las propiedades de uso exclusivo de la aplicación, como
ImportBatch, se incluyan en la correspondencia.
Parámetros SQL
El Client nativo asocia los valores con los marcadores de posición{name:Type} propios de ClickHouse. No reescribe
los marcadores de posición @name de ADO.NET.
ClickHouseTcpParameter.ClickHouseType. Utilice el tipo Identifier para los nombres de tablas y columnas.
Si un DateTime o DateTimeOffset representa un instante concreto, incluya una zona horaria como
{timestamp:DateTime('UTC')}; de lo contrario, la zona horaria de la sesión del servidor podría cambiar su significado.
ID de consulta
Cada operación tiene un ID de consulta que utilizan las tablas del sistema de ClickHouse, los logs del Client y los spans de traza. SiQueryId es nulo o está vacío, el Client genera un nuevo GUID. Establezca su valor cuando sea necesario
correlacionar la operación con un identificador de la aplicación:
Progreso de la consulta y metadata
ConfigureClickHouseTcpQueryOptions.Callbacks para recibir metadata intercalada con la respuesta:
OnLog, OnProfileEvents, OnTotals y OnExtremes son prestados y no deben utilizarse fuera de la
función de callback.
ClickHouse no envía paquetes de progreso de la consulta para las filas cargadas mediante una inserción. Use
OnBlockWritten para observar los bloques enviados por el Client; esta función informa del progreso de la transmisión, pero no confirma que el
servidor haya completado el commit de la inserción.
Cancelación
Todas las operaciones aceptan unCancellationToken:
Información del servidor y comprobaciones de estado
GetServerInfoAsync devuelve la identity del servidor, su versión, la zona horaria y la información del protocolo negociado
durante el handshake nativo:
ProtocolRevision, la revisión negociada entre el Client y
el servidor. Habilite las funcionalidades de SQL, como los tipos de datos y las funciones, según Version. El método reutiliza una
conexión si hay alguna disponible y abre una nueva cuando el grupo está vacío.
Use PingAsync para comprobar si el servicio está listo mediante el protocolo nativo:
Más ejemplos
Para consultar ejemplos completos y ejecutables sobre lectura e inserción de datos, tipos, sesiones, TLS, observabilidad y gestión de errores, consulte los ejemplos de TCP nativo en el repositorio de GitHub.Sesiones
Las operaciones habituales del Client utilizan cualquier conexión disponible del grupo, por lo que el estado asociado a una conexión no queda aislado ni se garantiza que persista entre llamadas. Las conexiones del grupo pueden estar vinculadas a distintos servidores. Abra una sesión cuando las tablas temporales, las sentenciasSET u otra secuencia de operaciones deban utilizar la misma conexión.
IClickHouseTcpSession ofrece las mismas API de consulta, ejecución, inserción, ping e información del servidor
que el Client. La sesión no es segura para su uso simultáneo desde varios threads. Las operaciones deben ejecutarse de forma secuencial: si se inicia otra antes de que termine la actual, se rechaza. Un resultado transmitido progresivamente mantiene ocupada la sesión hasta que se recorren todos sus elementos o se libera su
enumerador.
Cada sesión ocupa un slot de MaxPoolSize durante toda su duración. El Client puede seguir utilizando otras
conexiones del grupo, pero, si el grupo solo tiene una conexión, las demás operaciones del Client deben esperar
hasta que se libere la sesión o venza PoolTimeout.
Libere la sesión antes de liberar su Client padre. Al hacerlo, la
conexión reservada se cierra en lugar de devolverse al grupo. Así se evita que los llamadores posteriores hereden sus
tablas temporales o su configuración. Un fallo de conexión o de protocolo, una cancelación o un
flujo de resultados incompleto pueden dejar la sesión inutilizable; cuando IsOpen pase a ser false, abra una sesión nueva.
Buenas prácticas
Duración del Client y agrupación de conexiones
Cree unClickHouseTcpClient o ClickHouseTcpDataSource para cada combinación de endpoint y configuración, y reutilícelo durante toda la vida de la aplicación. El Client es seguro para subprocesos y gestiona su propio grupo de conexiones; crear uno por operación genera un grupo nuevo cada vez e impide reutilizar las conexiones.
En una aplicación con inyección de dependencias, registre AddClickHouseTcpDataSource una sola vez e inyecte IClickHouseTcpClient. El proveedor de servicios es propietario del Client, por lo que quienes usen la instancia inyectada no deben liberarla. Fuera de la inyección de dependencias, libere el Client al detener la aplicación mediante await using.
Cada conexión nativa procesa una sola operación a la vez. Por tanto, MaxPoolSize limita tanto las conexiones abiertas como las operaciones simultáneas; los llamadores adicionales esperan a que quede un cupo libre durante un máximo de PoolTimeout. Elija un valor que permita atender la concurrencia real de la aplicación sin superar los límites de conexiones y consultas del lado del servidor. Aumentarlo no acelera las consultas individuales.
Tenga en cuenta qué operaciones ocupan conexiones del grupo:
- Un resultado transmitido progresivamente mantiene ocupada su conexión hasta que se libera su enumerador.
- Una sesión mantiene ocupada una conexión durante toda su duración y solo admite una operación a la vez.
- Si se abandona un resultado, se cancela una operación en curso o falla el protocolo o la conexión, esta se cierra en lugar de reutilizarse.
ClickHouse.Driver.Tcp.Pool para diagnosticar el agotamiento del grupo, el descarte inesperado de conexiones o los nuevos intentos de conexión frecuentes.
Tiempos de espera y cancelación
El cliente TCP establece límites distintos para cada tipo de espera:
Si para obtener una conexión primero hay que esperar a que haya un espacio libre en el grupo y después abrir
una conexión nueva, el proceso puede tardar hasta
PoolTimeout + DialTimeout. ReadTimeout se reinicia con cada lectura del transporte, por lo que una consulta larga que
sigue enviando información de progreso o datos puede durar más que ese valor. Configure un valor lo bastante alto para permitir
períodos normales de inactividad del servidor; use TimeSpan.Zero solo si otro tiempo de espera limita de forma fiable
la operación.
Use un token de cancelación cuando necesite un tiempo de espera para toda la operación:
Manejo de fechas y horas
PrefieraDateTime('UTC') o DateTime64(S, 'UTC') para las marcas de tiempo y use DateTimeOffset o un
DateTime cuyo Kind sea Utc en el código de la aplicación. Así queda claro qué instante se representa
y se evita depender de la zona horaria del servidor o de la sesión.
El Client TCP aplica estas reglas al escribir valores DateTime:
Se rechaza una hora no especificada que no existe debido al cambio al horario de verano, ya que no corresponde a ningún
instante. Si una hora es ambigua durante el cambio al horario de invierno, se elige la primera aparición. Use
DateTimeOffset cuando
sea necesario indicar explícitamente cuál de las dos corresponde.
Para los parámetros SQL que representan un instante, incluya la zona horaria en el marcador de posición:
DateTime y DateTime64 exponen de forma predeterminada sus recuentos sin procesar como uint o long.
Use Block.ReadAs<DateTimeOffset>, IDateTimeColumn.GetDateTimeOffset o una propiedad POCO del tipo correspondiente
si le resulta más cómodo trabajar con un valor de fecha y hora. Conserve el recuento sin procesar cuando cada dígito sea importante:
DateTimeOffset tiene una resolución de 100 nanosegundos, por lo que leer DateTime64 con una escala de 8 o 9 mediante este tipo
hace que se pierda la precisión inferior a un tick.
Use DateOnly para Date y Date32. Use TimeSpan para los valores Time y Time64 que puedan ser
negativos o superar las 24 horas; TimeOnly solo es adecuado cuando la columna se limita a una
hora del día.
Procesamiento en streaming y duración de los resultados
UseStreamAsync y columnas tipadas para procesar datos con un caudal elevado. Esto se ajusta a la
disposición columnar de ClickHouse y evita los arrays por fila, el boxing y las asignaciones de memoria para objetos POCO. Use QueryAsync<T> cuando
sea más importante disponer de un modelo de aplicación propio que minimizar las asignaciones, y use la versión sin tipos de
QueryAsync solo cuando el esquema no se conozca en tiempo de compilación.
Los bloques devueltos por StreamAsync son prestados. El bloque, sus columnas, las columnas hijas de estructuras compuestas y
todos los spans solo son válidos durante la iteración actual del bucle. Procéselos directamente o copie los valores que
deban seguir disponibles después de esa iteración:
await foreach libere el enumerador. Si solo necesita una parte del
resultado, especifíquelo en SQL con LIMIT y seleccione únicamente las columnas necesarias. Salir de
la iteración antes de tiempo cancela el resto de la respuesta e impide reutilizar esa conexión.
Estructura de las inserciones y procesamiento por lotes
PrefieraInsertAsync con columnas de tipos definidos cuando los datos ya estén organizados por columnas. Es la opción que requiere menos
conversiones en el Client. InsertRowsAsync<T> es la opción natural para datos POCO; las filas object[] sin tipos definidos
ofrecen más flexibilidad, pero requieren asignar arrays y convertir los tipos de valor en objetos.
Envíe una cantidad considerable de filas en cada llamada de inserción, en lugar de realizar muchas inserciones pequeñas. En cada
llamada, MaxRowsPerBlock divide los datos en bloques wire nativos. Su valor predeterminado de 50 000 filas también
limita el tamaño de los búferes temporales de columnas utilizados al convertir entradas organizadas por filas y datos POCO. Aumentarlo puede
mejorar el caudal cuando las filas tienen pocas columnas, pero incrementa el consumo máximo de memoria; establecerlo en null escribe toda la
inserción en un solo bloque y convierte a la vez todas las entradas organizadas por filas de ese bloque.
MaxSendBufferBytes limita por separado la cantidad de datos codificados que se almacenan en el búfer antes de su vaciado al
socket. Es un límite flexible que se comprueba entre columnas, por lo que una sola columna ancha puede superarlo.
Las entradas organizadas por filas y los datos POCO se convierten bloque a bloque. Por ello, un valor incorrecto en un bloque posterior puede
detectarse cuando ya se han enviado los bloques anteriores. Valide la admisibilidad de valores nulos y los tipos CLR antes de la
inserción si no tiene certeza de la calidad de los datos, y establezca un DeduplicationToken derivado de los datos siempre que
pueda reintentarse el lote lógico.
Tipos de datos compatibles
Las tablas siguientes distinguen entre el tipo que devuelveIColumn<T> tras la decodificación y los tipos adicionales
disponibles mediante la conversión con Block.ReadAs<T>, la correspondencia con POCO de QueryAsync<T> o las inserciones. Puede consultar al mismo
resolvedor que utilizan esas operaciones si admite una correspondencia concreta:
Nullable, Array, Tuple, Map y LowCardinality se aplican de forma recursiva a sus
tipos internos.
Correspondencia de tipos: lectura de ClickHouse
Default .NET type es el tipo T que exponen Block.Column<T> e IColumn<T>. Los tipos de la
columna Also readable as se pueden leer mediante Block.ReadAs<T> y las propiedades de los objetos POCO.
Tipos de enteros
Tipos de coma flotante
Tipos decimales
ClickHouseTcpDecimal almacena una mantisa entera de tamaño arbitrario y una escala, lo que permite conservar valores
cuya precisión supera la capacidad de decimal.
Tipo booleano
Tipos String
Use
IStringColumn.GetBytes(row) o lea los datos como byte[] si es posible que no sean UTF-8 válido.
FixedString(N) conserva los N bytes, incluidos los bytes nulos finales.
Tipos de fecha y hora
La representación como entero sin procesar es la predeterminada para que las lecturas columnares conserven el valor exacto en formato wire. Las
conversiones a fecha y hora usan la zona horaria declarada por el tipo o, si este no declara ninguna, la zona horaria
de la sesión. Leer
Time o Time64 como TimeOnly genera una excepción si el valor es negativo o es igual o superior
a 24 horas; use TimeSpan para abarcar todo el rango de ClickHouse.
Tipos enumerados
IEnumColumn también expone la correspondencia declarada entre las etiquetas y sus valores ordinales.
Otros tipos escalares
Tipos compuestos
Las tuplas pueden contener hasta siete elementos. Una columna
Nested admite cualquier aridad y conviene leerla
mediante INestedColumn, que permite acceder a sus columnas de campos planos con nombre y a los desplazamientos de fila compartidos sin
tener que crear registros empaquetados como objetos. Con la configuración predeterminada de ClickHouse, flatten_nested = 1, los campos anidados llegan como
columnas Array(T) independientes cuyos nombres contienen puntos.
Tipos Variant, Dynamic y JSON
Variant y Dynamic devuelven el valor CLR del tipo seleccionado en cada fila, o null. Sus
vistas columnares exponen el flujo de discriminadores y una columna secundaria tipada por cada tipo en tiempo de ejecución, lo que evita
el empaquetado al procesar los datos por columnas.
El client TCP lee JSON mediante la serialización de ClickHouse para String. El client activa
output_format_native_write_json_as_string = 1 de forma predeterminada; si se desactiva esta configuración, no se admiten las lecturas de JSON.
ClickHouse analiza y normaliza JSON, por lo que el texto devuelto puede diferir del texto insertado en el orden de las claves,
los espacios en blanco y el formato de los números.
Tipos geométricos
Geometry se expone como una IVariantColumn que admite los seis tipos geométricos.
Tipo QBit
El client TCP admite la variante
QBit(T, N) de dos argumentos, sin stride. La disposición de tres argumentos
con stride no es compatible.
Tipos AggregateFunction
Una columna
AggregateFunction contiene un estado intermedio específico de la función. Obtenga el resultado final en el
servidor, por ejemplo, con sumMerge(column), y lea el valor resultante.
Correspondencia de tipos: escritura en ClickHouse
Cada entrada indica el tipo CLR de una fila de la columnaIColumn pasada a InsertAsync. Estas correspondencias son
exactas: el client TCP no realiza conversiones implícitas como las de Convert.
Tipos de enteros
Tipos de coma flotante
Al escribir valores
BFloat16, cada valor float se trunca a la representación de coma flotante de 16 bits conocida como «brain floating point».
Tipos decimales
La operación de escritura lanza una
OverflowException si la mantisa escalada supera la precisión declarada.
Tipo booleano
Tipos String
FixedString(N) no admite string por diseño; codifique el valor y añádale el relleno necesario de forma explícita para que su
representación binaria exacta no dé lugar a ambigüedades.
Tipos de fecha y hora
Los valores enteros sin procesar usan las unidades indicadas en la tabla de lectura.
DateTimeOffset conserva el instante de tiempo.
DateTime tiene en cuenta su Kind; un valor Unspecified se interpreta como la hora del reloj en la
zona horaria de la columna o, si esta no especifica ninguna, en la zona horaria de la sesión.
Tipos enumerados
Las etiquetas desconocidas se rechazan antes de enviar los datos.
Otros tipos escalares
Tipos compuestos
La estructura aceptada se define de forma recursiva:Array(Nullable(DateTime)) acepta un DateTime?[] por
fila y Map(String, UInt32) acepta un KeyValuePair<string, uint>[].
La escritura directa de
Nested utiliza la estructura de columnas densas devuelta por una lectura anterior. Para las inserciones
generadas por la aplicación, mantenga la representación predeterminada flatten_nested = 1 y escriba cada campo
Array(T) cuyo nombre contenga un punto como una columna independiente.
Tipos Variant, Dynamic y JSON
Para
Variant, el tipo en tiempo de ejecución debe corresponderse de forma unívoca con el tipo CLR predeterminado de una de las alternativas. Las
correspondencias de tipos por conveniencia, como escribir un DateTime en una alternativa DateTime, no se aplican dentro de una variante;
utilice en su lugar el tipo sin procesar predeterminado de la alternativa. Dynamic admite valores escalares, así como valores de
arrays, mapas y tuplas admitidos de forma recursiva.
Tipos geométricos
En una columna
Geometry creada por la aplicación, solo Point y MultiPolygon tienen estructuras CLR exclusivas.
Ring y LineString comparten la misma estructura, al igual que Polygon y MultiLineString, por lo que el client no puede
inferir qué alternativa representa un valor object. Una columna Geometry decodificada conserva sus
discriminadores y puede volver a insertarse sin esa ambigüedad.
Tipo QBit
Tipos AggregateFunction
Compresión
El client activa la compresión de forma predeterminada y usa LZ4 para los bloques que escribe; ClickHouse también usa LZ4 de forma predeterminada para los bloques de respuesta. La compresión se aplica a los bloques de resultados y a los bloques enviados mediante una inserción, mientras que el texto de la consulta, la información de progreso, las excepciones y los demás paquetes del protocolo mantienen su codificación wire habitual. Utilice la claveCompression de la cadena de conexión para elegir el códec que usa el client:
IClickHouseCompressor:
Compressor = null para desactivar la compresión. Un compresor personalizado debe admitir la delimitación de bloques del protocolo nativo;
los compresores que solo admiten cuerpos de solicitudes y respuestas HTTP se rechazan al crear el client.
Selección del códec de respuesta
Compressor determina cómo se comprimen los bloques que escribe el client. El paquete de consulta nativo solicita
compresión al servidor, pero no especifica un códec. Por eso, ClickHouse selecciona el códec de respuesta según
el ajuste network_compression_method. El códec predeterminado del servidor es LZ4.
Configure el códec de respuesta para cada operación cuando sea necesario:
Gestión de errores
Los fallos notificados por ClickHouse o por la conexión nativa derivan deClickHouseTcpException,
que, a su vez, deriva de DbException:
ClickHouseTcpServerException expone tanto RawCode, el código numérico exacto enviado por el servidor,
como Code, el ClickHouseErrorCode correspondiente si el driver tiene un nombre para ese código. También incluye el
Name de la excepción del servidor, ServerStackTrace y las excepciones anidadas del servidor, si las hay, a través de
InnerException.
ClickHouseErrorCode tienen Code == ClickHouseErrorCode.Unknown; consulte
RawCode sin dar por hecho que la enumeración incluye todos los errores de ClickHouse.
Los errores de validación de argumentos y del ciclo de vida de los objetos mantienen sus tipos de excepción habituales de .NET.
La cancelación lanza OperationCanceledException. DialTimeout y ReadTimeout lanzan
ClickHouseTcpConnectionException con una excepción interna TimeoutException, y la conexión se descarta.
PoolTimeout lanza un TimeoutException simple, que no es un ClickHouseTcpException: no ha fallado ninguna conexión,
y la solución es reducir las operaciones simultáneas, ampliar el grupo o terminar de enumerar los resultados.
Reintento de operaciones
Si falla la conexión o se agota el tiempo de espera durante una inserción, no se sabe si la operación se completó: el servidor podría haber confirmado las filas antes de que el client dejara de recibir la respuesta. Asigne unDeduplicationToken estable al lote lógico antes de reintentar la operación:
Registro y diagnóstico
El client TCP se integra conMicrosoft.Extensions.Logging. El registro es opcional; si no se configura
LoggerFactory, el cliente no crea registradores ni da formato a los mensajes de registro.
ILoggerFactory del contenedor, salvo que ya se haya especificado una en las opciones proporcionadas.
Categorías de registro
Configure las categorías mediante la configuración estándar de registro de .NET:
Debug e incluye, como máximo, StatementMaxLength caracteres de
SQL. El valor predeterminado es de cinco caracteres. Establezca el valor en cero o menos para que el texto de la sentencia no aparezca en los logs,
o auméntelo solo después de tener en cuenta los parámetros y literales que puedan contener datos confidenciales.
Mensajes del log del servidor
La integración de logging registra el comportamiento del cliente. Los paquetes del registro de consultas de ClickHouse son independientes y se envían aClickHouseTcpQueryCallbacks.OnLog. Para habilitarlos, configure el
parámetro del servidor send_logs_level:
OpenTelemetry
El cliente TCP emite spans de trazas distribuidas a través de la APISystem.Diagnostics.Activity de .NET.
Suscríbase a la fuente de actividades TCP mediante un proveedor de trazas de OpenTelemetry:
ClickHouse.Driver.Tcp, distinto del de la fuente del cliente HTTP, por lo que
se pueden recopilar datos de cada transporte por separado. Si no hay ningún listener suscrito, las operaciones no
crean actividades.
Spans y atributos
El client emite spans para las operaciones SQL, los pings y las conexiones nuevas. Los spans SQL toman el nombre de la palabra clave con la que comienza la sentencia, comoSELECT o INSERT; si no se reconoce una palabra clave inicial, se usa query. Un span connect abarca la conexión mediante socket, la negociación TLS y el handshake nativo. Los spans de sentencias también incluyen el tiempo de espera hasta obtener una conexión del pool.
Los contadores solo están presentes cuando el servidor o el client disponen de un valor significativo que comunicar. Por ejemplo, una inserción que carga bloques indica las filas enviadas por el client, pero no recibe contadores de lectura del servidor. Los spans fallidos también contienen un evento
exception con el tipo de excepción, el mensaje y la traza de pila.
Texto SQL y datos sensibles
De forma predeterminada, los spans no incluyen el texto SQL. Habilite su inclusión de forma explícita y establezca un límite adecuado:StatementMaxLength limita la longitud del atributo db.query.text y del texto SQL en los logs de depuración. Un valor de cero
o menos hace que el texto SQL se omita en ambos casos. Revise también los mensajes de excepción y las trazas de pila exportados, ya que
los errores del servidor pueden incluir detalles de las consultas.
Propagación del contexto de traza
CuandoActivity.Current usa el formato de ID del W3C, el client incluye el ID de traza, el ID de span, los indicadores de traza
y el estado de la traza en el paquete de consulta nativo. ClickHouse puede así crear spans de servidor dentro de la misma
traza distribuida. La recopilación y el muestreo de spans del lado del servidor se configuran en ClickHouse; por
ejemplo, la probabilidad de muestreo se puede establecer para cada consulta:
system.query_log y, si está configurado, con system.opentelemetry_span_log de ClickHouse.
Limitaciones
El client TCP es experimental y no ofrece todas las funciones del client HTTP.Funcionalidades disponibles solo por HTTP
La API TCP no es un proveedor de ADO.NET y no puede utilizarse con ORM. Tampoco admite la entrada ni la salida en CSV, JSONEachRow, Parquet o flujos sin procesar; la autenticación bearer ni los encabezados HTTP personalizados; la resolución personalizada de tipos de parámetros, el formateo o la conversión de lectura; ni la especificación de una base de datos o un rol por consulta. Use el cliente HTTP si una aplicación necesita alguna de estas funcionalidades.Parámetros SQL
Solo se admiten los marcadores de posición{name:Type} propios de ClickHouse; el cliente TCP no transforma
los marcadores de posición @name de ADO.NET. En las versiones de ClickHouse de la 25.8 a la 26.6, los nombres de parámetros que coincidan con
opciones de configuración del servidor, como limit u offset, pueden interpretarse como tales y rechazarse. Si necesita compatibilidad
con esas versiones, cámbieles el nombre, por ejemplo, a row_limit.
Cobertura de tipos de datos
La sección tipos de datos compatibles detalla todas las correspondencias. El códec nativo actual presenta estas limitaciones principales:- Las tuplas pueden contener como máximo siete elementos.
- Los estados intermedios de
AggregateFunction(function, ...)no son compatibles. Finalícelos en el servidor, por ejemplo consumMerge(column), y lea el resultado. - Solo se admite la disposición
QBit(T, N)de dos argumentos y sin partición por stride. JSONutiliza la serialización String de ClickHouse y requiereoutput_format_native_write_json_as_string = 1, que el cliente solicita de forma predeterminada.- Las inserciones generadas por la aplicación no tienen una representación orientada a filas para
Nested(...)cuandoflatten_nested = 0. Utilice en su lugar las columnasArray(T)aplanadas, con nombres separados por puntos, que se usan de forma predeterminada. - Una columna
Geometrygenerada por la aplicación no permite distinguir entre tipos que comparten la misma estructura CLR, comoRingyLineString. Inserte el tipo de geometría concreto o vuelva a insertar una columnaGeometrydecodificada que conserve sus discriminadores.
Reintentos automáticos
El client no reintenta automáticamente las operaciones fallidas. Reintente solo las operaciones que sea seguro repetir y establezca unDeduplicationToken estable antes de reintentar una inserción cuyo resultado se desconozca.
Consulte cómo reintentar operaciones para obtener más información.