Перейти к основному содержимому
Перейти к основному содержимому

ClickHouse JS

Официальный JS-клиент для подключения к ClickHouse.
Клиент написан на TypeScript и предоставляет типы для публичного API клиента.

Он не имеет зависимостей, оптимизирован для максимальной производительности и протестирован с различными версиями и конфигурациями ClickHouse (локальный одиночный узел, локальный кластер и ClickHouse Cloud).

Существует две разные версии клиента для различных сред:

  • @clickhouse/client - только для Node.js
  • @clickhouse/client-web - браузеры (Chrome/Firefox), Cloudflare workers

При использовании TypeScript убедитесь, что он не ниже версии 4.5, которая позволяет использовать синтаксис импорта и экспорта в строках.

Исходный код клиента доступен в репозитории ClickHouse-JS на GitHub.

Требования к окружению (Node.js)

Node.js должен быть доступен в окружении для работы клиента.
Клиент совместим со всеми поддерживаемыми версиями Node.js.

Как только версия Node.js достигает конца своего жизненного цикла, клиент перестает ее поддерживать, так как она считается устаревшей и небезопасной.

Поддерживаемые версии Node.js:

Версия Node.jsПоддерживается?
22.x
20.x
18.x
16.xУпорный труд

Требования к окружению (Web)

Веб-версия клиента официально тестируется с последними браузерами Chrome/Firefox и может использоваться в качестве зависимости, например, в приложениях React/Vue/Angular или Cloudflare workers.

Установка

Чтобы установить последнюю стабильную версию клиента Node.js, выполните команду:

Установка веб-версии:

Совместимость с ClickHouse

Версия клиентаClickHouse
1.8.023.3+

Скорее всего, клиент будет работать и с более старыми версиями, но это поддержка на лучших условиях и не гарантируется. Если у вас версия ClickHouse ниже 23.3, пожалуйста, ознакомьтесь с политикой безопасности ClickHouse и рассмотрите возможность обновления.

Примеры

Мы стремимся охватить различные сценарии использования клиента в примерах в репозитории клиента.

Обзор доступен в README примеров.

Если что-то неясно или отсутствует в примерах или следующей документации, не стесняйтесь связываться с нами.

API клиента

Большинство примеров должны быть совместимы как с Node.js, так и с веб-версиями клиента, если явно не указано иное.

Создание экземпляра клиента

Вы можете создать столько экземпляров клиента, сколько необходимо, с помощью фабрики createClient:

Если ваша среда не поддерживает ESM модули, вы можете использовать вместо этого синтаксис CJS:

Экземпляр клиента может быть предварительно настроен во время создания.

Конфигурация

При создании экземпляра клиента можно настроить следующие параметры подключения:

ПараметрОписаниеЗначение по умолчаниюСмотрите также
url?: stringURL-адрес экземпляра ClickHouse.http://localhost:8123Документация по конфигурации URL
pathname?: stringДополнительный путь, который будет добавлен к URL ClickHouse после его разбора клиентом.''Прокси с путем документ
request_timeout?: numberТаймаут запроса в миллисекундах.30_000-
compression?: { **response**?: boolean; **request**?: boolean }Включить сжатие.-Документация по сжатию
username?: stringИмя пользователя, от имени которого выполняются запросы.default-
password?: stringПароль пользователя.''-
application?: stringИмя приложения, использующего клиент Node.js.clickhouse-js-
database?: stringИмя базы данных для использования.default-
clickhouse_settings?: ClickHouseSettingsНастройки ClickHouse, которые будут применены ко всем запросам.{}-
log?: { **LoggerClass**?: Logger, **level**?: ClickHouseLogLevel }Конфигурация внутренних логов клиента.-Документация по ведению журнала
session_id?: stringНеобязательный идентификатор сессии ClickHouse, который будет отправлен с каждым запросом.--
keep_alive?: { **enabled**?: boolean }Включен по умолчанию как в версиях Node.js, так и в веб-версиях.--
http_headers?: Record<string, string>Дополнительные HTTP-заголовки для исходящих запросов ClickHouse.-Обратный прокси с аутентификацией документация
roles?: string | string[]Имена ролей ClickHouse, которые будут прикреплены к исходящим запросам.-Использование ролей с HTTP-интерфейсом

Специфические параметры конфигурации для Node.js

