Вставка данных в ClickHouse
Основной пример
Вы можете использовать знакомую команду INSERT INTO TABLE
с ClickHouse. Давайте вставим некоторые данные в таблицу, которую мы создали в руководстве "Создание таблиц в ClickHouse".
Чтобы убедиться, что все сработало, мы выполним следующий запрос SELECT
:
Что вернет:
Вставка в ClickHouse и OLTP базы данных
Как OLAP (Online Analytical Processing) база данных, ClickHouse оптимизирован для высокой производительности и масштабируемости, позволяя потенциально вставлять миллионы строк в секунду. Это достигается за счет сочетания высокопараллельной архитектуры и эффективного колоночного сжатия, но с компромиссами на уровне немедленной согласованности. Более конкретно, ClickHouse оптимизирован для операций только на добавление и предлагает только гарантии со временем согласованности.
В отличие от этого, OLTP базы данных, такие как Postgres, специально оптимизированы для транзакционных вставок с полной совместимостью ACID, обеспечивая строгую согласованность и надежные гарантии. PostgreSQL использует MVCC (Multi-Version Concurrency Control) для обработки параллельных транзакций, что подразумевает поддержку нескольких версий данных. Эти транзакции могут включать потенциально небольшое количество строк за раз, с значительными накладными расходами из-за гарантий надежности, ограничивающих производительность вставки.
Чтобы достичь высокой производительности вставки, сохраняя строгие гарантии согласованности, пользователи должны придерживаться простых правил, описанных ниже, при вставке данных в ClickHouse. Следуя этим правилам, можно избежать проблем, с которыми пользователи обычно сталкиваются в первый раз при использовании ClickHouse, и попытаться воспроизвести стратегию вставки, которая работает для OLTP баз данных.
Лучшие практики для вставок
Вставляйте большими партиями
По умолчанию каждая вставка, отправленная в ClickHouse, заставляет ClickHouse немедленно создать часть хранилища, содержащую данные вставки вместе с другими метаданными, которые необходимо сохранить. Поэтому отправка меньшего количества вставок, каждая из которых содержит больше данных, по сравнению с отправкой большего количества вставок, каждая из которых содержит меньше данных, уменьшит количество необходимых записей. В общем, мы рекомендуем вставлять данные довольно крупными партиями, как минимум по 1,000 строк за раз, а лучше от 10,000 до 100,000 строк. (Дополнительные сведения здесь).
Если большие партии невозможны, используйте асинхронные вставки, описанные ниже.
Обеспечьте согласованные партии для идемпотентных повторных попыток
По умолчанию вставки в ClickHouse являются синхронными и идемпотентными (т.е. выполнение одной и той же операции вставки несколько раз оказывает такой же эффект, как выполнение ее один раз). Для таблиц семейства движка MergeTree, ClickHouse по умолчанию автоматически удаляет дубликаты вставок.
Это означает, что вставки остаются устойчивыми в следующих случаях:
-
- Если узел, принимающий данные, имеет проблемы, запрос вставки будет истекать (или выдаст более конкретную ошибку) и не получит подтверждение.
-
- Если данные были записаны узлом, но подтверждение не может быть возвращено отправителю запроса из-за сетевых перебоев, отправитель либо получит таймаут, либо сетевую ошибку.
С точки зрения клиента (i) и (ii) могут быть трудно различимы. Однако в обоих случаях неподтвержденную вставку можно немедленно повторить. Пока повторяемый запрос вставки содержит те же данные в том же порядке, ClickHouse автоматически проигнорирует повторяемую вставку, если исходная (неподтвержденная) вставка прошла успешно.
Вставка в таблицу MergeTree или распределенную таблицу
Мы рекомендуем вставлять напрямую в таблицу MergeTree (или реплицированную таблицу), распределяя запросы по набору узлов, если данные шардированы, и устанавливать internal_replication=true
.
Это позволит ClickHouse реплицировать данные на любые доступные репликации шардов и обеспечить, чтобы данные были в конечном итоге согласованными.
Если это клиентское балансирование нагрузки неудобно, пользователи могут вставлять через распределенную таблицу, которая затем распределит записи по узлам. Тем не менее, рекомендуется установить internal_replication=true
.
Однако стоит отметить, что этот подход менее эффективен, поскольку записи должны сначала выполняться локально на узле с распределенной таблицей, а затем отправляться на шардирование.
Используйте асинхронные вставки для малых партий
Существуют сценарии, когда клиентская пакетная обработка невозможна, например, в случае с наблюдаемостью, когда 100 или 1000 одноцелевых агентов отправляют логи, метрики, трассировки и т. д. В этом сценарии важна быстрая передача данных, чтобы обнаружить проблемы и аномалии как можно быстрее. Кроме того, существует риск всплесков событий в наблюдаемых системах, что потенциально может вызвать большие всплески памяти и связанные с ними проблемы при попытке буферизовать данные наблюдаемости на стороне клиента. Если большие партии не могут быть вставлены, пользователи могут делегировать пакетирование ClickHouse, используя асинхронные вставки.
При включенных асинхронных вставках данные сначала вставляются в буфер, а затем записываются в хранилище базы данных позже в 3 этапа, как показано на диаграмме ниже:

