Amministrazione di ClickHouse

ClickHouse e' un potente Columnar Database SQL, distribuito ed Open Source con ottime prestazioni sulle attivita' OLAP (On-Line Analytical Processing).
In questa paginetta ne vediamo gli aspetti piu' utili per l'amministrazione di ClickHouse da parte di un DBA.

Questa pagina si riferisce alla versione 20.2 o successive di ClickHouse perche' sono stati introdotti notevoli cambiamenti in tale versione relativi all'amministrazione del database.
Le funzionalita' di ClickHouse sono cresciute in modo molto significativo ed precedenza molte configurazioni venivano effettuate su file .XML mentre ora sono presenti comandi SQL... e' arrivato il momento di raccogliere i principali strumenti e comandi per il DBA.

Gli argomenti contenuti in questa pagina sono: Architettura, Amministrazione ( utenti, profili, quota, autorizzazioni, gestione spazio, logging, Data Dictionary, configurazione, ) Database Design, ...

Architettura

ClickHouse (CH) e' un database column-oriented. Questo significa che i dati non sono organizzati per righe, come avviene per tutti i database relazionali tradizionali; i dati sono memorizzati su un file per ogni colonna, organizzati come in un indice e compressi.

Oltre all'organizzazione per colonne ed alla compressione ClickHouse utilizza algoritmi di calcolo parallelo ed effettua automaticamente il partizionamento.
Quando si effettua una query ClickHouse suddivide il lavoro in piu' thread ed effettua le operazioni in memoria utilizzando tutte le CPU e tutta la RAM disponibili. Questo rende incredibilmente piu' veloci le ricerche rispetto ad un DB tradizionale sopratutto quando vanno analizzate grandi quantita' di dati. ClickHouse risulta anche particolamente veloce rispetto ad altri database analitici perche' ha prestazioni quasi real time nelle query semplici.

ClickHouse e' costituito da un solo processo clickhouse-server ma internamente sono presenti decine di thread che operano in modo indipendente. Le principali porte socket utilizzate sono: 9000 interfaccia nativa utilizzata dal protocollo interno tra client e server CH, 8123 accesso HTTP, 9004 utilizzata per la replica dati. E' possibile utilizzare anche altre porte... ad esempio si puo' utilizzare la 3306 per far accedere a ClickHouse da client MySQL.

Per ogni tabella e' possibile scegliere un tipo di memorizzazione dei dati: l'Engine.
Vi sono diverse tipologie di Engine, il piu' importante e' il MergeTree ed i suoi derivati. Con il MergeTree i dati sono ordinati per Primary Key e viene eseguito il pruning delle query sulla partitioning key. In fase di inserimento i dati vengono scritti velocemente in parti (parts) e quindi uniti (merge) successivamente da un thread asincrono. Gli inserimenti non bloccano mai le query, che vengono eseguite sulle parts attive.
L'intruzione fondamentale e' la SELECT che consente join e subquery, la INSERT vie ottimizzata effettuando in batch gli inserimenti ed i successivi merge. Le UPDATE e DELETE in ClickHouse hanno la sintassi ALTER TABLE, poiche' sono DDL e non DML, vengono chiamate mutation e vanno usate solo in casi particolari.

Dal punto di vista dell'utilizzo ClickHouse ha un'interfaccia SQL molto vicina al dialetto MySQL anche se piu' precisa nel trattamento dei datatypes e delle conversioni; dal punto di vista dell'amministrazione...

Amministrazione

Le attivita' in corso sul sistema si controllano con: SHOW PROCESSLIST e l'elenco delle tabelle ed i loro dettagli si analizzano con i comandi: SHOW DATABASES; USE database; SHOW TABLES; SHOW CREATE TABLE table; ma le analogie con MySQL si fermano a questo punto, anche perche' il disegno della base dati e' molto differente per gli OLAP.

Vediamo ora in dettaglio tutti i comandi di amministrazione del database ClickHouse.

Utenti

Gli utenti vengono definti con uno specifico statement DCL:

