Skip to main content
O cliente JS oficial para se conectar ao ClickHouse. O cliente é escrito em TypeScript e fornece tipagens para a API pública do cliente. Ele tem zero dependências, é otimizado para desempenho máximo e foi testado com várias versões e configurações do ClickHouse (single node on-premise, cluster on-premise e ClickHouse Cloud). Há duas versões diferentes do cliente disponíveis para ambientes distintos:
  • @clickhouse/client - apenas Node.js
  • @clickhouse/client-web - navegadores (Chrome/Firefox), Cloudflare workers
Ao usar TypeScript, certifique-se de que a versão seja pelo menos a 4.5, que habilita a sintaxe inline de import e export. O código-fonte do cliente está disponível no repositório GitHub ClickHouse-JS.
Skills para agentes de IAO cliente JS vem com Skills para agentes de IA que podem ajudar agentes de codificação a trabalhar com o cliente. Instale-as com:

Requisitos do ambiente (node.js)

O Node.js deve estar disponível no ambiente para executar o cliente. O cliente é compatível com todos os lançamentos do Node.js atualmente mantidos. Assim que uma versão do Node.js se aproxima do fim de vida, o cliente deixa de oferecer suporte a ela, por ser considerada desatualizada e insegura. Versões atuais do Node.js com suporte:

Requisitos de ambiente (web)

A versão web do cliente é oficialmente testada nas versões mais recentes dos navegadores Chrome/Firefox e pode ser usada como dependência, por exemplo, em aplicações React/Vue/Angular ou em Cloudflare workers.

Instalação

Para instalar a versão estável mais recente do cliente Node.js, execute:
Instalação da versão web:

Compatibilidade com ClickHouse

É provável que o cliente também funcione com versões mais antigas; no entanto, esse suporte é oferecido em regime de melhor esforço e não é garantido. Se você estiver usando uma versão do ClickHouse anterior à versão 23.3, consulte a política de segurança do ClickHouse e considere atualizá-la.

Exemplos

Nosso objetivo é abranger vários cenários de uso do client com os exemplos no repositório do client. A visão geral está disponível no README dos exemplos. Se algo não estiver claro ou estiver faltando nos exemplos ou na documentação a seguir, sinta-se à vontade para entrar em contato conosco.

API do cliente

A maioria dos exemplos deve ser compatível com as versões para Node.js e web do cliente, a menos que seja explicitamente indicado o contrário.

Criando uma instância de cliente

Você pode criar quantas instâncias de cliente forem necessárias com a função de fábrica createClient:
Se o seu ambiente não oferecer suporte a módulos ESM, você pode usar a sintaxe CJS em vez disso:
Uma instância de cliente pode ser pré-configurada ao ser instanciada.

Configuração

Ao criar uma instância do cliente, as seguintes configurações de conexão podem ser ajustadas:

Parâmetros de configuração específicos do Node.js

Configuração de URL

A configuração de URL sempre substituirá os valores definidos no código, e um aviso será registrado no log nesse caso.
É possível configurar a maioria dos parâmetros da instância do cliente com uma URL. O formato da URL é http[s]://[username:password@]hostname:port[/database][?param1=value1&param2=value2]. Em quase todos os casos, o nome de um determinado parâmetro reflete seu caminho na interface de opções de configuração, com algumas exceções. Os seguintes parâmetros são suportados:
  • (1) Para booleanos, os valores válidos são true/1 e false/0.
  • (2) Qualquer parâmetro com o prefixo clickhouse_setting_ ou ch_ terá esse prefixo removido, e o restante será adicionado a clickhouse_settings do cliente. Por exemplo, ?ch_async_insert=1&ch_wait_for_async_insert=1 será o mesmo que:
Nota: os valores booleanos de clickhouse_settings devem ser passados como 1/0 na URL.
  • (3) Semelhante ao item (2), mas para a configuração de http_header. Por exemplo, ?http_header_x-clickhouse-auth=foobar será equivalente a:

Conexão

Reúna os detalhes da conexão