С включенными асинхронными вставками ClickHouse:
(1) получает запрос вставки асинхронно. (2) сначала записывает данные запроса в буфер в памяти. (3) сортирует и записывает данные в виде части в хранилище базы данных только тогда, когда происходит следующий сброс буфера.
Прежде чем буфер будет сброшен, данные других асинхронных запросов вставки от того же клиента или других клиентов могут быть собраны в буфере. Часть, созданная при сбросе буфера, будет потенциально содержать данные от нескольких асинхронных запросов вставки. В общем, эта механика переносит пакетирование данных с клиентской стороны на серверную сторону (экземпляр ClickHouse).
Используйте официальные клиенты ClickHouse
ClickHouse имеет клиенты на самых популярных языках программирования. Эти клиенты оптимизированы для того, чтобы гарантировать, что вставки выполняются корректно и нативно поддерживают асинхронные вставки либо напрямую, как например в Go клиенте, либо косвенно, когда это включено в запрос, настройки пользователя или соединения.
Смотрите Клиенты и драйверы для полного списка доступных клиентов и драйверов ClickHouse.
Предпочитайте нативный формат
ClickHouse поддерживает многие форматы ввода во время вставки (и запроса). Это значительное отличие от OLTP баз данных и упрощает загрузку данных из внешних источников, особенно в сочетании с табличными функциями и возможностью загружать данные из файлов на диске. Эти форматы идеально подходят для экстренной загрузки данных и задач по обработке данных.
Для приложений, стремящихся к оптимальной производительности вставки, пользователи должны вставлять данные, используя Нативный формат. Это поддерживается большинством клиентов (таких как Go и Python) и гарантирует, что сервер должен выполнять минимальное количество работы, поскольку этот формат уже колоночный. Таким образом, ответственность за преобразование данных в колоночный формат переносится на клиентскую сторону. Это важно для эффективного масштабирования вставок.
В качестве альтернативы пользователи могут использовать RowBinary формат (как используется в Java клиенте), если предпочтителен строковый формат - это обычно проще для записи, чем нативный формат. Это более эффективно с точки зрения сжатия, сетевых накладных расходов и обработки на сервере, чем альтернативные строковые форматы, такие как JSON. Формат JSONEachRow можно рассмотреть для пользователей с меньшей пропускной способностью записи, желающими быстро интегрироваться. Пользователи должны понимать, что этот формат потребует дополнительных затрат на процессор в ClickHouse для парсинга.
Используйте HTTP интерфейс
В отличие от многих традиционных баз данных, ClickHouse поддерживает HTTP интерфейс. Пользователи могут использовать это как для вставки, так и для запроса данных, используя любой из вышеперечисленных форматов. Это часто предпочтительнее, чем родной протокол ClickHouse, поскольку позволяет легко переключать трафик с балансировщиками нагрузки. Мы ожидаем небольших различий в производительности вставок с родным протоколом, который требует немного меньше накладных расходов. Существующие клиенты используют любой из этих протоколов (в некоторых случаях оба, например, Go клиент). Родной протокол действительно позволяет легко отслеживать процесс запроса.
Смотрите HTTP интерфейс для получения дополнительной информации.
Загрузка данных из Postgres
Для загрузки данных из Postgres пользователи могут использовать:
PeerDB by ClickHouse
, инструмент ETL, специально разработанный для репликации баз данных PostgreSQL. Это доступно в обеих версиях:- ClickHouse Cloud - доступно через наш новый коннектор (Private Preview) в ClickPipes, нашем управляемом сервисе загрузки данных. Заинтересованные пользователи могут зарегистрироваться здесь.
- Self-managed - через проект с открытым исходным кодом.
- PostgreSQL табличный движок для чтения данных напрямую, как показано в предыдущих примерах. Обычно подходит, если пакетная репликация на основе известного водяного знака, например, временной метки, является достаточной или если это одноразовая миграция. Этот подход может масштабироваться до десятков миллионов строк. Пользователи, желающие мигрировать большие наборы данных, должны рассмотреть возможность выполнения нескольких запросов, каждый из которых обрабатывает часть данных. Этапные таблицы могут использоваться для каждой части перед перемещением ее разделов в финальную таблицу. Это позволяет повторно попытаться выполнить неудачные запросы. Для получения дополнительных сведений о этой стратегии массовой загрузки смотрите здесь.
- Данные могут быть экспортированы из PostgreSQL в формате CSV. Это может быть вставлено в ClickHouse как из локальных файлов, так и через объектное хранилище с использованием табличных функций.
Если вам нужна помощь с вставкой больших наборов данных или возникают ошибки при импорте данных в ClickHouse Cloud, пожалуйста, свяжитесь с нами по адресу [email protected], и мы поможем.