ПараметрОписаниеЗначение по умолчаниюСмотрите также
max_open_connections?: numberМаксимальное количество подключенных сокетов для каждого хоста.10-
tls?: { **ca_cert**: Buffer, **cert**?: Buffer, **key**?: Buffer }Настройка сертификатов TLS.-Документация по TLS
keep_alive?: { **enabled**?: boolean, **idle_socket_ttl**?: number }--Документация по Keep Alive
http_agent?: http.Agent | https.Agent
Experimental feature. Learn more.
Пользовательский HTTP-агент для клиента.-Документация по HTTP-агенту
set_basic_auth_header?: boolean
Experimental feature. Learn more.
Установить заголовок Authorization с учетными данными базовой аутентификации.trueиспользование этого параметра в документации HTTP-агента

Конфигурация URL

к сведению

Конфигурация URL всегда перезапишет закодированные значения, и в этом случае будет выведено предупреждение.

Возможно настроить большинство параметров экземпляра клиента с помощью URL. Формат URL: http[s]://[username:password@]hostname:port[/database][?param1=value1&param2=value2]. В большинстве случаев имя конкретного параметра отражает его путь в интерфейсе параметров конфигурации, за исключением нескольких случаев. Поддерживаются следующие параметры:

ПараметрТип
pathnameпроизвольная строка.
application_idпроизвольная строка.
session_idпроизвольная строка.
request_timeoutнеотрицательное число.
max_open_connectionsнеотрицательное число, больше нуля.
compression_requestboolean. См. ниже (1)
compression_responseboolean.
log_levelдопустимые значения: OFF, TRACE, DEBUG, INFO, WARN, ERROR.
keep_alive_enabledboolean.
clickhouse_setting_* или ch_*см. ниже (2)
http_header_*см. ниже (3)
(только для Node.js) keep_alive_idle_socket_ttlнеотрицательное число.
  • (1) Для boolean допустимые значения true/1 и false/0.
  • (2) Любой параметр, начинающийся с clickhouse_setting_ или ch_, будет иметь этот префикс удалённым, а оставшаяся часть будет добавлена к clickhouse_settings клиента. Например, ?ch_async_insert=1&ch_wait_for_async_insert=1 будет равно:

Примечание: boolean значения для clickhouse_settings должны передаваться как 1/0 в URL.

  • (3) Аналогично (2), но для конфигурации http_header. Например, ?http_header_x-clickhouse-auth=foobar будет эквивалентно:

Подключение

Соберите свои данные подключения

Чтобы подключиться к ClickHouse с помощью HTTP(S), вам нужна следующая информация:

  • ХОСТ и ПОРТ: обычно порт 8443 при использовании TLS или 8123 при его отсутствии.

  • НАЗВАНИЕ БАЗЫ ДАННЫХ: по умолчанию есть база данных с именем default, используйте имя базы данных, к которой вы хотите подключиться.

  • ИМЯ ПОЛЬЗОВАТЕЛЯ и ПАРОЛЬ: по умолчанию имя пользователя default. Используйте имя пользователя, подходящее для вашего случая использования.

Данные для вашей службы ClickHouse Cloud доступны в консоли ClickHouse Cloud. Выберите службу, к которой вы будете подключаться, и нажмите Подключиться:

Кнопка подключения к службе ClickHouse Cloud

Выберите HTTPS, и детали будут доступны в примере команды curl.

Детали подключения ClickHouse Cloud через HTTPS

Если вы используете self-managed ClickHouse, детали подключения задаются вашим администратором ClickHouse.

Обзор подключения

Клиент реализует подключение через протокол HTTP(s). Поддержка RowBinary планируется, см. связанную проблему.

Следующий пример демонстрирует, как настроить подключение к ClickHouse Cloud. Предполагается, что значения url (включая протокол и порт) и password указаны через переменные окружения, и используется пользователь default.

Пример: Создание экземпляра клиента Node.js с использованием переменных окружения для конфигурации.

Репозиторий клиента содержит множество примеров, которые используют переменные окружения, такие как создание таблицы в ClickHouse Cloud, использование асинхронных вставок и множество других.

Пул подключений (только для Node.js)

Чтобы избежать накладных расходов на установление соединения при каждом запросе, клиент создает пул подключений к ClickHouse для повторного использования, используя механизм Keep-Alive. По умолчанию Keep-Alive включен, а размер пула подключений установлен на 10, но вы можете изменить его с помощью параметра конфигурации max_open_connections опции.

Нет гарантии, что одно и то же соединение в пуле будет использоваться для последующих запросов, если пользователь не установил max_open_connections: 1. Это редко необходимо, но может потребоваться в случаях, когда пользователи используют временные таблицы.