Para se conectar ao ClickHouse via HTTP(S), você precisa das seguintes informações: Os detalhes do seu serviço do ClickHouse Cloud estão disponíveis no console do ClickHouse Cloud. Selecione um serviço e clique em Connect:
botão Connect do serviço do ClickHouse Cloud
Escolha HTTPS. Os detalhes de conexão são exibidos em um comando curl de exemplo.
detalhes de conexão HTTPS do ClickHouse Cloud
Se você estiver usando ClickHouse autogerenciado, os detalhes de conexão são definidos pelo administrador do seu ClickHouse.

Visão geral da conexão

O client estabelece uma conexão via protocolo HTTP ou HTTPS. O suporte a RowBinary está em andamento; veja a issue relacionada. O exemplo a seguir mostra como configurar uma conexão com o ClickHouse Cloud. Ele pressupõe que os valores de url (incluindo protocolo e porta) e password sejam especificados por meio de variáveis de ambiente, e que o usuário default seja usado. Exemplo: Criando uma instância de Client para Node.js usando variáveis de ambiente na configuração.
O repositório da biblioteca cliente contém vários exemplos que usam variáveis de ambiente, como criar uma tabela no ClickHouse Cloud, usar inserts assíncronos e vários outros.

Pool de conexões (somente Node.js)

Para evitar a sobrecarga de estabelecer uma conexão a cada requisição, o cliente cria um pool de conexões com o ClickHouse para reutilizá-las, usando um mecanismo de Keep-Alive. Por padrão, o Keep-Alive é habilitado, e o tamanho do pool de conexões é definido como 10, mas você pode alterá-lo com a opção de configuração max_open_connections. Não há garantia de que a mesma conexão do pool será usada nas consultas seguintes, a menos que o usuário defina max_open_connections: 1. Isso raramente é necessário, mas pode ser exigido em casos em que os usuários estejam usando tabelas temporárias. Veja também: configuração de Keep-Alive.

ID da consulta

Todo método que envia uma consulta ou uma instrução (command, exec, insert, select) fornecerá query_id no resultado. Esse identificador único é atribuído pelo client a cada consulta e pode ser útil para buscar os dados em system.query_log, se ele estiver habilitado na configuração do servidor, ou para cancelar consultas de longa duração (veja o exemplo). Se necessário, o query_id pode ser substituído pelo usuário nos parâmetros dos métodos command/query/exec/insert.
Se você substituir o parâmetro query_id, precisará garantir que ele seja único em cada chamada. Um UUID aleatório é uma boa escolha.

Base parameters for all client methods

Há vários parâmetros que se aplicam a todos os métodos do cliente (query/command/insert/exec).

Método de consulta

Ele é usado para a maioria das instruções que podem ter uma resposta, como SELECT, ou para enviar DDLs, como CREATE TABLE, e deve ser aguardado. Espera-se que o conjunto de resultados retornado seja consumido pela aplicação.
Há um método específico, insert, para inserção de dados, e command, para DDLs.
Veja também: Base parameters for all client methods.
Não especifique a cláusula FORMAT em query; use o parâmetro format.

Abstrações de conjunto de resultados e de linhas

