deшка
Урок 10.11

Загрузка: батчи, форматы и async inserts

Как передать данные без лавины parts и что означает подтверждение записи.

Загрузка в ClickHouse связывает три решения: как сгруппировать строки для вставки, как представить значения и как обработать повтор после ошибки. Успешный INSERT должен означать именно ту гарантию, на которую рассчитывает отправитель.

Синхронная вставка и размер порции

Обычная синхронная вставка в локальный MergeTree обрабатывает входной блок и записывает части. Если данные относятся к нескольким партициям, частей может быть несколько. Много маленьких INSERT увеличивает число parts, метаданных и работу фоновых merges.

Несколько строк передают одной командой, например для таблицы events с полями event_id и event_type:

INSERT INTO events (event_id, event_type) VALUES
    (1, 'click'), (2, 'view'), (3, 'click');

Три строки здесь только показывают синтаксис. Рабочую порцию выбирают по числу строк, байтам, доступной памяти и допустимой задержке. Один очень большой пакет может долго занимать память и усложнять повтор; слишком маленькие пакеты создают лишние части. Важна и численность одновременно загружаемых партиций.

Явный список колонок защищает загрузку от перестановки полей схемы. Типы, часовой пояс, обязательные поля и правила обработки неверных значений входят в договор с источником.

Формат данных

ФорматКак представлены значенияЧто учитывать
CSVWithNamesСтроки с заголовком колонокКавычки, разделитель, кодировку и настройки сопоставления полей
JSONEachRowОдин JSON-объект на строкуИмена полей, типы и поведение отсутствующих значений
ParquetТипизированные колонки в файлеСовместимость схемы и преобразование типов
NativeВнутренние бинарные блоки ClickHouseУдобен клиентам, понимающим протокол и типы ClickHouse

Формат описывает представление входа, а не движок целевой таблицы. JSONEachRow не требует колонки типа JSON. Файл Parquet после загрузки в MergeTree не становится частью таблицы в своём исходном формате.

Источник может передавать данные через native client, HTTP API, библиотеку, INSERT SELECT или интеграционный инструмент. Файлы, которые видит сервер, и файлы на машине клиента — разные пространства. Это важно при выборе способа чтения.

Асинхронные вставки

Async inserts позволяют серверу накопить несколько маленьких запросов в буфере и записать их вместе. Буферы разделяются по форме запроса и настройкам; это не единый общий пакет всех клиентов.

При async_insert = 1 и wait_for_async_insert = 1 клиент ждёт flush и получает ошибку, если накопленная вставка не выполнена. При wait_for_async_insert = 0 подтверждение относится к приёму в буфер: после него возможна ошибка записи, которую клиент уже не увидит как ответ своей команды. Такой режим требует отдельно продуманной сохранности.

Async inserts уменьшают давление маленьких частей, но не проверяют бизнес-уникальность событий. Они также не отменяют требований к памяти, задержке и наблюдению за ошибками.

Повторы и граница подтверждения

После сетевого таймаута отправитель может не знать, выполнена ли вставка. Повтор обеспечивает доставку, но способен повторно добавить данные. PRIMARY KEY MergeTree этому не препятствует.

Insert deduplication имеет ограниченное окно и правила распознавания блока или токена. При перепаковывании тех же событий в другие блоки результат зависит от выбранного механизма. Дедупликация блоков не равна бессрочной уникальности event_id.

Гарантии повторов для async inserts и связанных materialized views менялись между версиями. Современные гарантии нельзя автоматически переносить на учебную 25.8. Для нужной версии проверяют сохранность исходной таблицы и повторный вклад в target view вместе. В распределённой загрузке дополнительно выясняют, означает ответ запись на шард или только помещение в очередь Distributed.

Войти, чтобы отмечатьдальше →
10.12 →Materialized views: инкрементальная и периодическая обработка