Смотрите также: Конфигурация Keep-Alive.

ID запроса

Каждый метод, который отправляет запрос или оператор (command, exec, insert, select), предоставит query_id в результате. Этот уникальный идентификатор определяется клиентом для каждого запроса и может быть полезен для извлечения данных из system.query_log, если он включен в конфигурации сервера, или для отмены длительных запросов (см. пример). Если необходимо, query_id может быть переопределен пользователем в параметрах методов command/query/exec/insert.

подсказка

Если вы переопределяете параметр query_id, вам нужно убедиться в его уникальности для каждого вызова. Случайный UUID - хорошее решение.

Базовые параметры для всех методов клиента

Существует несколько параметров, которые могут быть применены ко всем методам клиента (query/command/insert/exec).

Метод запроса

Этот метод используется для большинства операторов, которые могут иметь ответ, таких как SELECT, или для отправки DDL, таких как CREATE TABLE, и его следует ожидать. Ожидается, что возвращаемый набор результатов будет потребляться в приложении.

примечание

Существует специальный метод insert для вставки данных и command для DDL.

Смотрите также: Базовые параметры для всех методов клиента.

подсказка

Не указывайте форматный клауз в query, используйте вместо этого параметр format.

Наборы результатов и абстракции строк

ResultSet предоставляет несколько удобных методов для обработки данных в вашем приложении.

Реализация ResultSet для Node.js использует Stream.Readable под капотом, в то время как веб-версия использует Web API ReadableStream.

Вы можете потреблять ResultSet, вызывая методы text или json на ResultSet и загружая весь набор строк, возвращенный запросом, в память.

Вы должны начинать потребление ResultSet как можно скорее, так как он удерживает открытую строчку ответа и, следовательно, поддерживает активным базовое соединение. Клиент не буферизует входные данные, чтобы избежать потенциального чрезмерного использования памяти приложением.

В качестве альтернативы, если он слишком велик, чтобы поместиться в памяти за один раз, вы можете вызвать метод stream и обрабатывать данные в потоковом режиме. Каждый из частей ответа будет преобразован в относительно небольшие массивы строк (размер этого массива зависит от размера конкретного порции, получаемого клиентом от сервера, так как это может варьироваться, и размера отдельных строк), по очереди.

Пожалуйста, обратитесь к списку поддерживаемых форматов данных, чтобы определить, какой формат является наилучшим для потоковой передачи в вашем случае. Например, если вы хотите передавать JSON-объекты, вы можете выбрать JSONEachRow, и каждая строка будет распознана как объект JS, или, возможно, более компактный формат JSONCompactColumns, который приведет к тому, что каждая строка будет компактным массивом значений. См. также: потоковые файлы.

к сведению

Если ResultSet или его поток не будут полностью потреблены, он будет уничтожен после периода неактивности request_timeout.

Пример: (Node.js/Web) Запрос с результирующим набором данных в формате JSONEachRow, потребление всего потока и парсинг содержимого как JS объектов.
Исходный код.

Пример: (Node.js только) Потоковый результат запроса в формате JSONEachRow, используя классический подход on('data'). Это взаимозаменяемо с синтаксисом for await const.
Исходный код.

Пример: (Node.js только) Потоковый результат запроса в формате CSV, используя классический подход on('data'). Это взаимозаменяемо с синтаксисом for await const.
Исходный код.

Пример: (Node.js только) Потоковый результат запроса как JS объекты в формате JSONEachRow, потребляемый с использованием синтаксиса for await const. Это взаимозаменяемо с классическим подходом on('data').
Исходный код.

примечание

Синтаксис for await const имеет немного меньше кода, чем подход on('data'), но может иметь негативное влияние на производительность.
Смотрите это сообщение в репозитории Node.js для получения дополнительной информации.

Пример: (Только веб) Итерация по ReadableStream объектов.

Метод вставки

Это основной метод для вставки данных.

Тип возврата минимален, так как мы не ожидаем, что сервер вернет какие-либо данные и сразу же освободит поток ответа.

Если пустой массив был предоставлен методу вставки, оператор вставки не будет отправлен на сервер; вместо этого метод немедленно вернется с { query_id: '...', executed: false }. Если параметр query_id не был предоставлен в параметрах метода, он будет пустой строкой в результате, так как возвращение случайного UUID, сгенерированного клиентом, может быть запутанным, поскольку запроса с таким query_id не будет в таблице system.query_log.

Если оператор вставки был отправлен на сервер, флаг executed будет true.