CREATE USER [IF NOT EXISTS | OR REPLACE] name
  [IDENTIFIED [WITH {NO_PASSWORD|PLAINTEXT_PASSWORD|SHA256_PASSWORD|SHA256_HASH|DOUBLE_SHA1_PASSWORD|DOUBLE_SHA1_HASH}] BY {'password'|'hash'}]
  [HOST {LOCAL | NAME 'name' | NAME REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
  [PROFILE 'profile_name']

La password puo' essere indicata in chiaro o crittografata. In ogni caso verra' memorizzata in forma crittografata. L'hash si ottiene con:
 echo -n "MyPass" | sha256sum | tr -d '-'
 echo -n "MyPass" | sha1sum | tr -d '-'| xxd -r -p | sha1sum | tr -d '-'

E' possibile limitare l'accesso di un utente a seconda della provenienza impostando la clausola HOST.

Ad un utente viene associato un profilo che ne imposta le caratteristiche.

Nelle versioni precedenti le utenze erano configurate nel file /etc/clickhouse-server/users.xml indicando il nome dell'utente e la password, l'assegnazione di un profilo (eg. default, readonly) ed eventualmente l'allow_databases.

Profili e settings

Un utente ClickHouse ha sempre un profile. Il profilo di default e' tipicamente molto libero ma e' possibile creare profile per definire un insieme molto ampio di impostazioni (setting) [NdA anzi gli insiemi sono due].

Con l'impostazione di un profilo e' possibile limitare la complessita' delle richieste sulle singole query per ogni tipologia di utente.

Quota

Per default il quota registra l'utilizzo di risorse (eg. durata) per un ora senza limitarne l'utilizzo. E' tuttavia possibile definire un periodo di tempo diverso ed un limite per risorsa.
Le risorse possono essere:

Autorizzazioni

Agli utenti vengono assegnate/revocate specifiche autorizzazioni:

GRANT access_type[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} TO user_name
REVOKE access_type[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} TO user_name

I privilegi assegnabili sono molto dettagliati (cfr. AccessType.h), vediamo qualche esempio: NONE, ALL, SHOW, SELECT, INSERT, UPDATE, DELETE, CREATE_TABLE, ADD_COLUMN, COMMENT_COLUMN, CREATE_USER, SHUTDOWN, STOP_MERGES, RESTART_REPLICA, mysql, ...

Gestione dello spazio

Ovviamente su una base dati analitica la gestione degli spazi e' fondamentale perche' la grande quantita' di dati lo impone.

Il primo grosso vantaggio di CH e' che comprime in modo molto significativo i dati. La compressione dei default (LZ4) e' automatica ma possibile e' configurabile sia la codifica che la successiva compressione dei dati per singola colonna.
La verifica della quantita' di spazio risparmiato si effettua con:

SELECT database, table, column, type,
       column_data_compressed_bytes compressed,
       column_data_uncompressed_bytes,
       (column_data_uncompressed_bytes-column_data_compressed_bytes)*100/column_data_uncompressed_bytes ratio
  FROM system.parts_columns
 WHERE active
   AND database<>'system'
   AND column_data_uncompressed_bytes>0
 ORDER BY database, table, column;

CH utilizza gli statement standard di TRUNCATE e DROP sia a livello di tabella che di partizione. Il partizionamento consigliato e': PARTITION BY toYYYYMM(Date Column) e comunque non e' consigliabile utilizza migliaia di partizioni perche' inefficiente. Naturalmente possono essere cancellate le partizioni con i dati da storicizzare, il comando e'

:) ALTER TABLE big_table DROP PARTITION 201806;

Un parametro molto utile nella creazione di una tabella e' il TTL (Time To Live) ovvero la retention automatica del dato. Puo' essere impostato a livello di tabella e/o di singola colonna: viene applicato il primo che scade. La cancellazione non e' immediata ma avviene solo in fase di merge delle Part. Un esempio di impostazione e':

CREATE TABLE iot_data(
  timestamp DateTime, 
  device String, 
...
  value UInt32)
 ENGINE = MergeTree 
 PARTITION BY toYYYYMM(timestamp)
 ORDER BY (timestamp, device)
 TTL timestamp + toIntervalMonth(6)
 SETTINGS index_granularity = 8192;

Anche se con le ultime versioni sarebbe tecnicamente possibile... e' comunque sconsigliabile effettuare cancellazioni con la DELETE [NdA che in ClickHouse la sintassi e' ALTER TABLE ... DELETE]. In effetti una mutation prima occupa piu' spazio e, se tutto va bene, lo libera dopo "lentamente" ma sopratutto e' molto meno efficiente.

