Skip to main content

Visão geral

O ClickHouse oferece suporte ao protocolo Apache Arrow Flight — um framework de RPC de alto desempenho para o transporte eficiente de dados colunares usando o formato Arrow IPC por meio de gRPC. A implementação inclui suporte ao Arrow Flight SQL, permitindo que ferramentas de BI e aplicativos compatíveis com o protocolo Flight SQL consultem o ClickHouse diretamente. Principais recursos:
  • Executar consultas SQL e recuperar resultados no formato Apache Arrow.
  • Inserir dados em tabelas usando o formato Arrow.
  • Consultar metadados (catálogos, esquemas, tabelas, chaves primárias) por meio de comandos do Flight SQL.
  • Criar, vincular, executar e fechar instruções preparadas no servidor por meio do Flight SQL.
  • Gerenciar sessões e configurações por meio de ações do Flight SQL.
  • Criptografia com TLS e autenticação com nome de usuário e senha.
  • Recuperação incremental de resultados por meio de PollFlightInfo.
  • Cancelamento de consultas por meio de CancelFlightInfo.

Habilitando o Arrow Flight Server

Para habilitar o Arrow Flight server, adicione a configuração arrowflight_port à configuração do servidor ClickHouse:
Ao iniciar, uma mensagem de log confirma que a interface está ativa:

Configuração de TLS

Para ativar o TLS na interface Arrow Flight, defina as seguintes configurações:
Quando o TLS estiver habilitado, os clientes deverão se conectar usando o esquema grpc+tls:// em vez de grpc://.

Autenticação

A interface Arrow Flight oferece suporte a dois métodos de autenticação:

Autenticação básica

Os clientes se autenticam com um nome de usuário e uma senha por meio do cabeçalho HTTP padrão Authorization: Basic. Após a autenticação bem-sucedida, o servidor retorna um token Bearer no cabeçalho da resposta.

Autenticação com Bearer Token

As solicitações subsequentes podem usar o Bearer token retornado pela autenticação básica por meio do cabeçalho Authorization: Bearer <token>. O token é renovado automaticamente a cada uso e expira com base na configuração do servidor default_session_timeout (padrão: 60 segundos).

Exemplo em Python

Com TLS:

Gerenciamento de sessões

A interface Arrow Flight oferece suporte a sessões do ClickHouse por meio de cabeçalhos de metadados gRPC personalizados:
Como o Arrow Flight usa gRPC sobre HTTP/2, os nomes dos cabeçalhos de metadados diferenciam maiúsculas de minúsculas e devem ser especificados em minúsculas, exatamente como mostrado (por exemplo, x-clickhouse-session-id, e não X-ClickHouse-Session-Id). Isso é exigido pela RFC 9113, Seção 8.2, que determina que os nomes dos campos em HTTP/2 contenham apenas caracteres minúsculos. Isso difere do HTTP/1.1, em que os nomes dos cabeçalhos não diferenciam maiúsculas de minúsculas.
As sessões permitem definir configurações persistentes do ClickHouse por meio da ação SetSessionOptions (consulte DoAction).

Referência de configuração do servidor

Métodos RPC suportados

GetFlightInfo

Executa uma consulta e retorna um FlightInfo contendo o esquema do resultado, endpoints com tickets para recuperação de dados, contagem de linhas e de bytes. Aceita um FlightDescriptor, que pode ser:
  • descritor PATH: Um path de um único componente interpretado como nome de tabela. Gera SELECT * FROM <table>.
  • descritor CMD: Uma string bruta de consulta SQL ou um comando protobuf Flight SQL serializado (consulte Flight SQL Commands).
A consulta é executada integralmente, e os resultados são armazenados em tickets no servidor. Cada bloco de dados gera um endpoint/ticket separado, permitindo que os clientes recuperem os dados em paralelo.

PollFlightInfo

Permite a recuperação incremental de resultados para consultas de longa execução. Em vez de esperar a consulta inteira ser concluída (como faz o GetFlightInfo), o PollFlightInfo retorna os resultados bloco a bloco. Na primeira chamada, a consulta começa a ser executada. A resposta inclui:
  • Um FlightInfo com endpoints para quaisquer blocos de dados disponíveis até aquele momento.
  • Um FlightDescriptor para a próxima verificação (se houver expectativa de mais resultados).