ResultSet fornece vários métodos práticos para o processamento de dados na sua aplicação. A implementação de ResultSet no Node.js usa Stream.Readable internamente, enquanto a versão web usa a Web API ReadableStream. Você pode consumir o ResultSet chamando os métodos text ou json em ResultSet e carregar na memória todo o conjunto de linhas retornado pela consulta. Você deve começar a consumir o ResultSet o quanto antes, pois ele mantém o fluxo de resposta aberto e, consequentemente, a conexão subjacente ocupada. O cliente não armazena em buffer os dados recebidos para evitar um uso de memória potencialmente excessivo pela aplicação. Como alternativa, se ele for grande demais para caber na memória de uma só vez, você pode chamar o método stream e processar os dados em modo de streaming. Nesse caso, cada fragmento da resposta será transformado em arrays relativamente pequenos de linhas (o tamanho desse array depende do tamanho de um fragmento específico que o cliente recebe do servidor, já que isso pode variar, e do tamanho de cada linha), um fragmento por vez. Consulte a lista de formatos de dados compatíveis para determinar qual é o melhor formato para streaming no seu caso. Por exemplo, se você quiser fazer streaming de objetos JSON, poderá escolher JSONEachRow, e cada linha será convertida em um objeto JS, ou talvez o formato mais compacto JSONCompactColumns, em que cada linha será um array compacto de valores. Veja também: arquivos em streaming.
Se o ResultSet ou seu fluxo não for consumido por completo, ele será destruído após o período de inatividade de request_timeout.
Exemplo: (Node.js/Web) Uma consulta cujo conjunto de dados resultante está no formato JSONEachRow, consumindo todo o stream e interpretando o conteúdo como objetos JS. Código-fonte.
Exemplo: (somente no Node.js) Resultado de consulta em streaming no formato JSONEachRow usando a abordagem clássica on('data'). Ela pode ser usada em vez da sintaxe for await const. Código-fonte.
Exemplo: (somente no Node.js) Resultado de uma consulta em streaming no formato CSV usando a abordagem clássica on('data'). Isso pode ser usado de forma intercambiável com a sintaxe for await const. Código-fonte
Exemplo: (apenas Node.js) Resultado de uma consulta em streaming como objetos JS no formato JSONEachRow, consumido com a sintaxe for await const. Isso pode ser usado no lugar da abordagem clássica on('data'). Código-fonte.
A sintaxe for await const exige um pouco menos de código do que a abordagem on('data'), mas pode ter um impacto negativo no desempenho. Consulte esta issue no repositório do Node.js para mais detalhes.
Exemplo: (Apenas Web) Iteração sobre o ReadableStream de objetos.

Método insert

Este é o principal método de inserção de dados.
O tipo de retorno é mínimo, pois não esperamos que nenhum dado seja retornado pelo servidor e consumimos o fluxo de resposta imediatamente. Se um array vazio for fornecido ao método insert, a instrução insert não será enviada ao servidor; em vez disso, o método será resolvido imediatamente com { query_id: '...', executed: false }. Se o query_id não tiver sido fornecido nos params do método nesse caso, ele será uma string vazia no resultado, já que retornar um UUID aleatório gerado pelo client poderia ser confuso, pois a consulta com esse query_id não existirá na tabela system.query_log. Se a instrução insert tiver sido enviada ao servidor, a flag executed será true.

Método insert e streaming no Node.js

Ele pode funcionar tanto com um Stream.Readable quanto com um Array<T> simples, dependendo do formato de dados especificado para o método insert. Veja também esta seção sobre streaming de arquivos. O método insert deve ser aguardado; no entanto, é possível especificar um stream de entrada e aguardar a operação de insert mais tarde, somente quando o stream for concluído (o que também resolverá a promise do insert). Isso pode ser útil para listeners de eventos e cenários semelhantes, mas o tratamento de erros pode não ser trivial, com muitos casos-limite no lado do client. Em vez disso, considere usar inserções assíncronas, como mostrado neste exemplo.
Se você tiver uma instrução INSERT personalizada que seja difícil de modelar com este método, considere usar o método command.Você pode ver como ele é usado nos exemplos INSERT INTO … VALUES ou INSERT INTO … SELECT.
Veja também: Base parameters for all client methods.
Uma requisição cancelada com abort_signal não garante que nenhum dado tenha sido inserido, pois o servidor pode ter recebido parte dos dados transmitidos em fluxo antes do cancelamento.
Exemplo: (Node.js/Web) Insira um array de valores. Código-fonte.
Exemplo: (apenas no Node.js) Insira um stream a partir de um arquivo CSV. Código-fonte. Veja também: streaming de arquivos.
Exemplo: Exclua algumas colunas da instrução INSERT. Considere a seguinte definição de tabela:
Insira apenas uma coluna específica:
Exclua algumas colunas:
Veja o código-fonte para mais detalhes. Exemplo: Inserir em um banco de dados diferente do informado para a instância do cliente. Código-fonte.

Limitações da versão web

No momento, os inserts em @clickhouse/client-web só funcionam com os formatos Array<T> e JSON*. A inserção via streams ainda não tem suporte na versão web devido à baixa compatibilidade dos navegadores. Consequentemente, a interface InsertParams da versão web é um pouco diferente da versão para Node.js, já que values se limita apenas ao tipo ReadonlyArray<T>:
Isso pode mudar no futuro. Veja também: Base parameters for all client methods.

Método command

