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çãoarrowflight_port à configuração do servidor ClickHouse:
Configuração de TLS
Para ativar o TLS na interface Arrow Flight, defina as seguintes configurações: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ãoAuthorization: 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çalhoAuthorization: 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
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.SetSessionOptions (consulte DoAction).
Referência de configuração do servidor
Métodos RPC suportados
GetFlightInfo
Executa uma consulta e retorna umFlightInfo 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).
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 oGetFlightInfo), o PollFlightInfo retorna os resultados bloco a bloco.
Na primeira chamada, a consulta começa a ser executada. A resposta inclui:
- Um
FlightInfocom endpoints para quaisquer blocos de dados disponíveis até aquele momento. - Um
FlightDescriptorpara a próxima verificação (se houver expectativa de mais resultados).
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 queGetFlightInfo.
DoGet
Recupera os dados de um determinado ticket. Aceita uma destas opções:- Um ticket retornado por
GetFlightInfoouPollFlightInfo. - Uma string bruta de consulta SQL como valor do ticket.
DoPut
Envia dados ao ClickHouse. Aceita umFlightDescriptor e um fluxo de lotes de registros Arrow.
Insert por nome da tabela (descritor PATH):
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 umFlightInfo. 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çalhox-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 (consultasystem.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.
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
?porNULL, de modo que um placeholder que determina uma coluna de resultado recebe o tipo desseNULL, e não o tipo do valor que você vincula posteriormente.SELECT ? AS xinfere uma coluna do tipoNothing, mas, ao vincular5, é entregue umUInt8. Um placeholder usado apenas em um predicado, como emSELECT 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 entregarbinaryondeutf8havia sido anunciado, ou vice-versa. Definir o modo dentro da própria consulta preparada o fixa para ambos os casos.
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.
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 comClosePreparedStatement quando o identificador está vazio:
- Se
x-clickhouse-session-idestiver 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.
x-clickhouse-session-id), ela também será fechada automaticamente quando essa sessão for encerrada.
Comandos do Flight SQL
Quando um descritorCMD 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 formatoArrow é 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 retornarcatalog_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 colunasutf8embinarytornaria o ClickHouse não conforme para todos os drivers Flight SQL e também alteraria o schema por tabela que o ClickHouse anuncia dentro detable_schema. - Um cliente Flight busca o schema e os dados em chamadas separadas (
GetFlightInfoouGetSchemae, 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.
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