Zurück zur Startseite

ClickHouse: Deduplizierung und Verluste in MV

Der Artikel analysiert den Mechanismus der Datenverluste in ClickHouse beim Einsatz materialisierter Ansichten aufgrund von Block-Deduplizierung. Beschreibt die Bedingungen der INSERT-Atomizität, die Rolle von block_id und empfohlene Einstellungen zur Beseitigung des Problems. Geeignet für Middle-/Senior-Entwickler von OLAP-Systemen.

Wie ClickHouse Daten in materialisierten Ansichten verliert
Advertisement 728x90

Datenverlust in ClickHouse: Deduplizierung und materialisierte Ansichten

In ClickHouse können bei der Verwendung materialisierter Ansichten die Daten in der Zieltabelle nicht mit der Quelle übereinstimmen. Dies geschieht durch Block-Deduplizierung während INSERT, insbesondere in replizierten Clustern. Die Standardkonfiguration führt dazu, dass Blöcke bei wiederholten Einfügungen ignoriert werden, was die Erwartungen an append-only-Speicherung zunichtemacht. Die Lösung besteht darin, die Einstellungen insert_deduplicate und deduplicate_blocks_in_dependent_materialized_views anzupassen.

Betrachten Sie einen typischen Pipeline:

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;

Daten aus source_table werden in final_table kopiert, aber mit der Zeit verschwinden Datensätze aus final_table ohne ersichtlichen Grund.

Google AdInline article slot

Atomicität von INSERT im Detail

ClickHouse teilt INSERT-Daten basierend auf der Einstellung max_insert_block_size in Blöcke auf. Atomicität wird nur für einen einzelnen Block in einer MergeTree-Tabellenpartition garantiert. Bei Unterbrechung eines INSERTs versucht ClickHouse, die fehlenden Blöcke erneut einzufügen, ohne den Benutzer zu benachrichtigen.

Beim Wiederholungsversuch greift die Deduplizierung: Jeder Block erhält eine block_id als Hash seines Inhalts. Ist diese block_id bereits im Deduplizierungsprotokoll vorhanden, wird der gesamte Block übersprungen. Ergebnis:

  • Ein Teil der Daten aus dem ursprünglichen INSERT geht verloren.
  • Die materialisierte Ansicht erhält nicht die vollständigen Daten.

Bedingungen für Atomicität:

Google AdInline article slot
  • Einfügen in eine einzige Partition.
  • Keine gleichzeitigen INSERTs in dieselbe Partition.
  • Daten in einem einzigen Block gepackt.

Nicht-Erfüllung dieser Bedingungen führt zu partiellen Einfügungen und Deduplizierung beim Wiederholungsversuch.

Mechanismus der Block-Deduplizierung

Die Deduplizierung arbeitet auf Blockebene in replizierten MergeTree-Tabellen. Die Einstellung insert_deduplicate (standardmäßig 1) aktiviert block_id-Überprüfungen. Bei Fund eines Duplikats wird der Block ignoriert.

In nicht replizierten Tabellen ist Deduplizierung deaktiviert (non_replicated_deduplication_window=0). Für Replikation wird empfohlen:

Google AdInline article slot
insert_deduplicate = 0

Dies verhindert Blockverluste bei wiederholten INSERTs, erlaubt aber Duplikate. Bei analytischen append-only-Workloads sind Duplikate akzeptabel und werden während der Merges bereinigt.

Deduplizierung in materialisierten Ansichten

Materialisierte Ansichten führen INSERTs in die Zieltabelle basierend auf Quellendaten durch. Standardmäßig wird Deduplizierung auf der Quelltabelle geprüft, und der Status wird auf die Ansicht übertragen.

Die Einstellung deduplicate_blocks_in_dependent_materialized_views steuert dies:

  • 0 (Standard): Deduplizierung auf source_table, Risiko von Datenverlust.
  • 1: Deduplizierung auf final_table, Blöcke vollständig eingefügt.

Legen Sie fest:

SET deduplicate_blocks_in_dependent_materialized_views = 1;

Die ClickHouse-Dokumentation warnt ausdrücklich, dass materialisierte Ansichten bei wiederholten Blockeinfügungen Daten verpassen können, wenn keine Anpassungen vorgenommen werden.

Empfohlene Einstellungen

Um Datenverlust zu eliminieren, wenden Sie diese Änderungen in der Server- oder Sitzungskonfiguration an:

  • insert_deduplicate = 0 — Deduplizierung bei wiederholten INSERTs deaktivieren.
  • deduplicate_blocks_in_dependent_materialized_views = 1 — Deduplizierung in MV auf der Zieltabelle.
  • Überprüfen Sie max_insert_block_size: Größere Werte minimieren die Blockaufteilung.
  • Vermeiden Sie gleichzeitige INSERTs in dieselbe Partition.

Überwachen Sie Logs auf partielle Einfügungen und vergleichen Sie COUNT(*) zwischen Quell- und Zieltabelle.

Wichtige Erkenntnisse

  • ClickHouse garantiert ACID nur für einen einzelnen Block in einer Partition; alles andere hängt von Einstellungen ab.
  • Block-Deduplizierung per block_id verursacht Verluste bei unterbrochenen INSERTs in MV-Pipelines.
  • Das Deaktivieren von insert_deduplicate löst das Problem für replizierte MergeTree.
  • Das Setzen von deduplicate_blocks_in_dependent_materialized_views=1 verhindert Verluste in Ansichten.
  • Duplikate nach Deaktivierung der Deduplizierung werden durch Standard-Merges entfernt.

— Editorial Team

Advertisement 728x90

Weiterlesen