Pode ser usado com instruções que não geram saída, quando a cláusula FORMAT não se aplica ou quando a resposta não é necessária. Um exemplo desse tipo de instrução pode ser CREATE TABLE ou ALTER TABLE. Deve ser aguardado. O fluxo de resposta é encerrado imediatamente, o que significa que o socket subjacente é liberado.
Veja também: Base parameters for all client methods. Exemplo: (Node.js/Web) Criar uma tabela no ClickHouse Cloud. Código-fonte.
Exemplo: (Node.js/Web) Crie uma tabela em uma instância do ClickHouse auto-hospedada. Código-fonte.
Exemplo: (Node.js/Web) INSERT FROM SELECT
Uma requisição cancelada com abort_signal não garante que a instrução não tenha sido executada pelo servidor.

Método exec

Se você tiver uma consulta personalizada que não se enquadre em query/insert e quiser o resultado, poderá usar exec como alternativa a command. exec retorna um fluxo legível que DEVE ser consumido ou encerrado no lado da aplicação.
Veja também: Base parameters for all client methods. O tipo de retorno do stream é diferente nas versões Node.js e Web. Node.js:
Web:

Ping

O método ping, usado para verificar o status da conectividade, retorna true se o servidor puder ser acessado. Se o servidor estiver inacessível, o erro correspondente também será incluído no resultado.
Ping pode ser uma ferramenta útil para verificar se o servidor está disponível quando a aplicação é iniciada, especialmente com o ClickHouse Cloud, em que uma instância pode estar ociosa e voltar a ficar ativa após um ping: nesse caso, talvez você queira tentar novamente algumas vezes, com um intervalo entre as tentativas. Observe que, por padrão, a versão Node.js usa o endpoint /ping, enquanto a versão Web usa uma consulta simples SELECT 1 para obter um resultado semelhante, já que o endpoint /ping não oferece suporte a CORS. Exemplo: (Node.js/Web) Um ping simples para a instância do servidor ClickHouse. Obs.: para a versão Web, os erros capturados serão diferentes. Código-fonte.
Exemplo: Se você também quiser verificar as credenciais ao chamar o método ping ou especificar parâmetros adicionais, como query_id, poderá usá-lo da seguinte forma:
O método ping aceitará a maioria dos parâmetros padrão do método query — consulte a definição de tipo PingParamsWithSelectQuery.

Close (somente Node.js)

Fecha todas as conexões abertas e libera os recursos. No-op na versão web.

Streaming de arquivos (somente Node.js)

Há vários exemplos de streaming de arquivos com formatos de dados populares (NDJSON, CSV, Parquet) no repositório da biblioteca cliente. O streaming de outros formatos para um arquivo deve ser semelhante ao de Parquet, a única diferença estará no formato usado na chamada query (JSONEachRow, CSV etc.) e no nome do arquivo de saída.

Formatos de dados compatíveis

O cliente lida com formatos de dados como JSON ou texto. Se você especificar format como um dos formatos da família JSON (JSONEachRow, JSONCompactEachRow etc.), o cliente serializará e desserializará os dados durante a comunicação pelo wire. Os dados fornecidos nos formatos de texto “brutos” (famílias CSV, TabSeparated e CustomSeparated) são enviados pelo wire sem transformações adicionais.
Pode haver confusão entre JSON como formato geral e o formato JSON do ClickHouse.O cliente oferece suporte ao streaming de objetos JSON com formatos como JSONEachRow (consulte a visão geral da tabela para outros formatos adequados para streaming; veja também os select_streaming_ examples no repositório da biblioteca cliente).A única questão é que formatos como ClickHouse JSON e alguns outros são representados como um único objeto na resposta e não podem ser transmitidos por streaming pelo cliente.
Para o Parquet, o principal caso de uso das instruções SELECT provavelmente será gravar o fluxo resultante em um arquivo. Veja o exemplo no repositório da biblioteca cliente. JSONEachRowWithProgress é um formato somente de saída que oferece suporte ao reporte de progresso no fluxo. Veja este exemplo para mais detalhes. A lista completa dos formatos de entrada e saída do ClickHouse está disponível aqui.

Tipos de dados do ClickHouse suportados