Per sicurezza non e' possibile cancellare oggetti piu' grandi di 50GB, in effetti ricaricarli puo' essere impegnativo... Per farlo o si crea un file con touch /home/clickhouse/flags/force_drop_table oppure si imposta a 0 il parametro max_[table/partition]_size_to_drop [NdA meglio il touch del file, il controllo e' utile].

Logging e tracing

Il log e' mantenuto nel file /var/log/clickhouse-server/clickhouse-server.log che contiene eventuali errori e segnalazioni. Il livello di dettaglio e' definito nella sezione <logger> ed il default e' trace [NdA in effetti un po' elevato si puo' abbassare a information. I livelli disponibili sono: trace, debug, information, notice, warning, error, critical, fatal, none]. Il file /var/log/clickhouse-server/clickhouse-server.err.log contiene solo gli errori, con i relativi stack trace, ed e' di dimesioni piu' ridotte.

La destinazione del trace di tutte le query e dei thread eseguiti e' definita per default ma vengono tracciate solo le sessioni che hanno impostato esplicitamente log_queries=1. Per impostare il tracing per tutti gli accessi [NdA consigliabile su un sistema di produzione] si puo' configurare come segue il profilo di default nel file users.xml:

<?xml version="1.0"?> <yandex> <!-- Profiles of settings. --> <profiles> <!-- Default settings. --> <default> <!-- Query logging. --> <log_queries>1</log_queries> <!-- Maximum memory usage for processing single query, in bytes. --> <max_memory_usage>10000000000</max_memory_usage> ...

A differenza di un OLTP con un OLAP il tracing di tutti gli accessi non e' eccessivo [NdA CH non effettua il logging delle INSERT].
Se si vuole monitorare l'intero cluster e' possibile utilizzare una tabella distribuita:

CREATE TABLE IF NOT EXISTS system.query_log_all
  ON CLUSTER ClusterName
  AS system.query_log
  ENGINE = Distributed(ClusterName, system, query_log, rand());

E' anche possibile monitorare tutte le attivita' sulle Parts, abilitando la sezione <part_log>. Per default e' disabilitata anche perche' le attivita' sulle Parts sono molto frequenti in CH.

Sul client e' possibile abilitare il logging della sessione con set send_logs_level='trace'. E' molto dettagliato e, anche se non fornisce un vero query plan, e' molto utile anche per l'ottimizzazione delle query.

Data Dictionary

E' disponibile un completo Data Dictionary, nel database system, che contiene gli oggetti definiti (eg. tables, columns, parts), le attivita' (eg. processes, merges), ...
L'accesso in lettura a system e' disponibile per tutti gli utenti.

Sono particolarmente importanti per il monitoraggio le seguenti tabelle: system.metrics, system.events e system.asynchronous_metrics [NdE oltre alla gia' citata system.parts]. CH puo' esportare le metriche su Graphite.

Comandi amministrativi

Sono disponibili i truculenti comandi KILL QUERY (eg KILL QUERY where query_id = 'xxx' dove il query_id si ottiene con SHOW PROCESSLIST) e KILL MUTATION. Il primo uccide le query, il secondo uccide le DELETE e le UPDATE che, in ClickHouse, sono comandi di ALTER ed eseguiti in modo asincrono.

Varie ed eventuali

Il documento Introduzione a ClickHouse contiene una presentazione sulle funzioni di base, il documento Architettura ClickHouse riporta i principali aspetti dell'architettura mentre DBA scripts contiene alcuni dei comandi piu' utili per il DBA.


Titolo: Amministrazione di ClickHouse
Livello: Medio (2/5)
Data: 1 Aprile 2020
Versione: 1.0.0 - 1 Aprile 2020 🐟
© Autore: mail [AT] meo.bogliolo.name