Перейти к основному содержанию
Асинхронные вставки в ClickHouse — это эффективная альтернатива, когда пакетирование на стороне клиента невозможно. Это особенно важно для задач обсервабилити, где сотни или тысячи agent-ов непрерывно отправляют данные — журналы, метрики, трассировки, — часто небольшими полезными нагрузками в реальном времени. Буферизация данных на стороне клиента в таких средах усложняет архитектуру, поскольку требует централизованной очереди, чтобы отправлять достаточно крупные батчи.
Отправлять много небольших батчей в синхронном режиме не рекомендуется, так как это приводит к созданию множества частей. Это ухудшает производительность запросов и вызывает ошибки “too many part”.
Асинхронные вставки переносят ответственность за пакетирование с клиента на сервер: входящие данные записываются в буфер в памяти, а затем сбрасываются в хранилище при достижении настраиваемых порогов. Такой подход значительно снижает накладные расходы на создание частей, уменьшает нагрузку на CPU и обеспечивает эффективную ингестию даже при высоком параллелизме. Основное поведение управляется через настройку async_insert. Асинхронные вставки поддерживаются как через HTTP, так и через native TCP interface. Когда они включены (async_insert = 1), вставки буферизуются и записываются на диск только после выполнения одного из условий сброса:
  • Буфер достигает заданного размера данных (async_insert_max_data_size, по умолчанию 100 MiB).
  • Проходит заданный интервал времени (async_insert_busy_timeout_ms, по умолчанию 200 мс или 1000 мс в Cloud).
  • Накапливается максимальное количество запросов на вставку (async_insert_max_query_number, по умолчанию 450).
Сброс выполняется при достижении первого из этих порогов. Этот процесс пакетирования прозрачен для клиентов и помогает ClickHouse эффективно объединять трафик вставки из нескольких источников. Однако до сброса данные недоступны для запросов. Важно, что для каждой комбинации формы вставки и настроек существует несколько буферов, а в кластерах буферы поддерживаются отдельно на каждом узле, что позволяет гибко управлять ими в многопользовательских средах. Во всем остальном механика вставки идентична описанной для синхронных вставок.

Выбор режима возврата

Поведение асинхронных вставок дополнительно настраивается с помощью параметра wait_for_async_insert. Если установлено значение 1 (по умолчанию), ClickHouse подтверждает вставку только после того, как данные успешно сбрасываются на диск. Это обеспечивает строгие гарантии сохранности данных и упрощает обработку ошибок: если во время сброса что-то пойдет не так, ошибка будет возвращена клиенту. Этот режим рекомендуется для большинства production-сценариев, особенно если отказы вставки нужно надежно отслеживать. Бенчмарки показывают, что этот режим хорошо масштабируется при параллелизме — как с 200, так и с 500 клиентами — благодаря адаптивным вставкам и стабильному созданию частей. Параметр wait_for_async_insert = 0 включает режим “fire-and-forget”. В этом случае сервер подтверждает вставку сразу после буферизации данных, не дожидаясь их записи в хранилище. Это обеспечивает сверхнизкую latency вставок и максимальный throughput, что идеально подходит для высокоскоростных, но некритичных данных. Однако здесь есть компромиссы: нет гарантии, что данные будут сохранены, ошибки проявляются только во время сброса, а dead-letter queue для неудачных вставок отсутствует — для трассировки сбоев приходится постфактум проверять серверные журналы и системные таблицы. Используйте этот режим только в том случае, если ваша рабочая нагрузка допускает потерю данных. Бенчмарки также показывают существенное сокращение количества частей и снижение загрузки CPU, когда буфер сбрасывается нечасто (например, каждые 30 секунд), однако риск незаметного сбоя сохраняется. Мы настоятельно рекомендуем использовать async_insert=1,wait_for_async_insert=1, если вы используете асинхронные вставки. Использование wait_for_async_insert=0 очень рискованно, потому что ваш INSERT-клиент может не узнать о наличии ошибок, а также это может привести к перегрузке, если клиент продолжит быстро записывать данные в ситуации, когда серверу ClickHouse нужно замедлить запись и создать обратное давление, чтобы обеспечить надежность сервиса.

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