O tipo JS correspondente é relevante para todos os formatos JSON*, exceto aqueles que representam tudo como string (por exemplo, JSONStringEachRow)
A lista completa dos formatos compatíveis do ClickHouse está disponível aqui. Veja também:

Observações sobre os tipos Date/Date32

Como o cliente insere valores sem conversão adicional de tipo, colunas do tipo Date/Date32 só podem ser inseridas como strings. Exemplo: Insira um valor do tipo Date. Código-fonte
No entanto, se você estiver usando colunas DateTime ou DateTime64, poderá usar tanto strings quanto objetos Date do JS. Objetos Date do JS podem ser passados diretamente para insert, com date_time_input_format definido como best_effort. Consulte este exemplo para mais detalhes.

Ressalvas sobre os tipos Decimal*

É possível inserir valores Decimal usando formatos da família JSON*. Supondo que temos uma tabela definida como:
Podemos inserir valores sem perda de precisão usando a representação textual:
No entanto, ao consultar os dados nos formatos JSON*, o ClickHouse retornará valores Decimal como números por padrão, o que pode levar à perda de precisão. Para evitar isso, você pode converter valores Decimal para string na consulta:
Consulte este exemplo para mais detalhes.

Tipos integrais: Int64, Int128, Int256, UInt64, UInt128, UInt256

Embora o servidor possa aceitá-los como números, eles são retornados como strings nos formatos de saída da família JSON* para evitar overflow de inteiro, já que os valores máximos desses tipos são maiores que Number.MAX_SAFE_INTEGER. Esse comportamento, no entanto, pode ser alterado com a configuração output_format_json_quote_64bit_integers . Exemplo: Ajuste o formato de saída JSON para números de 64 bits.

Configurações do ClickHouse

O cliente pode ajustar o comportamento do ClickHouse por meio do mecanismo de configurações. As configurações podem ser definidas no nível da instância do cliente para que sejam aplicadas a todas as requisições enviadas ao ClickHouse:
Ou uma configuração pode ser aplicada em nível de requisição:
Um arquivo de declaração de tipos com todas as configurações do ClickHouse compatíveis pode ser encontrado aqui.
Certifique-se de que o usuário em nome do qual as consultas são feitas tenha permissões suficientes para alterar as configurações.

Tópicos avançados

Consultas com parâmetros

Você pode criar uma consulta com parâmetros e passar valores para ela a partir da aplicação cliente. Isso permite evitar a formatação da consulta no lado do cliente com valores dinâmicos específicos. Formate uma consulta normalmente e, em seguida, coloque entre chaves os valores que deseja passar dos parâmetros da aplicação para a consulta, no seguinte formato:
onde:
  • name — Identificador do placeholder.
  • data_type - Tipo de dado do valor do parâmetro da aplicação.
Exemplo:: Consulta com parâmetros. Código-fonte .
Consulte https://clickhouse.com/docs/interfaces/cli#cli-queries-with-parameters-syntax para mais detalhes.

Compressão

NB: no momento, a compressão de requisições não está disponível na versão web. A compressão de respostas funciona normalmente. A versão do Node.js oferece suporte a ambas. Aplicações de dados que operam com grandes volumes de dados trafegando pelo wire podem se beneficiar da ativação da compressão. Atualmente, há suporte apenas a GZIP, por meio de zlib.
Os parâmetros de configuração são:
  • response: true instrui o servidor ClickHouse a responder com o corpo da resposta comprimido. Valor padrão: response: false
  • request: true habilita a compressão no corpo da requisição do cliente. Valor padrão: request: false

Logging (somente Node.js)

O logging é uma funcionalidade experimental e pode mudar no futuro.
A implementação padrão do logger emite registros de log em stdout por meio dos métodos console.debug/info e em stderr por meio dos métodos console.warn/error. Você pode personalizar a lógica de logging fornecendo uma LoggerClass e escolher o nível de log desejado por meio do parâmetro level (o padrão é WARN):
Atualmente, o cliente registrará os seguintes eventos:
  • TRACE - informações de baixo nível sobre o ciclo de vida dos sockets Keep-Alive
  • DEBUG - informações da resposta (sem os cabeçalhos de autorização e as informações de host)
  • INFO - praticamente não é usado; exibirá o nível de log atual quando o cliente for inicializado
  • WARN - erros não fatais; uma solicitação ping com falha é registrada como aviso, pois o erro subjacente está incluído no resultado retornado
  • ERROR - erros fatais dos métodos query/insert/exec/command, como uma solicitação com falha
