Perte de données dans ClickHouse : Déduplication et vues matérialisées
Dans ClickHouse, lors de l'utilisation de vues matérialisées, les données de la table cible peuvent ne pas correspondre à celles de la source. Cela se produit en raison de la déduplication de blocs pendant INSERT, en particulier dans les clusters répliqués. La configuration par défaut fait que les blocs sont ignorés lors d'insertions répétées, ce qui va à l'encontre des attentes d'un stockage append-only. La solution consiste à ajuster les paramètres insert_deduplicate et deduplicate_blocks_in_dependent_materialized_views.
Voici un pipeline typique :
CREATE TABLE source_table (
message String
) engine=MergeTree()
ORDER BY (message);
CREATE TABLE final_table (
message String
) engine=MergeTree()
ORDER BY (message);
CREATE MATERIALIZED VIEW mv_source_table TO final_table AS
SELECT
message
FROM source_table;
Les données de source_table sont copiées vers final_table, mais avec le temps, des enregistrements disparaissent de final_table sans raison apparente.
Atomicité des INSERT en détail
ClickHouse divise les données INSERT en blocs en fonction du paramètre max_insert_block_size. L'atomicité n'est garantie que pour un seul bloc dans une partition de table MergeTree. Si un INSERT est interrompu, ClickHouse tente de réinsérer les blocs manquants sans en informer l'utilisateur.
Lors de la reprise, la déduplication entre en jeu : chaque bloc reçoit un block_id sous forme de hachage de son contenu. Si ce block_id figure déjà dans le journal de déduplication, l'ensemble du bloc est ignoré. Résultat :
- Une partie des données de l'INSERT initial est perdue.
- La vue matérialisée ne reçoit pas l'ensemble des données.
Conditions pour l'atomicité :
- Insertion dans une seule partition.
- Absence d'INSERT concurrents dans la même partition.
- Données regroupées en un seul bloc.
Le non-respect de ces conditions entraîne des insertions partielles et une déduplication lors de la reprise.
Mécanisme de déduplication des blocs
La déduplication opère au niveau des blocs dans les tables MergeTree répliquées. Le paramètre insert_deduplicate (1 par défaut) active les vérifications de block_id. Si un doublon est détecté, le bloc est ignoré.
Dans les tables non répliquées, la déduplication est désactivée (non_replicated_deduplication_window=0). Pour la réplication, il est recommandé de définir :
insert_deduplicate = 0
Cela évite la perte de blocs lors d'INSERT répétés, mais autorise les doublons. Pour les charges de travail analytiques append-only, les doublons sont acceptables et sont nettoyés lors des fusions.
Déduplication dans les vues matérialisées
Les vues matérialisées effectuent des INSERT dans la table cible en se basant sur les données source. Par défaut, la déduplication est vérifiée sur la table source, et le statut est propagé à la vue.
Le paramètre deduplicate_blocks_in_dependent_materialized_views contrôle cela :
- 0 (par défaut) : Déduplication sur source_table, risque de perte de données.
- 1 : Déduplication sur final_table, blocs insérés intégralement.
Définir :
SET deduplicate_blocks_in_dependent_materialized_views = 1;
La documentation ClickHouse avertit explicitement que sans ajustements, les vues matérialisées peuvent manquer des données lors d'insertions de blocs répétés.
Paramètres recommandés
Pour éliminer la perte de données, appliquez ces modifications à la configuration du serveur ou de la session :
insert_deduplicate = 0— désactive la déduplication lors d'INSERT répétés.deduplicate_blocks_in_dependent_materialized_views = 1— déduplication dans les MV sur la table cible.- Vérifiez max_insert_block_size : des valeurs plus élevées minimisent la division en blocs.
- Évitez les INSERT concurrents dans la même partition.
Surveillez les journaux pour les insertions partielles et comparez COUNT(*) entre les tables source et finale.
Points clés à retenir
- ClickHouse garantit les propriétés ACID uniquement pour un seul bloc dans une partition ; tout le reste dépend des paramètres.
- La déduplication des blocs par block_id provoque des pertes lors d'INSERT interrompus dans les pipelines de vues matérialisées.
- La désactivation de insert_deduplicate résout le problème pour MergeTree répliqué.
- La définition de deduplicate_blocks_in_dependent_materialized_views=1 empêche les pertes dans les vues.
- Les doublons après désactivation de la déduplication sont supprimés par les fusions standard.
— Editorial Team
Aucun commentaire pour le moment.