Powrót do strony głównej

ClickHouse: deduplikacja i straty w MV

Artykuł analizuje mechanizm strat danych w ClickHouse przy użyciu materialized views z powodu deduplikacji bloków. Opisane są warunki atomowości INSERT, rola block_id oraz zalecane ustawienia w celu wyeliminowania problemu. Nadaje się dla middle/senior deweloperów systemów OLAP.

Jak ClickHouse traci dane w materialized views
Advertisement 728x90

# Utrata danych w ClickHouse: deduplikacja i materialized views

W ClickHouse przy korzystaniu z materialized views dane w tabeli docelowej mogą nie zgadzać się z źródłowymi. Dzieje się tak z powodu deduplikacji bloków podczas INSERT, szczególnie w zreplikoowanych klastrach. Domyślna konfiguracja powoduje ignorowanie bloków przy powtarzanych wstawieniach, co narusza oczekiwania dotyczące magazynu append-only. Rozwiązanie polega na dostosowaniu ustawień insert_deduplicate i deduplicate_blocks_in_dependent_materialized_views.

Rozważmy typowy 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;

Dane z source_table są kopiowane do final_table, ale z czasem w final_table znikają rekordy bez widocznej przyczyny.

Google AdInline article slot

Atomowość INSERT w szczegółach

INSERT w ClickHouse dzieli dane na bloki zgodnie z ustawieniem max_insert_block_size. Atomowość jest gwarantowana tylko dla pojedynczego bloku w jednej partycji tabeli MergeTree. Jeśli INSERT zostanie przerwany, ClickHouse próbuje powtórzyć wstawienie brakujących bloków bez powiadamiania użytkownika.

Przy ponownej próbie uruchamia się deduplikacja: każdemu blokowi przypisywany jest block_id jako hash zawartości. Jeśli taki block_id jest już w dzienniku deduplikacji, cały blok jest pomijany. W rezultacie:

  • Część danych z oryginalnego INSERT ginie.
  • Materialized view nie otrzymuje pełnych danych.

Warunki atomowości:

Google AdInline article slot
  • Wstawianie do jednej partycji.
  • Brak równoległych INSERT do tej samej partycji.
  • Dane spakowane w pojedynczy blok.

Niezachowanie tych warunków prowadzi do częściowego wstawienia i deduplikacji przy powtórce.

Mechanizm deduplikacji bloków

Deduplikacja działa na poziomie bloków w zreplikoowanych tabelach MergeTree. Ustawienie insert_deduplicate (domyślnie 1) włącza sprawdzanie block_id. Po wykryciu duplikatu blok jest ignorowany.

W tabelach non-replicated deduplikacja jest wyłączona (non_replicated_deduplication_window=0). W przypadku replikacji zaleca się ustawienie:

Google AdInline article slot
insert_deduplicate = 0

Pozwala to uniknąć utraty bloków przy powtarzanych INSERT, choć dopuszcza duplikaty. W obciążeniach analitycznych z append-only duplikaty są akceptowalne i usuwane podczas merges.

Deduplikacja w materialized views

Materialized views wykonują INSERT do tabeli docelowej na podstawie danych ze źródła. Domyślnie deduplikacja jest sprawdzana w tabeli źródłowej, a status przenoszony na view.

Ustawienie deduplicate_blocks_in_dependent_materialized_views kontroluje zachowanie:

  • Wartość 0 (domyślnie): deduplikacja w source_table, ryzyko strat.
  • Wartość 1: deduplikacja w final_table, bloki wstawiane w całości.

Ustaw:

SET deduplicate_blocks_in_dependent_materialized_views = 1;

Dokumentacja ClickHouse wyraźnie ostrzega: bez korekt materialized views mogą nie otrzymać danych przy powtarzanych wstawieniach bloków.

Zalecenia dotyczące ustawień

Aby wyeliminować utratę danych, wprowadź następujące zmiany w konfiguracji serwera lub sesji:

  • insert_deduplicate = 0 — wyłączenie deduplikacji przy powtarzanych INSERT.
  • deduplicate_blocks_in_dependent_materialized_views = 1 — deduplikacja w MV na tabeli docelowej.
  • Sprawdź max_insert_block_size: duże wartości minimalizują podział na bloki.
  • Unikaj równoległych INSERT do jednej partycji.

Monitoruj logi pod kątem częściowych wstawień i porównuj COUNT(*) między tabelami source i final.

Co ważne

  • ClickHouse gwarantuje ACID tylko dla pojedynczego bloku w jednej partycji, reszta zależy od ustawień.
  • Deduplikacja bloków po block_id powoduje straty przy przerwanych INSERT w pipeline'ach MV.
  • Wyłączenie insert_deduplicate rozwiązuje problem dla zreplikoowanych MergeTree.
  • Włączenie deduplicate_blocks_in_dependent_materialized_views=1 zapobiega stratom w views.
  • Duplikaty po wyłączeniu deduplikacji są usuwane standardowymi merges.

— Editorial Team

Advertisement 728x90

Czytaj dalej