As chamadas seguintes com o descritor retornado recuperam blocos adicionais. Quando não há mais dados disponíveis, a resposta não contém um próximo descritor.
A implementação atual bloqueia até que um bloco de dados esteja disponível, em vez de retornar imediatamente sem dados.

GetSchema

Retorna o esquema Arrow para o resultado de uma consulta sem executar a consulta inteira. Aceita os mesmos tipos de descritor que GetFlightInfo.

DoGet

Recupera os dados de um determinado ticket. Aceita uma destas opções:
  • Um ticket retornado por GetFlightInfo ou PollFlightInfo.
  • Uma string bruta de consulta SQL como valor do ticket.

DoPut

Envia dados ao ClickHouse. Aceita um FlightDescriptor e um fluxo de lotes de registros Arrow. Insert por nome da tabela (descritor PATH):
Inserção via SQL (descritor CMD):
Executar DDL/DML via Flight SQL CommandStatementUpdate: Clientes Flight SQL usam CommandStatementUpdate para executar instruções DDL/DML (CREATE, INSERT, ALTER etc.). A resposta inclui a contagem de linhas afetadas. Ingestão em massa via Flight SQL CommandStatementIngest: Só há suporte para anexar a tabelas existentes (TABLE_NOT_EXIST_OPTION_FAIL + TABLE_EXISTS_OPTION_APPEND). Catálogos e tabelas temporárias não são compatíveis com este comando. transaction_id não tem suporte em CommandStatementUpdate nem em CommandStatementIngest. Se for fornecido, o ClickHouse retorna um erro NotImplemented.
Somente o formato Arrow é aceito para transferência de dados. Especificar outros formatos em SQL (por exemplo, FORMAT JSON) resulta em um erro.

DoAction

Executa ações nomeadas. Há suporte para as seguintes ações:

CancelFlightInfo

Cancela uma consulta em execução associada a um FlightInfo. O ID da consulta é extraído do campo app_metadata de FlightInfo. Também cancela todos os descritores de polling associados à consulta.

SetSessionOptions

Define as configurações do servidor ClickHouse para a sessão atual. Exige que um ID de sessão seja definido por meio do cabeçalho x-clickhouse-session-id. Tipos de valor compatíveis: string, booleano, inteiro, double e listas de strings. Se o nome de uma configuração for desconhecido, o erro INVALID_NAME será retornado. Se um valor não puder ser interpretado, o erro INVALID_VALUE será retornado.

GetSessionOptions

Retorna todas as configurações atuais do ClickHouse e seus valores da sessão. Retorna um mapa dos nomes das configurações para valores em string (consulta system.settings internamente).

CreatePreparedStatement

Cria uma instrução preparada no servidor e retorna um identificador da instrução. A solicitação contém o texto da consulta SQL com placeholders ?. transaction_id não tem suporte nesta ação. Se for fornecido, o ClickHouse retorna um erro NotImplemented. Para instruções de consulta, a resposta pode incluir:
  • dataset_schema: schema do conjunto de resultados.
  • parameter_schema: schema dos parâmetros da instrução.
Se a inferência de schema falhar para uma consulta válida (por exemplo, quando substituir placeholders por NULL não for válido para essa consulta), o ClickHouse ainda cria a instrução preparada e retorna o identificador sem dataset_schema. dataset_schema é apenas uma estimativa, conforme prevê a especificação Flight SQL — ela afirma que o schema do resultado pode depender dos parâmetros, que o servidor deve fornecer sua melhor estimativa e que os clientes não devem presumir que o schema seja exato. Não confie nele; execute a instrução para obter o schema que descreve os dados. No ClickHouse, ele pode divergir do que é efetivamente entregue por dois motivos:
  • A inferência substitui cada ? por NULL, de modo que um placeholder que determina uma coluna de resultado recebe o tipo desse NULL, e não o tipo do valor que você vincula posteriormente. SELECT ? AS x infere uma coluna do tipo Nothing, mas, ao vincular 5, é entregue um UInt8. Um placeholder usado apenas em um predicado, como em SELECT id, name FROM t WHERE id = ?, não apresenta esse problema, porque os tipos do resultado vêm da tabela.
  • Uma coluna sem equivalente em Arrow obtém seu tipo Arrow de output_format_arrow_unsupported_types, que cada chamada resolve a partir da sessão que a realiza. Como um identificador pertence ao usuário, e não a uma única sessão, uma chamada posterior pode resolvê-lo de forma diferente e entregar binary onde utf8 havia sido anunciado, ou vice-versa. Definir o modo dentro da própria consulta preparada o fixa para ambos os casos.