Метод вставки и потоковая передача в Node.js

Он может работать либо с Stream.Readable, либо с обычным Array<T>, в зависимости от формата данных, указанного в методе insert. Также смотрите этот раздел о потоковой передаче файлов.

Метод вставки должен ожидаться (await); однако можно указать входной поток и ожидать операцию insert позже, только когда поток завершится (что также разрешит промис insert). Это может быть полезно для обработчиков событий и аналогичных сценариев, но обработка ошибок может быть сложной с множеством крайних случаев на стороне клиента. Вместо этого рассмотрите возможность использования асинхронных вставок, как показано в этом примере.

подсказка

Если у вас есть пользовательское утверждение INSERT, которое трудно смоделировать с помощью этого метода, рассмотрите возможность использования метода команд.

Вы можете увидеть, как он используется в примерах INSERT INTO ... VALUES или INSERT INTO ... SELECT.

Смотрите также: Базовые параметры для всех методов клиента.

к сведению

Запрос, отмененный с помощью abort_signal, не гарантирует, что вставка данных не произошла, так как сервер мог получить часть потоковых данных до отмены.

Пример: (Node.js/Web) Вставка массива значений. Исходный код.

Пример: (Только Node.js) Вставка потока из CSV файла. Исходный код. Также смотрите: потоковая передача файлов.

Пример: Исключение определенных колонок из SQL-выражения вставки.

При заданной такой определении таблицы:

Вставьте только определенную колонку:

Исключите определенные колонки:

Смотрите исходный код для дополнительных деталей.

Пример: Вставка в базу данных, отличную от предоставленной экземпляру клиента. Исходный код.

Ограничения веб-версии

В настоящее время вставки в @clickhouse/client-web работают только с Array<T> и форматами JSON*. Потоковая передача не поддерживается в веб-версии из-за плохой совместимости с браузерами.

Соответственно, интерфейс InsertParams для веб-версии выглядит немного иначе, чем версия Node.js, так как values ограничены только типом ReadonlyArray<T>:

Это может измениться в будущем. Смотрите также: Базовые параметры для всех методов клиента.

Метод команды

Он может быть использован для утверждений, которые не имеют никакого вывода, когда клаузула формата не применима или когда вы вообще не заинтересованы в ответе. Примером такого утверждения могут быть CREATE TABLE или ALTER TABLE.

Должен ожидаться.

Поток ответа немедленно уничтожается, что означает, что сокет, на котором он основан, освобождается.

Смотрите также: Базовые параметры для всех методов клиента.

Пример: (Node.js/Web) Создание таблицы в ClickHouse Cloud. Исходный код.

Пример: (Node.js/Web) Создание таблицы в установленном ClickHouse. Исходный код.

Пример: (Node.js/Web) ВСТАВКА ИЗ SELECT

к сведению

Запрос, отмененный с помощью abort_signal, не гарантирует, что утверждение не было выполнено сервером.

Метод exec

Если у вас есть пользовательский запрос, который не подходит под query/insert, и вас интересует результат, вы можете использовать exec в качестве альтернативы command.

exec возвращает читаемый поток, который ДОЛЖЕН быть потреблен или уничтожен на стороне приложения.

Смотрите также: Базовые параметры для всех методов клиента.

Тип возвращаемого потока отличается в версиях Node.js и Web.

Node.js:

Web:

Ping

Метод ping, предоставленный для проверки состояния подключения, возвращает true, если сервер доступен.

Если сервер недоступен, связанная ошибка включена в результат.

Ping может быть полезным инструментом для проверки доступности сервера при запуске приложения, особенно с ClickHouse Cloud, где экземпляр может быть в режиме ожидания и проснется после пинга.

Пример: (Node.js/Web) Пинг экземпляра сервера ClickHouse. Обратите внимание: для веб-версии пойманные ошибки будут различаться. Исходный код.

Обратите внимание: из-за отсутствия реализации CORS для конечной точки /ping веб-версия использует простой SELECT 1, чтобы достичь аналогичного результата.

Закрыть (только Node.js)

Закрывает все открытые соединения и освобождает ресурсы. Не выполняет никаких действий в веб-версии.

Потоковая передача файлов (только Node.js)

Существует несколько примеров потоковой передачи файлов с популярными форматами данных (NDJSON, CSV, Parquet) в репозитории клиента.

Потоковая передача других форматов в файл должна быть аналогична Parquet, единственное отличие будет в формате, используемом для вызова query (JSONEachRow, CSV и т. д.) и имени выходного файла.