Você pode encontrar a implementação padrão de Logger aqui.

Certificados TLS (somente Node.js)

O Node.js client oferece suporte opcional a TLS básico (somente autoridade certificadora) e mútuo (autoridade certificadora e certificados do cliente). Exemplo de configuração de TLS básico, supondo que você tenha seus certificados na pasta certs e que o nome do arquivo da CA seja CA.pem:
Exemplo de configuração de TLS mútuo com certificados de cliente:
Consulte exemplos completos de TLS básico e mútuo no repositório.

Configuração de Keep-Alive (somente Node.js)

O cliente habilita o Keep-Alive no agente HTTP subjacente por padrão, o que significa que os sockets conectados serão reutilizados em solicitações subsequentes, e o cabeçalho Connection: keep-alive será enviado. Os sockets ociosos permanecerão no pool de conexões por 2500 milissegundos por padrão (consulte as notas sobre como ajustar essa opção). O ideal é que keep_alive.idle_socket_ttl tenha um valor consideravelmente menor do que a configuração do servidor/LB. O principal motivo é que, como o HTTP/1.1 permite que o servidor feche os sockets sem notificar o cliente, se o servidor ou o balanceador de carga fechar a conexão antes de o cliente fazer isso, o cliente poderá tentar reutilizar o socket fechado, resultando em um erro socket hang up. Se você estiver modificando keep_alive.idle_socket_ttl, tenha em mente que ele deve estar sempre sincronizado com a configuração de Keep-Alive do seu servidor/LB e deve ser sempre menor do que ela, garantindo que o servidor nunca feche primeiro a conexão aberta.

Ajustando idle_socket_ttl

O cliente define keep_alive.idle_socket_ttl como 2500 milissegundos, pois esse pode ser considerado o padrão mais seguro; no lado do servidor, keep_alive_timeout pode ser definido para valores tão baixos quanto 3 segundos em versões do ClickHouse anteriores à 23.11 sem modificações no config.xml.
Se você está satisfeito com o desempenho e não enfrenta nenhum problema, é recomendável não aumentar o valor da configuração keep_alive.idle_socket_ttl, pois isso pode levar a possíveis erros de “Socket hang-up”; além disso, se a sua aplicação envia muitas consultas e não há muito intervalo entre elas, o valor padrão deve ser suficiente, pois os sockets não ficarão ociosos por tempo suficiente, e o cliente os manterá no pool.
Você pode encontrar o valor correto do timeout de Keep-Alive nos cabeçalhos de resposta do servidor executando o seguinte comando:
Verifique os valores dos cabeçalhos Connection e Keep-Alive na resposta. Por exemplo:
Nesse caso, keep_alive_timeout é de 10 segundos, e você pode tentar aumentar keep_alive.idle_socket_ttl para 9000 ou até 9500 milissegundos para manter os sockets ociosos abertos por um pouco mais de tempo do que o padrão. Fique atento a possíveis erros de “Socket hang-up”, que indicam que o servidor fecha as conexões antes do cliente, e reduza o valor até que os erros desapareçam.

Solução de problemas