As instruções preparadas pertencem ao usuário autenticado, não a uma única sessão. Se você abrir várias sessões como o mesmo usuário, poderá executar, refazer o bind e fechar o mesmo identificador de instrução em qualquer uma dessas sessões. Outros usuários não podem executar, fazer bind nem fechar um identificador de instrução que não tenham criado. arrowflight.prepared_statements_lifetime_seconds controla o comportamento de expiração:
  • > 0: usa o valor configurado como ciclo de vida da instrução. A expiração é renovada a cada solicitação, tanto para instruções vinculadas a sessão quanto para instruções sem sessão.
  • 0: instruções preparadas não expiram automaticamente.
  • -1 (padrão): se a instrução for criada em uma sessão, seu ciclo de vida seguirá o tempo limite dessa sessão e será renovado a cada solicitação nessa sessão. Se a instrução for criada sem uma sessão, ela não expirará automaticamente.
As instruções expiradas são removidas e deixam de contar para arrowflight.max_prepared_statements_per_user.

ClosePreparedStatement

Fecha uma instrução preparada e libera os recursos associados no servidor quando a solicitação contém um identificador de instrução não vazio. O ClickHouse também oferece suporte ao fechamento em massa com ClosePreparedStatement quando o identificador está vazio:
  • Se x-clickhouse-session-id estiver presente, fecha todas as instruções preparadas do usuário autenticado nessa sessão.
  • Se não houver ID de sessão, fecha apenas as instruções preparadas sem sessão do usuário autenticado.
Se uma instrução preparada for criada em uma sessão (via x-clickhouse-session-id), ela também será fechada automaticamente quando essa sessão for encerrada.

Comandos do Flight SQL

Quando um descritor CMD contém uma mensagem Flight SQL protobuf serializada, ClickHouse processa os seguintes comandos:

Suportado via GetFlightInfo / GetSchema

Suportado via DoPut

Sem suporte no ClickHouse

Esses comandos correspondem a recursos que o ClickHouse não oferece; por isso, não têm suporte na interface Arrow Flight SQL.

Exemplo completo

Query
Response

Formato de dados

Todos os dados são transferidos no formato Apache Arrow IPC. Apenas o formato Arrow é compatível — especificar outros formatos do ClickHouse (por exemplo, FORMAT JSON, FORMAT CSV) resulta em erro. Os tipos de dados do ClickHouse são mapeados para tipos Arrow durante a serialização. O Arrow Flight sempre usa o mapeamento canônico do Arrow e, ao contrário dos formatos de saída Arrow e ArrowStream, não segue as configurações output_format_arrow_* que alteram a forma como um tipo é representado — output_format_arrow_string_as_string, output_format_arrow_low_cardinality_as_dictionary, output_format_arrow_date_as_uint16, output_format_arrow_fixed_string_as_fixed_byte_array e as configurações de índice do dicionário não têm efeito aqui. Por isso, a mesma consulta pode produzir um schema diferente pelo Arrow Flight e pelo FORMAT Arrow, e isso é intencional, por dois motivos:
  • O Flight SQL fixa o schema de suas respostas de metadata. CommandGetTables, por exemplo, deve retornar catalog_name: utf8, db_schema_name: utf8, table_name: utf8 not null, table_type: utf8 not null, table_schema: bytes not null. Permitir que uma session setting transformasse essas colunas utf8 em binary tornaria o ClickHouse não conforme para todos os drivers Flight SQL e também alteraria o schema por tabela que o ClickHouse anuncia dentro de table_schema.
  • Um cliente Flight busca o schema e os dados em chamadas separadas (GetFlightInfo ou GetSchema e, depois, DoGet). Qualquer configuração capaz de alterar o schema abre espaço para que o schema anunciado e o stream entregue divirjam, caso a session mude nesse intervalo.