Поддерживаемые форматы данных

Клиент обрабатывает форматы данных как JSON или текст.

Если вы указываете format как один из форматов семейства JSON (JSONEachRow, JSONCompactEachRow и т. д.), клиент будет сериализовать и десериализовать данные в процессе передачи.

Данные, предоставленные в "сыром" текстовом формате (семейства CSV, TabSeparated и CustomSeparated), отправляются без дополнительных преобразований.

подсказка

Может возникнуть путаница между JSON как общим форматом и форматом JSON ClickHouse.

Клиент поддерживает потоковую передачу JSON объектов с форматами, такими как JSONEachRow (смотрите обзор таблицы для других форматов, благоприятствующих потоковой передаче; также смотрите примеры select_streaming_ в репозитории клиента здесь).

Только форматы, такие как ClickHouse JSON и несколько других, представлены в виде единого объекта в ответе и не могут быть переданы клиентом в потоке.

ФорматВвод (массив)Ввод (объект)Ввод/вывод (Поток)Вывод (JSON)Вывод (текст)
JSON✔️✔️✔️
JSONCompact✔️✔️✔️
JSONObjectEachRow✔️✔️✔️
JSONColumnsWithMetadata✔️✔️✔️
JSONStrings✔️✔️
JSONCompactStrings✔️✔️
JSONEachRow✔️✔️✔️✔️
JSONEachRowWithProgress✔️ ❗- см. ниже✔️✔️
JSONStringsEachRow✔️✔️✔️✔️
JSONCompactEachRow✔️✔️✔️✔️
JSONCompactStringsEachRow✔️✔️✔️✔️
JSONCompactEachRowWithNames✔️✔️✔️✔️
JSONCompactEachRowWithNamesAndTypes✔️✔️✔️✔️
JSONCompactStringsEachRowWithNames✔️✔️✔️✔️
JSONCompactStringsEachRowWithNamesAndTypes✔️✔️✔️✔️
CSV✔️✔️
CSVWithNames✔️✔️
CSVWithNamesAndTypes✔️✔️
TabSeparated✔️✔️
TabSeparatedRaw✔️✔️
TabSeparatedWithNames✔️✔️
TabSeparatedWithNamesAndTypes✔️✔️
CustomSeparated✔️✔️
CustomSeparatedWithNames✔️✔️
CustomSeparatedWithNamesAndTypes✔️✔️
Parquet✔️✔️❗- см. ниже

Для Parquet основной сценарий использования для выборок, вероятно, будет запись результирующего потока в файл. Смотрите пример в репозитории клиента.

JSONEachRowWithProgress - это формат только для вывода, который поддерживает отчетность о прогрессе в потоке. Смотрите этот пример для получения дополнительных сведений.

Полный список входных и выходных форматов ClickHouse доступен здесь.

Поддерживаемые типы данных ClickHouse

примечание

Связанный тип JS актуален для всех форматов JSON*, кроме тех, которые представляют все в виде строки (например, JSONStringEachRow)

ТипСтатусТип JS
UInt8/16/32✔️number
UInt64/128/256✔️ ❗- см. нижеstring
Int8/16/32✔️number
Int64/128/256✔️ ❗- см. нижеstring
Float32/64✔️number
Decimal✔️ ❗- см. нижеnumber
Boolean✔️boolean
String✔️string
FixedString✔️string
UUID✔️string
Date32/64✔️string
DateTime32/64✔️ ❗- см. нижеstring
Enum✔️string
LowCardinality✔️string
Array(T)✔️T[]
(новый) JSON✔️object
Variant(T1, T2...)✔️T (зависит от варианта)
Dynamic✔️T (зависит от варианта)
Nested✔️T[]
Tuple✔️Tuple
Nullable(T)✔️Тип JS для T или null
IPv4✔️string
IPv6✔️string
Point✔️[ number, number ]
Ring✔️Array<Point>
Polygon✔️Array<Ring>
MultiPolygon✔️Array<Polygon>
Map(K, V)✔️Record<K, V>

Полный список поддерживаемых форматов ClickHouse доступен здесь.

Предостережения по типам Date/Date32

Поскольку клиент вставляет значения без дополнительного преобразования типов, столбцы типов Date/Date32 могут быть вставлены только как строки.

Пример: Вставка значения типа Date. Исходный код.

Тем не менее, если вы используете столбцы DateTime или DateTime64, вы можете использовать как строки, так и объекты Date JS. Объекты Date JS могут быть переданы в insert как есть с установленным date_time_input_format на best_effort. Смотрите этот пример для получения дополнительных сведений.

