Funções de tabela S3
s3 permite ler e gravar arquivos em armazenamento compatível com S3. A estrutura dessa sintaxe é:
- path — URL do bucket com o path para o arquivo. Isso oferece suporte aos seguintes curingas no modo somente leitura:
*,?,{abc,def}e{N..M}, em queN,Msão números e'abc','def'são strings. Para mais informações, consulte a documentação sobre uso de curingas no path. - format — O formato do arquivo.
- structure — Estrutura da tabela. Formato
'column1_name column1_type, column2_name column2_type, ...'. - compression — O parâmetro é opcional. Valores compatíveis:
none,gzip/gz,brotli/br,xz/LZMA,zstd/zst. Por padrão, a compressão será detectada automaticamente pela extensão do arquivo.
Preparação
DESCRIBE:
DESCRIBE TABLE deve mostrar como o ClickHouse inferiria automaticamente esses dados, conforme aparecem no bucket do S3. Observe que ele também reconhece e descomprime automaticamente o formato de compressão gzip:
MergeTree padrão como destino. A instrução abaixo cria uma tabela chamada trips no banco de dados padrão. Observe que optamos por ajustar alguns desses tipos de dados, conforme inferido acima, em particular para não usar o modificador de tipo de dados Nullable(), o que poderia causar armazenamento adicional desnecessário de dados e alguma sobrecarga extra de desempenho:
pickup_date. Em geral, uma chave de partição é usada para gerenciamento de dados, mas mais adiante usaremos essa chave para paralelizar as gravações no S3.
Cada entrada no nosso conjunto de dados de corridas de táxi corresponde a uma viagem. Esses dados anonimizados contêm 20 milhões de registros, compactados no bucket do S3 https://datasets-documentation.s3.eu-west-3.amazonaws.com/ na pasta nyc-taxi. Os dados estão no formato TSV, com aproximadamente 1 milhão de linhas por arquivo.
Lendo dados do S3
TabSeparatedWithNames codifica os nomes das colunas na primeira linha. Outros formatos, como CSV ou TSV, retornarão colunas geradas automaticamente para esta consulta, por exemplo, c1, c2, c3 etc.
As consultas também oferecem suporte a colunas virtuais, como _path e _file, que fornecem informações sobre o caminho do bucket e o nome do arquivo, respectivamente. Por exemplo:
MergeTree no ClickHouse.
Usando clickhouse-local
clickhouse-local permite processar arquivos locais rapidamente sem implantar nem configurar o servidor ClickHouse. Qualquer consulta que use a função de tabela s3 pode ser executada com esse utilitário. Por exemplo:
Inserindo dados do S3
s3 com uma instrução INSERT simples. Observe que não precisamos listar as colunas, porque a tabela de destino fornece a estrutura necessária. Isso exige que as colunas apareçam na ordem especificada na instrução DDL da tabela: as colunas são mapeadas de acordo com sua posição na cláusula SELECT. A inserção de todas as 10 milhões de linhas pode levar alguns minutos, dependendo da instância do ClickHouse. Abaixo, inserimos 1 milhão de linhas para garantir uma resposta rápida. Ajuste a cláusula LIMIT ou a seleção de colunas para importar subconjuntos conforme necessário:
Inserção remota com o ClickHouse Local
clickhouse-local. No exemplo abaixo, lemos de um bucket do S3 e inserimos os dados no ClickHouse usando a função remote:
Para executar isso por uma conexão SSL segura, utilize a função
remoteSecure.Exportando dados
s3. Isso exigirá as permissões adequadas. Passamos as credenciais necessárias na solicitação, mas consulte a página Gerenciamento de credenciais para ver outras opções.
No exemplo simples abaixo, usamos a função de tabela como destino em vez de origem. Aqui, transmitimos 10.000 linhas da tabela trips para um bucket, especificando a compressão lz4 e o tipo de saída CSV:
s3 — isso pode ser inferido a partir do SELECT.
Dividindo arquivos grandes
INSERT várias vezes, cada vez visando um subconjunto dos dados. O ClickHouse oferece uma forma de dividir arquivos automaticamente usando uma chave PARTITION.
No exemplo abaixo, criamos dez arquivos usando o módulo da função rand(). Observe como o ID da partição resultante é referenciado no nome do arquivo. Isso resulta em dez arquivos com um sufixo numérico, por exemplo, trips_0.csv.lz4, trips_1.csv.lz4 etc…:
payment_type fornece uma chave de particionamento natural com cardinalidade 5.
Utilizando clusters
INSERT INTO SELECT, isso ainda deixa um único nó responsável por ler, analisar e processar os dados. Para enfrentar esse desafio e permitir o escalonamento horizontal das leituras, temos a função s3Cluster.
O nó que recebe a consulta, conhecido como iniciador, cria uma conexão com cada nó do cluster. O padrão glob que determina quais arquivos precisam ser lidos é expandido para um conjunto de arquivos. O iniciador distribui os arquivos entre os nós do cluster, que atuam como workers. Esses workers, por sua vez, solicitam arquivos para processar à medida que concluem as leituras. Esse processo garante que possamos escalar as leituras horizontalmente.
A função s3Cluster usa o mesmo formato das variantes de nó único, exceto que é necessário informar um cluster de destino para indicar os nós workers:
cluster_name— Nome de um cluster usado para montar um conjunto de endereços e parâmetros de conexão para servidores remotos e locais.source— URL para um arquivo ou um conjunto de arquivos. Suporta os seguintes curingas no modo somente leitura:*,?,{'abc','def'}e{N..M}, em que N, M — números; abc, def — strings. Para mais informações, consulte Wildcards In Path.access_key_idesecret_access_key— Chaves que especificam as credenciais a serem usadas com o endpoint informado. Opcional.format— O formato do arquivo.structure— Estrutura da tabela. Formato ‘column1_name column1_type, column2_name column2_type, …’.
s3, as credenciais são opcionais se o bucket for inseguro ou se você configurar a segurança por meio do ambiente, por exemplo, com IAM roles. Ao contrário da função s3, no entanto, a estrutura deve ser especificada na requisição a partir da versão 22.3.1, ou seja, o esquema não é inferido.
Na maioria dos casos, essa função será usada como parte de um INSERT INTO SELECT. Nesse caso, com frequência você estará inserindo em uma tabela distribuída. Abaixo, mostramos um exemplo simples em que trips_all é uma tabela distribuída. Embora essa tabela use o cluster events, a consistência dos nós usados para leituras e gravações não é um requisito:
s3cluster.
Motores de tabela S3
s3 permitam executar consultas ad hoc em dados armazenados no S3, sua sintaxe é verbosa. O motor de tabela S3 permite que você não precise especificar a URL do bucket e as credenciais repetidamente. Para resolver isso, o ClickHouse fornece o motor de tabela S3.
path— URL do bucket com o caminho para o arquivo. Oferece suporte aos seguintes curingas no modo somente leitura:*,?,{abc,def}e{N..M}, em que N e M são números, e ‘abc’ e ‘def’ são strings. Para mais informações, consulte aqui.format— O formato do arquivo.aws_access_key_id,aws_secret_access_key- Credenciais de longo prazo do usuário da conta AWS. Você pode usá-las para autenticar suas solicitações. O parâmetro é opcional. Se as credenciais não forem especificadas, serão usados os valores do arquivo de configuração. Para mais informações, consulte Gerenciamento de credenciais.compression— Tipo de compressão. Valores compatíveis: none, gzip/gz, brotli/br, xz/LZMA, zstd/zst. O parâmetro é opcional. Por padrão, a compressão será detectada automaticamente pela extensão do arquivo.
Leitura de dados
trips_raw usando os dez primeiros arquivos TSV localizados no bucket https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi/. Cada um deles contém 1 milhão de linhas:
{0..9} para limitar a seleção aos dez primeiros arquivos. Depois de criada, podemos consultar essa tabela como qualquer outra tabela:
Inserindo dados
S3 oferece suporte a leituras paralelas. As escritas só têm suporte se a definição da tabela não contiver padrões glob. Portanto, a tabela acima impediria escritas.
Para demonstrar escritas, crie uma tabela que aponte para um bucket do S3 com suporte a gravação:
- Especifique a configuração
s3_create_new_file_on_insert=1. Isso fará com que novos arquivos sejam criados a cada inserção. Um sufixo numérico será acrescentado ao final de cada arquivo e aumentará monotonicamente a cada operação de inserção. Para o exemplo acima, uma inserção subsequente causaria a criação de um arquivo trips_1.bin. - Especifique a configuração
s3_truncate_on_insert=1. Isso fará com que o arquivo seja truncado, ou seja, ele conterá apenas as linhas recém-inseridas quando a operação for concluída.
s3_truncate_on_insert terá precedência se ambas forem definidas.
Algumas observações sobre o motor de tabela S3:
- Ao contrário de uma tabela tradicional da família
MergeTree, remover uma tabelaS3não excluirá os dados subjacentes. - As configurações completas para esse tipo de tabela podem ser encontradas aqui.
- Tenha em mente as seguintes limitações ao usar este motor:
- Consultas ALTER não são compatíveis
- Operações SAMPLE não são compatíveis
- Não há conceito de índices, ou seja, primário ou de skip.
Gerenciando credenciais
s3 ou na definição da tabela S3. Embora isso possa ser aceitável para uso ocasional, em produção os usuários precisam de mecanismos de authentication menos explícitos. Para isso, o ClickHouse oferece várias opções:
-
Especifique os detalhes da connection em config.xml ou em um arquivo de configuração equivalente em conf.d. O conteúdo de um arquivo de exemplo é mostrado abaixo, considerando uma instalação com o pacote Debian.
Essas credenciais serão usadas para quaisquer solicitações em que o endpoint acima corresponda exatamente ao prefixo da URL solicitada. Observe também, neste exemplo, a possibilidade de declarar um cabeçalho de autorização como alternativa à chave de acesso e à chave secreta. Uma lista completa das configurações compatíveis pode ser encontrada aqui.
-
O exemplo acima destaca a disponibilidade do parâmetro de configuration
use_environment_credentials. Esse parâmetro de configuration também pode ser definido globalmente no nível des3:Essa configuração ativa a tentativa de obter credenciais do S3 a partir do ambiente, permitindo assim o acesso por meio de IAM roles. Especificamente, a seguinte ordem de obtenção é usada:- Busca pelas variáveis de ambiente
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEYeAWS_SESSION_TOKEN - Verificação em $HOME/.aws
- Credenciais temporárias obtidas por meio do AWS Security Token Service — ou seja, pela API
AssumeRole - Verificação de credenciais nas variáveis de ambiente do ECS
AWS_CONTAINER_CREDENTIALS_RELATIVE_URIouAWS_CONTAINER_CREDENTIALS_FULL_URIeAWS_ECS_CONTAINER_AUTHORIZATION_TOKEN. - Obtém as credenciais por meio dos metadados da instância do Amazon EC2, desde que AWS_EC2_METADATA_DISABLED não esteja definido como true.
- Essas mesmas configurações também podem ser definidas para um endpoint específico, usando a mesma regra de correspondência de prefixo.
- Busca pelas variáveis de ambiente
Otimização de desempenho
Ajuste do armazenamento S3
Wide e Compact. Embora a implementação atual use o comportamento padrão do ClickHouse (controlado pelas configurações min_bytes_for_wide_part e min_rows_for_wide_part), esperamos que esse comportamento seja diferente para o S3 em versões futuras, por exemplo, com um valor padrão maior para min_bytes_for_wide_part, favorecendo um formato mais Compact e, assim, menos arquivos. Neste momento, pode ser interessante ajustar essas configurações ao usar exclusivamente armazenamento S3.
MergeTree com backend em S3
s3 e o motor de tabela associado permitem consultar dados no S3 usando a sintaxe familiar do ClickHouse. No entanto, em termos de recursos de gerenciamento de dados e desempenho, eles são limitados. Não há suporte para índices primários, nem para no-cache, e as inserções de arquivos precisam ser gerenciadas pelo usuário.
O ClickHouse reconhece que o S3 é uma solução de armazenamento atraente, especialmente quando o desempenho das consultas em dados “mais frios” é menos crítico e os usuários buscam separar armazenamento e processamento. Para viabilizar isso, há suporte para usar o S3 como armazenamento de um engine MergeTree. Isso permite aproveitar a escalabilidade e as vantagens de custo do S3, além do desempenho de inserção e consulta do engine MergeTree.
Camadas de armazenamento
Criando um disco
use_environment_credentials pode ser definido como true no bloco de configurações acima para usar roles do IAM.
Criando uma política de armazenamento
Criando uma tabela
Modificando uma tabela
<path>. Observe que os nomes dos nossos volumes e discos não mudam. Novas inserções na nossa tabela permanecerão no disco padrão até que ele atinja move_factor * disk_size — momento em que os dados serão realocados para o S3.
Como lidar com a replicação
ReplicatedMergeTree. Consulte o guia replicando um único shard em duas Regiões da AWS usando armazenamento de objetos S3 para mais detalhes.
Leituras e gravações
- Por padrão, o número máximo de threads de processamento de consulta usadas por qualquer estágio do pipeline de processamento da consulta é igual ao número de núcleos. Alguns estágios são mais paralelizáveis do que outros, portanto esse valor define um limite superior. Vários estágios da consulta podem ser executados ao mesmo tempo, já que os dados são transmitidos do disco. Assim, o número exato de threads usadas por uma consulta pode exceder esse valor. Modifique isso por meio da configuração max_threads.
- As leituras no S3 são assíncronas por padrão. Esse comportamento é determinado pela configuração
remote_filesystem_read_method, definida com o valorthreadpoolpor padrão. Ao atender a uma solicitação, o ClickHouse lê grânulos em stripes. Cada uma dessas stripes pode conter muitas colunas. Uma thread lê as colunas dos respectivos grânulos, uma a uma. Em vez de fazer isso de forma síncrona, é feito um prefetch de todas as colunas antes de aguardar os dados. Isso oferece ganhos significativos de desempenho em comparação com a espera síncrona em cada coluna. Na maioria dos casos, você não precisará alterar essa configuração — veja otimização de desempenho. - As gravações são realizadas em paralelo, com no máximo 100 threads simultâneas de gravação de arquivos.
max_insert_delayed_streams_for_parallel_write, que tem valor padrão de 1000, controla o número de blobs do S3 gravados em paralelo. Como é necessário um buffer para cada arquivo gravado (~1MB), isso limita efetivamente o consumo de memória de um INSERT. Pode ser apropriado reduzir esse valor em cenários com pouca memória no servidor.
Use o armazenamento de objetos do S3 como disco do ClickHouse
Configure o ClickHouse para usar o bucket do S3 como disco
- Crie um novo arquivo no diretório
config.ddo ClickHouse para armazenar a configuração de armazenamento.
- Adicione o seguinte à configuração de armazenamento, substituindo pelo caminho do bucket, pela chave de acesso e pelas chaves secretas das etapas anteriores
As tags
s3_disk e s3_cache dentro da tag <disks> são rótulos arbitrários. Elas podem ser definidas de outra forma, mas o mesmo rótulo deve ser usado na tag <disk> dentro da tag <policies> para referenciar o disco.
A tag <S3_main> também é arbitrária e é o nome da política que será usada como identificador do destino de armazenamento ao criar recursos no ClickHouse.A configuração mostrada acima é para o ClickHouse versão 22.8 ou superior. Se você estiver usando uma versão mais antiga, consulte a documentação sobre armazenar dados.Para mais informações sobre como usar o S3:
Guia de integrações: S3 Backed MergeTree- Atualize o proprietário do arquivo para o usuário e o grupo
clickhouse
- Reinicie a instância do ClickHouse para que as alterações entrem em vigor.
Teste
- Faça login com o ClickHouse client, como no exemplo a seguir
- Crie uma tabela especificando a nova política de armazenamento de S3
- Verifique se a tabela foi criada com a política correta
- Insira linhas de teste na tabela
- Visualize as linhas
- No console da AWS, navegue até os buckets e selecione o novo bucket e a pasta. Você deverá ver algo como o seguinte:
Replicando um único shard entre duas regiões da AWS usando armazenamento de objetos S3
Planeje a implantação
Instale o software
Nós do servidor ClickHouse
Implantar o ClickHouse
chnode1 e chnode2.
Coloque chnode1 em uma região da AWS e chnode2 em outra.
Implante o ClickHouse Keeper
keepernode1, keepernode2 e keepernode3. O keepernode1 pode ser implantado na mesma região que chnode1, o keepernode2 com chnode2 e o keepernode3 em qualquer uma das regiões, mas em uma zona de disponibilidade diferente da do nó do ClickHouse nessa região.
Consulte as instruções de instalação ao executar as etapas de implantação nos nós do ClickHouse Keeper.
Crie buckets do S3
chnode1 e chnode2.
Se precisar de instruções passo a passo para criar buckets e uma função do IAM, expanda Criar buckets do S3 e uma função do IAM e siga as instruções:
Crie buckets do S3 e um usuário do IAM
Crie buckets do S3 e um usuário do IAM
Este artigo demonstra os conceitos básicos de como configurar um usuário do IAM da AWS, criar um bucket do S3 e configurar o ClickHouse para usar o bucket como um S3 disk.
Trabalhe com sua equipe de segurança para determinar as permissões a serem utilizadas e considere estas como ponto de partida.
Criar um usuário do IAM da AWS
Nos passos a seguir, você criará um usuário de service account (e não um usuário de login).- Faça login no Console de Gerenciamento do AWS IAM.
-
No menu
Users, selecioneCreate user
- Insira o nome de usuário, defina o tipo de credencial como
Access key - Programmatic accesse selecioneNext: Permissions
- Não adicione o usuário a nenhum grupo; selecione
Next: Tags
- A menos que precise adicionar tags, selecione
Next: Review
- Selecione
Create User
A mensagem de aviso informando que o usuário não tem permissões pode ser ignorada; as permissões para o usuário serão concedidas no bucket na próxima seção
- O usuário foi criado; clique em
showe copie a chave de acesso e a chave secreta.
Guarde as chaves em outro lugar; esta é a única vez em que a chave de acesso secreta estará disponível.
- Clique em Fechar e, em seguida, localize o usuário na tela de usuários.
- Copie o ARN (Amazon Resource Name) e salve-o para usar na configuração da política de acesso do bucket.
Criar um bucket do S3
- Na seção bucket do S3, selecione
Create bucket
- Insira um nome para o bucket e deixe as outras opções com os valores padrão
O nome do bucket deve ser único em toda a AWS, não apenas na organização, ou gerará um erro.
- Deixe
Block all Public Accessativado; o acesso público não é necessário.
- Selecione
Create Bucketno final da página
- Selecione o link, copie o ARN e salve-o para usá-lo ao configurar a política de acesso do bucket.
- Depois que o bucket for criado, localize o novo bucket do S3 na lista de buckets do S3 e selecione o link
- Selecione
Create folder
- Digite um nome para a pasta que será o destino do disco S3 do ClickHouse e selecione
Create folder
- A pasta agora deve aparecer na lista de buckets
- Selecione a caixa de seleção da nova pasta e clique em
Copy URL. Salve a URL copiada para usá-la na configuração de armazenamento do ClickHouse na próxima seção.
- Selecione a aba
Permissionse clique no botãoEditna seçãoBucket Policy
- Adicione uma política de bucket, conforme o exemplo abaixo:
Você deve trabalhar com sua equipe de segurança para determinar as permissões a serem usadas; considere-as como um ponto de partida.
Para mais informações sobre políticas e configurações, consulte a documentação da AWS:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-language-overview.html
- Salve a configuração da política.
/etc/clickhouse-server/config.d/. Aqui está um arquivo de configuração de exemplo para um bucket; o outro é semelhante, com diferença apenas nas três linhas destacadas:
/etc/clickhouse-server/config.d/storage_config.xml
Muitas das etapas deste guia pedirão que você coloque um arquivo de configuração em
/etc/clickhouse-server/config.d/. Este é o local padrão, em sistemas Linux, para arquivos de substituição de configuração. Quando você colocar esses arquivos nesse diretório, o ClickHouse usará esse conteúdo para substituir a configuração padrão. Ao colocar esses arquivos no diretório de substituição, você evitará perder a configuração durante uma atualização.Configurar o ClickHouse Keeper
/etc/clickhouse-keeper/keeper_config.xml. Todos os três servidores Keeper usam a mesma configuração, com apenas uma diferença: <server_id>.
server_id indica o ID a ser atribuído ao host em que o arquivo de configuração é usado. No exemplo abaixo, o server_id é 3 e, se você olhar mais abaixo no arquivo, na seção <raft_configuration>, verá que o servidor 3 tem o hostname keepernode3. É assim que o processo do ClickHouse Keeper sabe a quais outros servidores deve se conectar ao eleger um líder e executar todas as demais atividades.
/etc/clickhouse-keeper/keeper_config.xml
<server_id>):
Configurar o servidor ClickHouse
Defina um cluster
<remote_servers> da configuração. Neste exemplo, é definido um cluster, cluster_1S_2R, composto por um único shard com duas réplicas. As réplicas estão localizadas nos hosts chnode1 e chnode2.
/etc/clickhouse-server/config.d/remote-servers.xml
shard e replica. Ao criar uma tabela, você pode ver como as macros shard e replica são usadas consultando system.tables.
/etc/clickhouse-server/config.d/macros.xml
As macros acima são para
chnode1; no chnode2, defina replica como replica_2.Desativar a replicação zero-copy
allow_remote_fs_zero_copy_replication é definida como true por padrão para discos S3 e HDFS. Para este cenário de recuperação de desastres, essa configuração deve ser definida como false; na versão 22.8 e posteriores, ela já é definida como false por padrão.
Essa configuração deve ser false por dois motivos: 1) esse recurso ainda não está pronto para produção; 2) em um cenário de recuperação de desastres, tanto os dados quanto os metadados precisam ser armazenados em múltiplas regiões. Defina allow_remote_fs_zero_copy_replication como false.
/etc/clickhouse-server/config.d/remote-servers.xml
/etc/clickhouse-server/config.d/use_keeper.xml
Configurar a rede
/etc/clickhouse-server/config.d/. Aqui está um exemplo que configura o ClickHouse e o ClickHouse Keeper para escutar em todas as interfaces IPv4. Consulte a documentação ou o arquivo de configuração padrão /etc/clickhouse/config.xml para mais informações.
/etc/clickhouse-server/config.d/networking.xml
Inicie os servidores
Inicie o ClickHouse Keeper
Verifique o status do ClickHouse Keeper
netcat. Por exemplo, mntr retorna o estado do cluster do ClickHouse Keeper. Se você executar o comando em cada um dos nós do Keeper, verá que um deles é o leader e os outros dois são followers:
Inicie o servidor ClickHouse
Verifique o servidor ClickHouse
-
Verifique se o cluster existe:
-
Crie uma tabela no cluster usando o mecanismo de tabela
ReplicatedMergeTree: -
Entenda o uso das macros definidas anteriormente
As macros
shardereplicaforam definidas anteriormente, e na linha destacada abaixo você pode ver onde os valores são substituídos em cada nó do ClickHouse. Além disso, o valoruuidé usado;uuidnão é definido nas macros, pois é gerado pelo sistema.
Você pode personalizar o caminho do ZooKeeper
'clickhouse/tables/{uuid}/{shard} mostrado acima definindo default_replica_path e default_replica_name. A documentação está aqui.Teste
-
Adicione dados do conjunto de dados de táxis da cidade de Nova York:
-
Verifique se os dados estão armazenados no S3.
Esta consulta mostra o tamanho dos dados em disco e a política usada para determinar qual disco será utilizado.
Verifique o tamanho dos dados no disco local. Como mostrado acima, o tamanho em disco dos milhões de linhas armazenadas é 36.42 MiB. Isso deve estar no S3, e não no disco local. A consulta acima também informa onde os dados e os metadados estão armazenados no disco local. Verifique os dados locais:Verifique os dados no S3 em cada bucket do S3 (os totais não são mostrados, mas ambos os buckets têm aproximadamente 36 MiB armazenados após as inserções):
S3Express
O S3Express armazena dados em uma única AZ. Isso significa que os dados ficarão indisponíveis em caso de falha da AZ.
Disco S3
- Crie um bucket do tipo
Directory - Aplique a política de bucket apropriada para conceder todas as permissões necessárias ao seu usuário do S3 (por exemplo,
"Action": "s3express:*"para simplesmente permitir acesso irrestrito) - Ao configurar a política de armazenamento, forneça o parâmetro
region
Armazenamento S3
Object URL. Exemplo: