Este motor fornece integração com o ecossistema Apache Hadoop, permitindo gerenciar dados no HDFS via ClickHouse. Este motor é semelhante aos motores File e URL, mas oferece recursos específicos do Hadoop.
Esse recurso não conta com suporte dos engenheiros do ClickHouse e sua qualidade é reconhecidamente duvidosa. Se tiver algum problema, corrija por conta própria e envie um pull request.
Uso
ENGINE = HDFS(URI, format)Parâmetros do motor
URI- URI completa do arquivo no HDFS. A parte do caminho daURIpode conter globs. Nesse caso, a tabela fica em modo somente leitura.format- especifica um dos formatos de arquivo disponíveis. Para executar consultasSELECT, o formato deve ser compatível com entrada e, para executar consultasINSERT– com saída. Os formatos disponíveis estão listados na seção Formatos.- [PARTITION BY expr]
PARTITION BY
PARTITION BY — Opcional. Na maioria dos casos, você não precisa de uma chave de partição e, quando ela for necessária, em geral também não precisa ser mais granular do que por mês. O particionamento não acelera as consultas (ao contrário da expressão ORDER BY). Você nunca deve usar um particionamento granular demais. Não particione seus dados por identificadores ou nomes de clientes (em vez disso, use o identificador ou nome do cliente como a primeira coluna na expressão ORDER BY).
Para particionar por mês, use a expressão toYYYYMM(date_column), em que date_column é uma coluna com uma data do tipo Date. Os nomes das partições aqui têm o formato "YYYYMM".
Exemplo:
1. Configure a tabela hdfs_engine_table:
CREATE TABLE hdfs_engine_table (name String, value UInt32) ENGINE=HDFS('hdfs://hdfs1:9000/other_storage', 'TSV')2. Preencha o arquivo:
INSERT INTO hdfs_engine_table VALUES ('one', 1), ('two', 2), ('three', 3)3. Consulte os dados:
SELECT * FROM hdfs_engine_table LIMIT 2┌─name─┬─value─┐
│ one │ 1 │
│ two │ 2 │
└──────┴───────┘Detalhes de implementação
- Leituras e escritas podem ser paralelas.
- Não há suporte a:
- operações
ALTEReSELECT...SAMPLE. - Índices.
- A replicação zero-copy é possível, mas não recomendada.
- operações
Globs no caminho
Vários componentes do caminho podem ter globs. Para ser processado, o arquivo deve existir e corresponder ao padrão do caminho completo. A listagem dos arquivos ocorre durante SELECT (não no momento de CREATE).
*— Corresponde a qualquer quantidade de caracteres, exceto/, incluindo a string vazia.?— Corresponde a qualquer caractere único.{some_string,another_string,yet_another_one}— Corresponde a qualquer uma das strings'some_string', 'another_string', 'yet_another_one'.{N..M}— Corresponde a qualquer número no intervalo de N a M, incluindo ambos os limites.
As construções com {} são semelhantes à função de tabela remote.
Exemplo
-
Suponha que temos vários arquivos no formato TSV com os seguintes URIs no HDFS:
- 'hdfs://hdfs1:9000/some_dir/some_file_1'
- 'hdfs://hdfs1:9000/some_dir/some_file_2'
- 'hdfs://hdfs1:9000/some_dir/some_file_3'
- 'hdfs://hdfs1:9000/another_dir/some_file_1'
- 'hdfs://hdfs1:9000/another_dir/some_file_2'
- 'hdfs://hdfs1:9000/another_dir/some_file_3'
-
Há várias maneiras de criar uma tabela composta pelos seis arquivos:
CREATE TABLE table_with_range (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/{some,another}_dir/some_file_{1..3}', 'TSV')Outra maneira:
CREATE TABLE table_with_question_mark (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/{some,another}_dir/some_file_?', 'TSV')A tabela é composta por todos os arquivos em ambos os diretórios (todos os arquivos devem atender ao formato e ao esquema descritos na consulta):
CREATE TABLE table_with_asterisk (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/{some,another}_dir/*', 'TSV')Exemplo
Crie uma tabela com arquivos nomeados file000, file001, … , file999:
CREATE TABLE big_table (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/big_dir/file{0..9}{0..9}{0..9}', 'CSV')Configuração
Assim como o GraphiteMergeTree, o motor HDFS oferece suporte a configuração estendida usando o arquivo de configuração do ClickHouse. Há duas chaves de configuração que você pode usar: global (hdfs) e no nível do usuário (hdfs_*). A configuração global é aplicada primeiro e, em seguida, a configuração no nível do usuário é aplicada (se existir).
<!-- Global configuration options for HDFS engine type -->
<hdfs>
<hadoop_kerberos_keytab>/tmp/keytab/clickhouse.keytab</hadoop_kerberos_keytab>
<hadoop_kerberos_principal>clickuser@TEST.CLICKHOUSE.TECH</hadoop_kerberos_principal>
<hadoop_security_authentication>kerberos</hadoop_security_authentication>
</hdfs>
<!-- Configuration specific for user "root" -->
<hdfs_root>
<hadoop_kerberos_principal>root@TEST.CLICKHOUSE.TECH</hadoop_kerberos_principal>
</hdfs_root>Opções de configuração
Suportado por libhdfs3
| parâmetro | valor padrão |
|---|---|
| rpc_client_connect_tcpnodelay | true |
| dfs_client_read_shortcircuit | true |
| output_replace-datanode-on-failure | true |
| input_notretry-another-node | false |
| input_localread_mappedfile | true |
| dfs_client_use_legacy_blockreader_local | false |
| rpc_client_ping_interval | 10 * 1000 |
| rpc_client_connect_timeout | 600 * 1000 |
| rpc_client_read_timeout | 3600 * 1000 |
| rpc_client_write_timeout | 3600 * 1000 |
| rpc_client_socket_linger_timeout | -1 |
| rpc_client_connect_retry | 10 |
| rpc_client_timeout | 3600 * 1000 |
| dfs_default_replica | 3 |
| input_connect_timeout | 600 * 1000 |
| input_read_timeout | 3600 * 1000 |
| input_write_timeout | 3600 * 1000 |
| input_localread_default_buffersize | 1 * 1024 * 1024 |
| dfs_prefetchsize | 10 |
| input_read_getblockinfo_retry | 3 |
| input_localread_blockinfo_cachesize | 1000 |
| input_read_max_retry | 60 |
| output_default_chunksize | 512 |
| output_default_packetsize | 64 * 1024 |
| output_default_write_retry | 10 |
| output_connect_timeout | 600 * 1000 |
| output_read_timeout | 3600 * 1000 |
| output_write_timeout | 3600 * 1000 |
| output_close_timeout | 3600 * 1000 |
| output_packetpool_size | 1024 |
| output_heartbeat_interval | 10 * 1000 |
| dfs_client_failover_max_attempts | 15 |
| dfs_client_read_shortcircuit_streams_cache_size | 256 |
| dfs_client_socketcache_expiryMsec | 3000 |
| dfs_client_socketcache_capacity | 16 |
| dfs_default_blocksize | 64 * 1024 * 1024 |
| dfs_default_uri | "hdfs://localhost:9000" |
| hadoop_security_authentication | "simple" |
| hadoop_security_kerberos_ticket_cache_path | "" |
| dfs_client_log_severity | "INFO" |
| dfs_domain_socket_path | "" |
A referência de configuração do HDFS pode explicar alguns parâmetros.
Extras do ClickHouse
| parâmetro | valor padrão |
|---|---|
| hadoop_kerberos_keytab | "" |
| hadoop_kerberos_principal | "" |
| libhdfs3_conf | "" |
Limitações
hadoop_security_kerberos_ticket_cache_pathelibhdfs3_confsó podem ser globais, não específicos por usuário
Suporte ao Kerberos
Se o parâmetro hadoop_security_authentication tiver o valor kerberos, o ClickHouse será autenticado via Kerberos.
Os parâmetros estão aqui, e hadoop_security_kerberos_ticket_cache_path pode ser útil.
Observe que, devido a limitações do libhdfs3, apenas a abordagem antiga é compatível;
as comunicações com o datanode não são protegidas por SASL (HADOOP_SECURE_DN_USER é um indicador confiável dessa
abordagem de segurança). Use tests/integration/test_storage_kerberized_hdfs/hdfs_configs/bootstrap.sh como referência.
Se hadoop_kerberos_keytab, hadoop_kerberos_principal ou hadoop_security_kerberos_ticket_cache_path forem especificados, a autenticação via Kerberos será usada. Nesse caso, hadoop_kerberos_keytab e hadoop_kerberos_principal são obrigatórios.
Suporte a HA do NameNode do HDFS
O libhdfs3 oferece suporte a HA do NameNode do HDFS.
- Copie
hdfs-site.xmlde um nó do HDFS para/etc/clickhouse-server/. - Adicione o trecho a seguir ao arquivo de configuração do ClickHouse:
<hdfs>
<libhdfs3_conf>/etc/clickhouse-server/hdfs-site.xml</libhdfs3_conf>
</hdfs>- Em seguida, use o valor da tag
dfs.nameservicesemhdfs-site.xmlcomo o endereço do namenode no URI do HDFS. Por exemplo, substituahdfs://appadmin@192.168.101.11:8020/abc/porhdfs://appadmin@my_nameservice/abc/.
Colunas virtuais
_path— Caminho do arquivo. Tipo:LowCardinality(String)._file— Nome do arquivo. Tipo:LowCardinality(String)._size— Tamanho do arquivo em bytes. Tipo:Nullable(UInt64). Se o tamanho for desconhecido, o valor seráNULL._time— Hora da última modificação do arquivo. Tipo:Nullable(DateTime). Se a hora for desconhecida, o valor seráNULL._etag— ETag do arquivo. Tipo:LowCardinality(String). O HDFS não tem ETag nativo; portanto, o valor é gerado a partir do horário de modificação e do tamanho do arquivo, no formato<mtime_seconds>_<size>. Como olibhdfs3expõe o horário de modificação com precisão de apenas um segundo, uma regravação no mesmo segundo que mantém o mesmo tamanho produz o mesmo valor; por esse motivo, esse ETag gerado não é usado como chave de cache de conteúdo.
Configurações de armazenamento
- hdfs_truncate_on_insert - permite truncar o arquivo antes de inserir dados nele. Desativado por padrão.
- hdfs_create_new_file_on_insert - permite criar um novo arquivo a cada insert se o formato tiver sufixo. Desativado por padrão.
- hdfs_skip_empty_files - permite ignorar arquivos vazios durante a leitura. Desativado por padrão.
Veja também