Предостережения по типам Decimal*

Можно вставлять Decimals, используя форматы семейства JSON*. Предположим, у нас есть таблица, определенная как:

Мы можем вставить значения без потери точности, используя строковое представление:

Однако, при запросе данных в форматах JSON* ClickHouse вернет Decimals как числа по умолчанию, что может привести к потере точности. Чтобы избежать этого, вы можете привести Decimals к строкам в запросе:

Смотрите этот пример для получения дополнительных сведений.

Целочисленные типы: Int64, Int128, Int256, UInt64, UInt128, UInt256

Хотя сервер может принимать их как числа, они возвращаются как строки в форматах выходных данных семейства JSON*, чтобы избежать переполнения целых чисел, так как максимальные значения для этих типов больше, чем Number.MAX_SAFE_INTEGER.

Тем не менее, это поведение может быть изменено с помощью output_format_json_quote_64bit_integers настройки .

Пример: Настройка формата JSON для вывода 64-битных чисел.

Настройки ClickHouse

Клиент может настраивать поведение ClickHouse с помощью механизма настроек. Настройки могут быть установлены на уровне экземпляра клиента, чтобы они применялись к каждому запросу, отправленному в ClickHouse:

Или настройка может быть настроена на уровне запроса:

Файл определения типов, содержащий все поддерживаемые настройки ClickHouse, можно найти здесь.

к сведению

Убедитесь, что у пользователя, от имени которого выполняются запросы, достаточно прав для изменения настроек.

Расширенные темы

Запросы с параметрами

Вы можете создать запрос с параметрами и передать значения от клиентского приложения. Это позволяет избежать форматирования запроса с конкретными динамическими значениями на стороне клиента.

Форматируйте запрос, как обычно, затем поместите значения, которые вы хотите передать из приложения, в фигурные скобки в следующем формате:

где:

  • name — идентификатор заполнителя.
  • data_type - Тип данных значения параметра приложения.

Пример: Запрос с параметрами. Исходный код.

Смотрите https://clickhouse.com/docs/interfaces/cli#cli-queries-with-parameters-syntax для получения дополнительных сведений.

Сжатие

Обратите внимание: сжатие запросов в настоящее время недоступно в веб-версии. Ответное сжатие работает как обычно. Версия Node.js поддерживает оба.

Приложения для работы с большими наборами данных через сеть могут получить выгоду от включения сжатия. В настоящее время поддерживается только GZIP, используя zlib.

Параметры конфигурации:

  • response: true указывает серверу ClickHouse отвечать с сжатым телом ответа. Значение по умолчанию: response: false
  • request: true включает сжатие тела запроса клиента. Значение по умолчанию: request: false

Логирование (только Node.js)

к сведению

Логирование является экспериментальной функцией и может измениться в будущем.

Реализация по умолчанию генерирует записи журналов в stdout с помощью методов console.debug/info/warn/error. Вы можете настроить логику логирования, предоставив LoggerClass, и выбрать желаемый уровень журнала через параметр level (по умолчанию OFF):

В настоящее время клиент будет записывать следующие события:

  • TRACE - информация низкого уровня о жизненном цикле сокетов Keep-Alive
  • DEBUG - информация о ответе (без заголовков авторизации и информации о хосте)
  • INFO - в основном не используется, выводит текущий уровень журнала при инициализации клиента
  • WARN - нефатальные ошибки; неудачный запрос ping записывается как предупреждение, так как связанная ошибка включена в возвращаемый результат
  • ERROR - фатальные ошибки из методов query/insert/exec/command, такие как неудачный запрос

Вы можете найти реализацию по умолчанию для Logger здесь.

TLS-сертификаты (только Node.js)

Клиент Node.js дополнительно поддерживает как базовый (только удостоверяющий центр), так и взаимный (удостоверяющий центр и клиентские сертификаты) TLS.

Пример базовой конфигурации TLS, предполагая, что у вас есть сертификаты в папке certs и файл CA называется CA.pem:

Пример конфигурации взаимного TLS с использованием клиентских сертификатов:

Смотрите полные примеры для базового и взаимного TLS в репозитории.

Настройка Keep-Alive (только Node.js)

Клиент по умолчанию включает Keep-Alive в основном HTTP-агенте, что означает, что подключенные сокеты будут повторно использоваться для последующих запросов, и заголовок Connection: keep-alive будет отправлен. Сокеты, находящиеся в режиме ожидания, останутся в пуле соединений на 2500 миллисекунд по умолчанию (см. замечания о настройке этой опции).