Начиная с версии 24.2, ClickHouse по умолчанию использует адаптивные тайм-ауты сброса буфера (async_insert_use_adaptive_busy_timeout). Вместо фиксированного интервала сброса тайм-аут динамически подстраивается между минимальным значением (async_insert_busy_timeout_min_ms, по умолчанию 50 мс) и максимальным (async_insert_busy_timeout_max_ms, по умолчанию 200 мс или 1000 мс в Cloud) в зависимости от скорости поступления данных. Когда данные поступают часто, тайм-аут остается ближе к минимальному значению, чтобы сброс происходил раньше и уменьшалась сквозная задержка. Когда данные поступают редко, он увеличивается в сторону максимального значения, чтобы накапливать более крупные батчи. Это особенно полезно в режиме по умолчанию (wait_for_async_insert=1), где фиксированный большой тайм-аут заставлял бы клиентов ждать весь интервал, даже если данные уже готовы к сбросу.

Обработка ошибок

Проверка схемы и разбор данных происходят при сбросе буфера, а не в момент получения вставки. Если в какой-либо строке запроса на вставку есть ошибка разбора данных или несоответствие типа, никакие данные из этого запроса не сбрасываются на диск — отклоняется вся полезная нагрузка запроса. В режиме по умолчанию (wait_for_async_insert=1) ошибка возвращается клиенту. В режиме fire-and-forget ошибки записываются в серверный журнал и в таблицу system.asynchronous_inserts. Каждый сброс создает как минимум одну часть для каждого отдельного значения ключа партиционирования в буфере. Даже для таблиц без ключа партиционирования один сброс может создать несколько частей, если объем буферизованных данных превышает max_insert_block_size (по умолчанию ~1 миллион строк).
Несмотря на использование асинхронных вставок, вы все равно можете столкнуться с ошибками “too many parts”, если ключ партиционирования имеет высокую мощность.

Дедупликация и надежность

По умолчанию ClickHouse автоматически выполняет дедупликацию для синхронных вставок, что делает повторные попытки безопасными в случае сбоев. Однако для асинхронных вставок она отключена, если только вы не включили ее явно (ее не следует включать, если у вас есть зависимые materialized views — см. issue). На практике, если дедупликация включена и одна и та же вставка выполняется повторно — например, из-за тайм-аута или сбоя сети, — ClickHouse может безопасно проигнорировать дубликат. Это помогает сохранять идемпотентность и избежать повторной записи данных.

Включение асинхронных вставок

Асинхронные вставки можно включить для конкретного пользователя или для конкретного запроса:
  • Включение асинхронных вставок на уровне пользователя. В этом примере используется пользователь default; если вы создадите другого пользователя, подставьте его имя:
    ALTER USER default SETTINGS async_insert = 1
    
  • Вы можете указать настройки асинхронной вставки с помощью секции SETTINGS в запросах вставки:
    INSERT INTO YourTable SETTINGS async_insert=1, wait_for_async_insert=1 VALUES (...)
    
  • Вы также можете указать настройки асинхронной вставки как параметры подключения при использовании клиентской библиотеки ClickHouse для языка программирования. Например, вот как это можно сделать в строке подключения JDBC, если вы используете драйвер ClickHouse Java JDBC для подключения к ClickHouse Cloud:
    "jdbc:ch://HOST.clickhouse.cloud:8443/?user=default&password=PASSWORD&ssl=true&custom_http_params=async_insert=1,wait_for_async_insert=1"
    
Асинхронные вставки не применяются к запросам INSERT INTO ... SELECT. Если вставка содержит секцию SELECT, запрос всегда выполняется синхронно, независимо от настройки async_insert.

Сброс буферов при завершении работы

Чтобы сбросить все буферы async insert с ожидающими записи данными — например, при корректном завершении работы или перед обслуживанием, — выполните:
SYSTEM FLUSH ASYNC INSERT QUEUE
Это гарантирует, что все буферизованные данные будут записаны в хранилище перед остановкой сервера.

Сравнение с буферными таблицами

Асинхронные вставки — современная замена буферным таблицам. Ключевые различия:
  • Изменения DDL не требуются. Асинхронные вставки прозрачны — достаточно включить настройку, а не создавать дополнительные таблицы.
  • Буферизация по форме запроса. Асинхронные вставки поддерживают отдельные буферы для каждой уникальной формы запроса и комбинации настроек, что позволяет применять более гибкие политики сброса. Буферные таблицы используют один буфер на целевую таблицу.
  • Надёжность. В режиме по умолчанию (wait_for_async_insert=1) данные записываются на диск до того, как клиент получит подтверждение. Буферные таблицы работают по принципу fire-and-forget — при сбое буферизованные данные теряются.
  • Поведение в кластере. В кластерах буферы асинхронных вставок поддерживаются на каждом узле. Для буферных таблиц их нужно явно создавать на каждом узле.
Последнее изменение 10 июня 2026 г.