A única exceção é um tipo que não tem equivalente algum no Arrow, como JSON, Dynamic, QBit ou AggregateFunction. Não há mapeamento canônico ao qual se ater, então o ClickHouse precisa escolher uma representação, e output_format_arrow_unsupported_types permite indicar qual: Uma coluna AggregateFunction é o único tipo que permanece como coluna Arrow Binary mesmo no modo text: sua text form é o aggregate state bruto, que não é UTF-8 válido, e uma coluna Arrow Utf8 precisa conter UTF-8 válido. Use finalizeAggregation se quiser um valor legível. Pelo mesmo motivo, o ClickHouse substitui toda invalid UTF-8 sequence em um valor text por U+FFFD (�) antes de escrevê-lo na coluna Utf8. Um Dynamic que contém uma String serializa esses bytes literalmente, e eles podem ser arbitrários; portanto, sem essa substituição, a coluna violaria a especificação do Arrow e poderia ser rejeitada por um cliente estrito. Somente os valores que já não são texto válido mudam. Use o modo binary quando os bytes precisarem ser preservados exatamente. output_format_arrow_string_as_string nunca se aplica a essas colunas, nem mesmo em FORMAT Arrow — ela rege apenas colunas String e FixedString reais. Portanto, o tipo Arrow de uma coluna clickhouse.opaque sempre indica qual encoding ela contém: Utf8 para a text form e Binary para a binária. É por isso que um aggregate state contido em um Dynamic sofre perda no modo text, ainda que uma coluna AggregateFunction não sofra. A coluna é tipada a partir de Dynamic, que nada diz sobre o que suas linhas contêm, e o schema é fixado antes de qualquer valor ser visto, de modo que não é possível dar ao state uma coluna Binary própria. Use o modo binary para preservá-lo. Um Variant lista suas alternativas, então um AggregateFunction entre elas recebe seu próprio filho Binary e não é afetado. Fora isso, tal coluna é indistinguível de uma coluna Utf8/Binary genuína, por isso ela é declarada como um Arrow extension type: a metadata do field contém ARROW:extension:name = clickhouse.opaque e o nome original do tipo ClickHouse em ARROW:extension:metadata. Um cliente que não reconhece o nome da extensão vê o plain storage type, como prescreve a especificação do Arrow. As nested columns são marcadas em seu próprio field, de modo que o filho de um Array(JSON) carrega a marcação, assim como a chave de um Map(JSON, ...), e não o contêiner em si. A antiga configuração booleana output_format_arrow_unsupported_types_as_binary continua funcionando e equivale a throw quando definida como 0 e a binary quando definida como 1. Ela só é consultada enquanto output_format_arrow_unsupported_types permanecer com seu valor padrão.

Compatibilidade

A interface Arrow Flight é compatível com qualquer cliente ou ferramenta compatível com o protocolo Arrow Flight ou Arrow Flight SQL, incluindo:
  • Python (pyarrow)
  • Java (org.apache.arrow.flight)
  • C++ (arrow::flight)
  • Go (apache/arrow/go)
  • drivers ADBC (Arrow Database Connectivity)
  • DBeaver e outras ferramentas com suporte a Flight SQL
Se houver um conector nativo do ClickHouse disponível para sua ferramenta (por exemplo, JDBC, ODBC, protocolo nativo), prefira usá-lo, a menos que o Arrow Flight seja especificamente necessário por questões de desempenho ou compatibilidade de formato.

Recursos do ArrowFlight no cliente

O ClickHouse também pode atuar como cliente Flight para ler dados de servidores Arrow Flight externos. Veja:

Veja também

Última modificação em 26 de setembro de 2026