keep_alive.idle_socket_ttl должен иметь значение, значительно меньшее, чем конфигурация сервера/LB. Основная причина в том, что в HTTP/1.1 сервер может закрыть сокеты без уведомления клиента; если сервер или балансировщик нагрузки закроют соединение до того, как клиент, клиент может попытаться повторно использовать закрытый сокет, что приведет к ошибке socket hang up.

Если вы изменяете keep_alive.idle_socket_ttl, учтите, что он всегда должен быть согласован с вашей конфигурацией Keep-Alive сервера/LB, и он должен быть всегда ниже, чтобы обеспечить, чтобы сервер никогда не закрывал открытое соединение первым.

Корректировка idle_socket_ttl

Клиент устанавливает keep_alive.idle_socket_ttl на 2500 миллисекунд, так как это можно считать самым безопасным значением по умолчанию; на стороне сервера keep_alive_timeout может быть установлен настолько низко как 3 секунды в версиях ClickHouse до 23.11 без изменений в config.xml.

осторожно

Если вас устраивает производительность и вы не испытываете никаких проблем, рекомендуется не увеличивать значение настройки keep_alive.idle_socket_ttl, так как это может привести к потенциальным ошибкам "Socket hang-up"; кроме того, если ваше приложение отправляет много запросов и между ними не так много времени простоя, значение по умолчанию должно быть достаточным, поскольку сокеты не будут достаточно долго бездействовать, и клиент будет удерживать их в пуле.

Вы можете найти правильное значение таймаута Keep-Alive в заголовках ответа сервера, выполнив следующую команду:

Проверьте значения заголовков Connection и Keep-Alive в ответе. Например:

В этом случае keep_alive_timeout составляет 10 секунд, и вы можете попробовать увеличить keep_alive.idle_socket_ttl до 9000 или даже 9500 миллисекунд, чтобы поддерживать сокеты в режиме ожидания открытыми немного дольше, чем по умолчанию. Следите за потенциальными ошибками "Socket hang-up", которые укажут на то, что сервер закрывает соединения раньше, чем клиент, и снижайте значение, пока ошибки не исчезнут.

Устранение неполадок Keep-Alive

Если вы сталкиваетесь с ошибками socket hang up при использовании Keep-Alive, рассмотрите следующие варианты для решения этой проблемы:

  • Немного уменьшите значение настройки keep_alive.idle_socket_ttl в конфигурации сервера ClickHouse. В некоторых ситуациях, например, при высокой сетевой задержке между клиентом и сервером, может быть полезно уменьшить keep_alive.idle_socket_ttl еще на 200-500 миллисекунд, исключив ситуацию, когда исходящий запрос может получить сокет, который сервер собирается закрыть.

  • Если эта ошибка возникает во время длительных запросов, когда нет данных, поступающих внутрь или наружу (например, длительный INSERT FROM SELECT), это может быть связано с тем, что балансировщик нагрузки закрывает неактивные соединения. Вы можете попробовать заставить некоторые данные поступать во время длительных запросов, используя комбинацию следующих настроек ClickHouse:

    Тем не менее, учтите, что общий размер полученных заголовков имеет лимит в 16КБ в недавних версиях Node.js; после определенного количества полученных заголовков прогресса, которое в наших тестах составило около 70-80, будет сгенерировано исключение.

    Также возможно использовать совершенно другой подход, полностью избегая времени ожидания на сети; это может быть сделано с помощью "функции" HTTP интерфейса, что мутации не отменяются, когда соединение потеряно. Смотрите этот пример (часть 2) для получения дополнительных подробностей.

  • Функцию Keep-Alive можно отключить полностью. В этом случае клиент также добавит заголовок Connection: close к каждому запросу, и нижележащий HTTP-агент не будет повторно использовать соединения. Настройка keep_alive.idle_socket_ttl будет игнорироваться, так как не будет неактивных сокетов. Это приведет к дополнительным накладным расходам, так как для каждого запроса будет устанавливаться новое соединение.

Пользователи только для чтения

При использовании клиента с readonly=1 пользователем сжатие ответа нельзя включить, так как это требует настройки enable_http_compression. Следующая конфигурация приведет к ошибке:

Смотрите пример, который содержит больше информации о ограничениях пользователя readonly=1.

Прокси с путём

