O ClickHouse reconhece que o GCS é uma solução de armazenamento atraente para quem busca separar armazenamento e capacidade computacional. Para viabilizar isso, há suporte ao uso do GCS como armazenamento para um engine MergeTree. Isso permite aproveitar a escalabilidade e os benefícios de custo do GCS, além do desempenho de inserção e consulta do engine MergeTree.
MergeTree com armazenamento em GCS
Criando um disco
Para usar um GCS bucket como disco, primeiro precisamos declará-lo na configuração do ClickHouse em um arquivo dentro de conf.d. Um exemplo de declaração de um disco GCS é mostrado abaixo. Esta configuração inclui várias seções para configurar o "disco" GCS, o cache e a política especificada nas consultas DDL quando as tabelas forem criadas no disco GCS. Cada uma delas é descrita abaixo.
Configuração de armazenamento > disks > gcs
Esta parte da configuração é mostrada na seção destacada e especifica que:
- O tipo do disco é
s3, porque a API S3 está em uso. - O endpoint fornecido pelo GCS
- A chave HMAC e o segredo da conta de serviço
- O caminho dos metadados no disco local
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Configuração de armazenamento > disks > cache
A configuração de exemplo destacada abaixo ativa um cache em memória de 10Gi para o disco gcs.
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
<gcs_cache>
<type>cache</type>
<disk>gcs</disk>
<path>/var/lib/clickhouse/disks/gcs_cache/</path>
<max_size>10Gi</max_size>
</gcs_cache>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs_cache</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Configuração de armazenamento > políticas > gcs_main
As políticas de configuração de armazenamento permitem escolher onde os dados serão armazenados. A política destacada abaixo permite armazenar dados no disco gcs ao especificar a política gcs_main. Por exemplo, CREATE TABLE ... SETTINGS storage_policy='gcs_main'.
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Uma lista completa das configurações relevantes para esta definição de disco pode ser encontrada aqui.
Criando uma tabela
Supondo que você tenha configurado o disco para usar um bucket com acesso de gravação, você deverá conseguir criar uma tabela como no exemplo abaixo. Para ser breve, usamos um subconjunto das colunas de táxi de NYC e enviamos os dados diretamente para a tabela com armazenamento no GCS:
CREATE TABLE trips_gcs
(
`trip_id` UInt32,
`pickup_date` Date,
`pickup_datetime` DateTime,
`dropoff_datetime` DateTime,
`pickup_longitude` Float64,
`pickup_latitude` Float64,
`dropoff_longitude` Float64,
`dropoff_latitude` Float64,
`passenger_count` UInt8,
`trip_distance` Float64,
`tip_amount` Float32,
`total_amount` Float32,
`payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'INSERT INTO trips_gcs SELECT trip_id, pickup_date, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, passenger_count, trip_distance, tip_amount, total_amount, payment_type FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', NOSIGN, 'TabSeparatedWithNames') LIMIT 1000000;Dependendo do hardware, essa última operação de inserção de 1m de linhas pode levar alguns minutos para ser executada. Você pode acompanhar o progresso por meio da tabela system.processes. Sinta-se à vontade para ajustar a contagem de linhas até o limite de 10m e explorar algumas consultas de exemplo.
SELECT passenger_count, avg(tip_amount) AS avg_tip, avg(total_amount) AS avg_amount FROM trips_gcs GROUP BY passenger_count;Como lidar com a replicação
A replicação com discos GCS pode ser feita usando o mecanismo de tabela ReplicatedMergeTree. Consulte o guia replicando um único shard em duas regiões do GCP usando GCS para mais detalhes.
Saiba mais
A API XML do Cloud Storage é interoperável com algumas ferramentas e bibliotecas que funcionam com serviços como o Amazon Simple Storage Service (Amazon S3).
Para mais informações sobre o ajuste das threads, consulte Otimização de desempenho.
Usando Google Cloud Storage (GCS)
Planeje a implantação
Este tutorial foi escrito para descrever uma implantação replicada do ClickHouse em execução no Google Cloud e usando o Google Cloud Storage (GCS) como "tipo" de disco de armazenamento do ClickHouse.
Neste tutorial, você implantará nós do servidor ClickHouse em VMs do Google Cloud Engine, cada um com um bucket do GCS associado para armazenamento. A replicação é coordenada por um conjunto de nós do ClickHouse Keeper, também implantados como VMs.
Exemplo de requisitos para alta disponibilidade:
- Dois nós do servidor ClickHouse, em duas regiões do GCP
- Dois buckets do GCS, implantados nas mesmas regiões dos dois nós do servidor ClickHouse
- Três nós do ClickHouse Keeper, dois deles implantados nas mesmas regiões dos nós do servidor ClickHouse. O terceiro pode ficar na mesma região de um dos dois primeiros nós do Keeper, mas em uma zona de disponibilidade diferente.
O ClickHouse Keeper requer dois nós para funcionar; por isso, são necessários três nós para garantir alta disponibilidade.
Preparar máquinas virtuais
Implante cinco VMs em três regiões:
| Região | Servidor ClickHouse | bucket | ClickHouse Keeper |
|---|---|---|---|
| 1 | chnode1 |
bucket_regionname |
keepernode1 |
| 2 | chnode2 |
bucket_regionname |
keepernode2 |
3 * |
keepernode3 |
* Pode ser uma zona de disponibilidade diferente na mesma região que a 1 ou a 2.
Implantar o ClickHouse
Implante o ClickHouse em dois hosts; nas configurações de exemplo, eles são chamados de chnode1 e chnode2.
Coloque o chnode1 em uma região do GCP e o chnode2 em outra. Neste guia, us-east1 e us-east4 são usados para as VMs do Compute Engine e também para os buckets do GCS.
Consulte as instruções de instalação ao executar as etapas de implantação nos nós do servidor ClickHouse.
Implantar o ClickHouse Keeper
Implante o ClickHouse Keeper em três hosts; nas configurações de exemplo, eles são chamados de keepernode1, keepernode2 e keepernode3. O keepernode1 pode ser implantado na mesma região que o chnode1, o keepernode2 junto com o 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.
Criar dois buckets
Os dois servidores ClickHouse ficarão em regiões diferentes para garantir alta disponibilidade. Cada um terá um bucket do GCS na mesma região.
Em Cloud Storage > Buckets, escolha CREATE BUCKET. Para este tutorial, serão criados dois buckets, um em cada uma das regiões us-east1 e us-east4. Os buckets são de região única, com classe de armazenamento padrão, e não são públicos. Quando solicitado, ative a prevenção de acesso público. Não crie pastas; elas serão criadas quando o ClickHouse gravar no armazenamento.
Se precisar de instruções passo a passo para criar buckets e uma chave HMAC, expanda Criar buckets do GCS e uma chave HMAC e siga as instruções:
Criar buckets do GCS e uma chave HMAC
ch_bucket_us_east1

ch_bucket_us_east4

Gerar uma chave de acesso
Criar uma chave HMAC e um segredo para uma conta de serviço
Abra Cloud Storage > Settings > Interoperability e escolha uma chave de acesso existente ou CREATE A KEY FOR A SERVICE ACCOUNT. Este guia aborda o processo de criar uma nova chave para uma nova conta de serviço.

Adicionar uma nova conta de serviço
Se este for um projeto sem nenhuma conta de serviço existente, clique em CREATE NEW ACCOUNT.

Há três etapas para criar a conta de serviço. Na primeira, dê à conta um nome, ID e descrição significativos.

Na caixa de diálogo de configurações de Interoperability, recomenda-se a IAM role Storage Object Admin; selecione essa função na segunda etapa.

A terceira etapa é opcional e não é usada neste guia. Você pode permitir que usuários tenham esses privilégios com base nas suas políticas.

A chave HMAC da conta de serviço será exibida. Salve essas informações, pois elas serão usadas na configuração do ClickHouse.

Configurar o ClickHouse Keeper
Todos os nós do ClickHouse Keeper têm o mesmo arquivo de configuração, exceto pela linha server_id (a primeira linha destacada abaixo). Modifique o arquivo com os hostname dos seus servidores ClickHouse Keeper e, em cada servidor, defina o server_id para corresponder à entrada server adequada em raft_configuration. Como, neste exemplo, o server_id está definido como 3, destacamos as linhas correspondentes em raft_configuration.
- Edite o arquivo com os hostname e certifique-se de que eles possam ser resolvidos a partir dos nós do servidor ClickHouse e dos nós do Keeper
- Copie o arquivo para o local correto (
/etc/clickhouse-keeper/keeper_config.xmlem cada um dos servidores Keeper) - Edite o
server_idem cada máquina com base no número da respectiva entrada emraft_configuration
<clickhouse>
<logger>
<level>trace</level>
<log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
<errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</logger>
<listen_host>0.0.0.0</listen_host>
<keeper_server>
<tcp_port>9181</tcp_port>
<server_id>3</server_id>
<log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
<coordination_settings>
<operation_timeout_ms>10000</operation_timeout_ms>
<session_timeout_ms>30000</session_timeout_ms>
<raft_logs_level>warning</raft_logs_level>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>Configurar o servidor ClickHouse
Rede
Por padrão, o ClickHouse escuta na interface loopback; em uma configuração replicada, é necessária conectividade de rede entre as máquinas. Configure-o para escutar em todas as interfaces:
<clickhouse>
<listen_host>0.0.0.0</listen_host>
</clickhouse>Servidores remotos do ClickHouse Keeper
A replicação é coordenada pelo ClickHouse Keeper. Este arquivo de configuração identifica os nós do ClickHouse Keeper pelo hostname e pelo número da porta.
- Edite os hostnames para corresponder aos hosts do seu Keeper
<clickhouse>
<zookeeper>
<node index="1">
<host>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</host>
<port>9181</port>
</node>
<node index="2">
<host>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</host>
<port>9181</port>
</node>
<node index="3">
<host>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</host>
<port>9181</port>
</node>
</zookeeper>
</clickhouse>Servidores remotos do ClickHouse
Este arquivo configura o hostname e a porta de cada servidor ClickHouse no cluster. O arquivo de configuração padrão contém definições de cluster de exemplo; para exibir apenas os clusters totalmente configurados, a tag replace="true" é adicionada à entrada remote_servers, de modo que, quando essa configuração for combinada com a padrão, ela substitua a seção remote_servers em vez de ser acrescentada a ela.
- Edite o arquivo com seus hostnames e certifique-se de que eles possam ser resolvidos a partir dos nós do servidor ClickHouse
<clickhouse>
<remote_servers replace="true">
<cluster_1S_2R>
<shard>
<replica>
<host>chnode1.us-east1-b.c.clickhousegcs-374921.internal</host>
<port>9000</port>
</replica>
<replica>
<host>chnode2.us-east4-c.c.clickhousegcs-374921.internal</host>
<port>9000</port>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>
</clickhouse>Identificação da réplica
Este arquivo configura ajustes relacionados ao caminho do ClickHouse Keeper. Especificamente, as macros usadas para identificar a qual réplica os dados pertencem. Em um servidor, a réplica deve ser especificada como replica_1 e, no outro, como replica_2. Os nomes podem ser alterados; com base no nosso exemplo de uma réplica armazenada na Carolina do Sul e a outra no norte da Virgínia, os valores poderiam ser carolina e virginia; apenas certifique-se de que eles sejam diferentes em cada máquina.
<clickhouse>
<distributed_ddl>
<path>/clickhouse/task_queue/ddl</path>
</distributed_ddl>
<macros>
<cluster>cluster_1S_2R</cluster>
<shard>1</shard>
<replica>replica_1</replica>
</macros>
</clickhouse>Armazenamento no GCS
A configuração de armazenamento do ClickHouse inclui disks e policies. O disco configurado abaixo se chama gcs e é do type s3. O tipo é s3 porque o ClickHouse acessa o bucket do GCS como se fosse um bucket do S3 da AWS. Serão necessárias duas cópias dessa configuração, uma para cada nó do servidor ClickHouse.
As substituições a seguir devem ser feitas na configuração abaixo.
Estas substituições diferem entre os dois nós do servidor ClickHouse:
REPLICA 1 BUCKETdeve ser definido como o nome do bucket na mesma região do servidorREPLICA 1 FOLDERdeve ser alterado parareplica_1em um dos servidores e parareplica_2no outro
Estas substituições são comuns aos dois nós:
access_key_iddeve ser definido como a chave HMAC gerada anteriormentesecret_access_keydeve ser definido como o segredo HMAC gerado anteriormente
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>true</support_batch_delete>
<type>s3</type>
<endpoint>https://storage.googleapis.com/REPLICA 1 BUCKET/REPLICA 1 FOLDER/</endpoint>
<access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
<secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
<metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
</gcs>
<cache>
<type>cache</type>
<disk>gcs</disk>
<path>/var/lib/clickhouse/disks/gcs_cache/</path>
<max_size>10Gi</max_size>
</cache>
</disks>
<policies>
<gcs_main>
<volumes>
<main>
<disk>gcs</disk>
</main>
</volumes>
</gcs_main>
</policies>
</storage_configuration>
</clickhouse>Inicie o ClickHouse Keeper
Use os comandos do seu sistema operacional, por exemplo:
sudo systemctl enable clickhouse-keeper
sudo systemctl start clickhouse-keeper
sudo systemctl status clickhouse-keeperVerifique o status do ClickHouse Keeper
Envie comandos ao ClickHouse Keeper com 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 líder e os outros dois são seguidores:
echo mntr | nc localhost 9181zk_version v22.7.2.15-stable-f843089624e8dd3ff7927b8a125cf3a7a769c069
zk_avg_latency 0
zk_max_latency 11
zk_min_latency 0
zk_packets_received 1783
zk_packets_sent 1783
zk_num_alive_connections 2
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 135
zk_watch_count 8
zk_ephemerals_count 3
zk_approximate_data_size 42533
zk_key_arena_size 28672
zk_latest_snapshot_size 0
zk_open_file_descriptor_count 182
zk_max_file_descriptor_count 18446744073709551615
zk_followers 2
zk_synced_followers 2Inicie o servidor ClickHouse
Em chnode1 e chnode, execute:
sudo service clickhouse-server startsudo service clickhouse-server statusVerificação
Verifique a configuração dos discos
system.disks deve conter entradas para cada disco:
- default
- gcs
- cache
SELECT *
FROM system.disks
FORMAT VerticalRow 1:
──────
name: cache
path: /var/lib/clickhouse/disks/gcs/
free_space: 18446744073709551615
total_space: 18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space: 0
type: s3
is_encrypted: 0
is_read_only: 0
is_write_once: 0
is_remote: 1
is_broken: 0
cache_path: /var/lib/clickhouse/disks/gcs_cache/
Row 2:
──────
name: default
path: /var/lib/clickhouse/
free_space: 6555529216
total_space: 10331889664
unreserved_space: 6555529216
keep_free_space: 0
type: local
is_encrypted: 0
is_read_only: 0
is_write_once: 0
is_remote: 0
is_broken: 0
cache_path:
Row 3:
──────
name: gcs
path: /var/lib/clickhouse/disks/gcs/
free_space: 18446744073709551615
total_space: 18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space: 0
type: s3
is_encrypted: 0
is_read_only: 0
is_write_once: 0
is_remote: 1
is_broken: 0
cache_path:
3 rows in set. Elapsed: 0.002 sec.Verifique se as tabelas criadas no cluster existem em ambos os nós
create table trips on cluster 'cluster_1S_2R' (
`trip_id` UInt32,
`pickup_date` Date,
`pickup_datetime` DateTime,
`dropoff_datetime` DateTime,
`pickup_longitude` Float64,
`pickup_latitude` Float64,
`dropoff_longitude` Float64,
`dropoff_latitude` Float64,
`passenger_count` UInt8,
`trip_distance` Float64,
`tip_amount` Float32,
`total_amount` Float32,
`payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4))
ENGINE = ReplicatedMergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.us-east4-c.c.gcsqa-375100.internal │ 9000 │ 0 │ │ 1 │ 1 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.us-east1-b.c.gcsqa-375100.internal │ 9000 │ 0 │ │ 0 │ 0 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
2 rows in set. Elapsed: 0.641 sec.Verifique se é possível inserir dados
INSERT INTO trips SELECT
trip_id,
pickup_date,
pickup_datetime,
dropoff_datetime,
pickup_longitude,
pickup_latitude,
dropoff_longitude,
dropoff_latitude,
passenger_count,
trip_distance,
tip_amount,
total_amount,
payment_type
FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', NOSIGN, 'TabSeparatedWithNames')
LIMIT 1000000Verifique se a política de armazenamento gcs_main está sendo usada pela tabela.
SELECT
engine,
data_paths,
metadata_path,
storage_policy,
formatReadableSize(total_bytes)
FROM system.tables
WHERE name = 'trips'
FORMAT VerticalRow 1:
──────
engine: ReplicatedMergeTree
data_paths: ['/var/lib/clickhouse/disks/gcs/store/631/6315b109-d639-4214-a1e7-afbd98f39727/']
metadata_path: /var/lib/clickhouse/store/e0f/e0f3e248-7996-44d4-853e-0384e153b740/trips.sql
storage_policy: gcs_main
formatReadableSize(total_bytes): 36.42 MiB
1 row in set. Elapsed: 0.002 sec.Verifique no console do Google Cloud
Ao examinar os buckets, você verá que foi criada uma pasta em cada bucket com o nome usado no arquivo de configuração storage.xml. Expanda as pastas e você verá vários arquivos, que representam as partições de dados.
Bucket da réplica um

Bucket da réplica 2