Se você estiver enfrentando erros de socket hang up mesmo usando a versão mais recente do client, há as seguintes opções para resolver esse problema:
  • Ative os logs com pelo menos o nível WARN (padrão). Isso permitirá verificar se há um stream não consumido ou pendente no código da aplicação: a camada de transporte registrará isso no nível WARN, pois isso pode fazer com que o socket seja fechado pelo servidor. Você pode ativar o logging na configuração do client da seguinte forma:
  • Certifique-se de que a configuração desejada esteja aplicada à instância correta do client. Se você tiver várias instâncias de client na aplicação, confira se a que está usando para as queries tem o valor correto de keep_alive.idle_socket_ttl.
  • Reduza a configuração keep_alive.idle_socket_ttl do client em 500 milissegundos. Em certas situações, por exemplo, alta latência de rede entre client e servidor, isso pode ser benéfico, pois evita o caso em que uma requisição de saída obtém um socket que o servidor está prestes a fechar.
  • Se esse erro estiver acontecendo durante queries longas, sem entrada ou saída de dados (por exemplo, um INSERT FROM SELECT de longa duração), isso pode ser causado por um balanceador de carga ou outros componentes de rede que fecham conexões de longa duração ou requisições demoradas. Você pode tentar forçar a entrada de alguns dados durante queries longas usando uma combinação destas ClickHouse settings:
    No entanto, tenha em mente que o tamanho total dos headers recebidos tem limite de 16 KB nas versões recentes do Node.js; após uma certa quantidade de headers de progresso recebidos, em torno de 70 a 80 nos nossos testes, será gerada uma exceção. Também é possível usar uma abordagem totalmente diferente, evitando completamente o tempo de espera na transmissão; isso pode ser feito aproveitando a “funcionalidade” da interface HTTP de que mutações não são canceladas quando a conexão é perdida. Veja este exemplo (parte 2) para mais detalhes.
  • O recurso Keep-Alive pode ser desativado por completo. Nesse caso, o client também adicionará o header Connection: close a cada requisição, e o HTTP agent subjacente não reutilizará as conexões. A configuração keep_alive.idle_socket_ttl será ignorada, pois não haverá sockets ociosos. Isso resultará em sobrecarga adicional, já que uma nova conexão será estabelecida para cada requisição.
  • Descarte possíveis problemas com o restante da stack de rede, incluindo o próprio Node.js, executando um teste simples de linha de comando com a mesma instância do ClickHouse e o mesmo caminho de rede (isto é, a partir da mesma máquina ou segmento de rede, por exemplo, um pod do Kubernetes), por exemplo, usando curl:
    Talvez seja interessante executá-lo em loop por vários minutos. Se você vir erros semelhantes no curl, é provável que o problema não esteja relacionado à configuração do client, mas sim à stack de rede ou à configuração do servidor.
  • Para testar a conexão com funcionalidade nativa do Node.js, você pode tentar criar uma requisição HTTP simples para o servidor ClickHouse usando a API fetch integrada:
  • Em alguns casos, o código da aplicação ou os adaptadores do framework podem adicionar um ping() preventivo antes da execução real da consulta, o que pode levar a uma situação em que a solicitação ping() é bem-sucedida, mas a solicitação de consulta seguinte falha com um erro “socket hang up” devido ao mesmo problema subjacente com conexões ociosas. Se você identificar esse padrão nos logs, verifique se há alguma opção para desativar pings preventivos no seu framework ou no código da aplicação. Isso também deve ajudar a reduzir a probabilidade de ter a taxa limitada por qualquer componente intermediário da rede.
  • Certifique-se de que a própria aplicação esteja recebendo tempo de CPU suficiente e de que a rede não esteja sendo limitada pelo provedor de hospedagem. Diferentes formas de monitoramento, como métricas de pausa de GC, métricas de defasagem do loop de eventos e outras semelhantes, também podem ser úteis para descartar possíveis problemas de escassez de recursos.
  • Tente verificar o código da sua aplicação com a regra ESLint no-floating-promises habilitada, o que ajudará a identificar promises não tratadas que podem levar a streams e sockets pendentes.

Usuários somente leitura

Ao usar o client com um usuário readonly=1, a compressão da resposta não pode ser habilitada, pois requer a configuração enable_http_compression. A configuração a seguir resultará em um erro:
Veja o exemplo, que mostra mais detalhes sobre as limitações de usuários com readonly=1.

Proxy com pathname

Se a sua instância do ClickHouse estiver atrás de um proxy e houver um pathname na URL, como, por exemplo, http://proxy:8123/clickhouse&#95;server, especifique clickhouse_server na opção de configuração pathname (com ou sem barra inicial); caso contrário, se ele for informado diretamente em url, será interpretado como a opção database. Há suporte para vários segmentos, por exemplo, /my_proxy/db.

Proxy reverso com autenticação

Se você tiver um proxy reverso com autenticação à frente da sua implantação do ClickHouse, poderá usar a configuração http_headers para fornecer os cabeçalhos necessários:

Agente HTTP/HTTPS personalizado (experimental, somente Node.js)

Este é um recurso experimental que pode sofrer mudanças incompatíveis com versões anteriores em lançamentos futuros. A implementação padrão e as configurações fornecidas pelo cliente devem ser suficientes para a maioria dos casos de uso. Use este recurso apenas se tiver certeza de que precisa dele.
Por padrão, o cliente configurará o agente HTTP ou HTTPS subjacente usando as definições fornecidas na configuração do cliente (como max_open_connections, keep_alive.enabled, tls), que gerenciará as conexões com o servidor ClickHouse. Além disso, se certificados TLS forem usados, o agente subjacente será configurado com os certificados necessários, e os cabeçalhos corretos de autenticação TLS serão aplicados. A partir da versão 1.2.0, é possível fornecer um agente HTTP ou HTTPS personalizado ao cliente, substituindo o agente subjacente padrão. Isso pode ser útil em caso de configurações de rede complexas. As seguintes condições se aplicam se um agente personalizado for fornecido:
  • As opções max_open_connections e tls não terão nenhum efeito e serão ignoradas pelo cliente, pois fazem parte da configuração do agente subjacente.
  • keep_alive.enabled regulará apenas o valor padrão do cabeçalho Connection (true -> Connection: keep-alive, false -> Connection: close).
  • Embora o gerenciamento de sockets keep-alive ociosos continue funcionando (já que não está vinculado ao agente, mas a um socket específico), agora é possível desativá-lo completamente definindo o valor de keep_alive.idle_socket_ttl como 0.

Exemplos de uso de um agente personalizado

Usando um agente HTTP ou HTTPS personalizado sem certificados:
Usando um HTTPS Agent personalizado com TLS básico e certificado da CA:
Usando um agente HTTPS personalizado com TLS mútuo:
Com certificados e um agente HTTPS personalizado, provavelmente é necessário desativar o cabeçalho de autorização padrão por meio da configuração set_basic_auth_header (introduzida na versão 1.2.0), pois ele conflita com os cabeçalhos TLS. Todos os cabeçalhos TLS devem ser fornecidos manualmente.

Limitações conhecidas (Node.js/web)

  • Não há mapeadores de dados para os conjuntos de resultados, por isso apenas tipos primitivos da linguagem são usados. Está prevista a adição de mapeadores para determinados tipos de dados com suporte ao formato RowBinary.
  • Existem algumas ressalvas sobre os tipos de dados Decimal* e Date* / DateTime*.
  • Ao usar formatos da família JSON*, números maiores que Int32 são representados como strings, já que os valores máximos dos tipos Int64+ são maiores que Number.MAX_SAFE_INTEGER. Consulte a seção Tipos integrais para mais detalhes.

Limitações conhecidas (web)

  • O streaming para consultas SELECT funciona, mas está desabilitado para inserções (também no nível do tipo).
  • A compressão das requisições está desabilitada, e a configuração é ignorada. A compressão das respostas funciona.
  • Ainda não há suporte a logging.

Dicas para otimizar o desempenho

  • Para reduzir o consumo de memória da aplicação, considere usar streams para inserts grandes (por exemplo, a partir de arquivos) e instrução SELECT, quando aplicável. Para listeners de eventos e casos de uso semelhantes, async inserts podem ser outra boa opção, permitindo minimizar ou até mesmo evitar completamente o batching no client side. Exemplos de async insert estão disponíveis no repositório da biblioteca cliente, com async_insert_ como prefixo do nome do arquivo.
  • O client não habilita a compressão de request nem de response por padrão. No entanto, ao selecionar ou inserir datasets grandes, você pode considerar habilitá-la via ClickHouseClientConfigOptions.compression (seja apenas para request ou response, ou para ambos).
  • A compressão tem um impacto significativo no desempenho. Habilitá-la para request ou response afetará negativamente a velocidade das instruções SELECT ou dos inserts, respectivamente, mas reduzirá a quantidade de tráfego de rede transferida pela aplicação.

Fale conosco

Se você tiver alguma dúvida ou precisar de ajuda, fique à vontade para entrar em contato conosco no Slack da comunidade (canal #clickhouse-js) ou via issues no GitHub.
Última modificação em 23 de julho de 2026