Если ваш экземпляр ClickHouse находится за прокси и в URL есть путь, например, http://proxy:8123/clickhouse_server, укажите clickhouse_server как параметр конфигурации pathname (с или без ведущего слэша); в противном случае, если он предоставлен напрямую в url, он будет считаться параметром database. Поддерживаются несколько сегментов, например, /my_proxy/db.

Обратный прокси с аутентификацией

Если у вас есть обратный прокси с аутентификацией перед вашим развертыванием ClickHouse, вы можете использовать настройку http_headers, чтобы предоставить необходимые заголовки:

Пользовательский HTTP/HTTPS-агент (экспериментально, только Node.js)

осторожно

Это экспериментальная функция, которая может измениться в обратном несовместимом виде в будущих релизах. Стандартная реализация и настройки, предоставляемые клиентом, должны быть достаточно для большинства случаев использования. Используйте эту функцию только если вы уверены, что она вам нужна.

По умолчанию, клиент будет настраивать нижележащий HTTP(s) агент, используя настройки, предоставленные в конфигурации клиента (такие как max_open_connections, keep_alive.enabled, tls), который будет обрабатывать соединения с сервером ClickHouse. Кроме того, если используются TLS сертификаты, нижележащий агент будет настроен с необходимыми сертификатами, и правильные заголовки аутентификации TLS будут применены.

После версии 1.2.0, возможно предоставить пользовательский HTTP(s) агент клиенту, заменяя стандартный нижележащий. Это может быть полезно в случае сложных сетевых конфигураций. Если предоставлен пользовательский агент, действуют следующие условия:

  • Опции max_open_connections и tls не будут оказывать никакого эффекта и будут игнорироваться клиентом, так как это часть конфигурации нижележащего агента.
  • keep_alive.enabled будет регулировать лишь стандартное значение заголовка Connection (true -> Connection: keep-alive, false -> Connection: close).
  • В то время как управление неактивными сокетами keep-alive все еще будет работать (так как оно не связано с агентом, а с конкретным сокетом), теперь возможно полностью отключить его, установив значение keep_alive.idle_socket_ttl в 0.

Примеры использования пользовательского агента

Использование пользовательского HTTP(s) агента без сертификатов:

Использование пользовательского HTTPS агента с базовым TLS и сертификатом CA:

Использование пользовательского HTTPS агента с взаимной TLS:

С сертификатами и пользовательским HTTPS агентом, вероятно, необходимо отключить стандартный заголовок аутентификации через настройку set_basic_auth_header (введена в 1.2.0), так как она конфликтует с заголовками TLS. Все заголовки TLS должны быть предоставлены вручную.

Известные ограничения (Node.js/Веб)

  • Нет мапперов данных для наборов результатов, поэтому используются только примитивы языка. Определенные мапперы типов данных запланированы с поддержкой формата RowBinary.
  • Есть некоторые особенности типов данных Decimal* и Date* / DateTime*.
  • При использовании форматов семейства JSON* числа, большие чем Int32, представляются как строки, так как максимальные значения типов Int64+ больше, чем Number.MAX_SAFE_INTEGER. Смотрите раздел Целые типы для получения дополнительных подробностей.

Известные ограничения (Веб)

  • Потоковая передача для запросов select работает, но отключена для вставок (на уровне типа тоже).
  • Сжатие запроса отключено, и конфигурация игнорируется. Сжатие ответа работает.
  • Поддержка журналирования пока отсутствует.

Советы по оптимизации производительности

  • Для снижения потребления памяти приложением рассмотрите возможность использования потоков для больших вставок (например, из файлов) и выборок, когда это применимо. Для обработчиков событий и похожих случаев, асинхронные вставки могут быть еще одним хорошим вариантом, позволяя минимизировать, или даже полностью избежать пакетирования на стороне клиента. Примеры асинхронных вставок доступны в репозитории клиента, с префиксом имени файла async_insert_.
  • Клиент по умолчанию не включает сжатие запросов или ответов. Тем не менее, при выборе или вставке больших наборов данных вы можете рассмотреть возможность его включения через ClickHouseClientConfigOptions.compression (либо только для request, либо для response, либо для обоих).
  • Сжатие имеет значительный штраф по производительности. Включение его для request или response негативно повлияет на скорость выборок или вставок соответственно, но уменьшит объем сетевого трафика, передаваемого приложением.

Связаться с нами

Если у вас есть вопросы или вам нужна помощь, не стесняйтесь обращаться к нам в Community Slack (канал #clickhouse-js) или через GitHub issues.