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.12.0 | 24.8+ |
Скорее всего, клиент будет работать и с более старыми версиями; однако это поддерживаемая версия, и гарантий нет. Если у вас версия ClickHouse старше 23.3, пожалуйста, ознакомьтесь с политикой безопасности ClickHouse и подумайте о выполнении обновления.
Примеры
Мы стремимся рассмотреть различные сценарии использования клиента в примерах в репозитории клиента.
Обзор доступен в README примеров.
Если что-то неясно или отсутствует в примерах или в следующей документации, не стесняйтесь связаться с нами.
API клиента
Большинство примеров должны быть совместимы как с Node.js, так и с веб-версией клиента, если не указано иное.
Создание экземпляра клиента
Вы можете создать сколько угодно экземпляров клиента с помощью фабрики createClient
:
Если ваша среда не поддерживает модули ESM, вы можете использовать синтаксис CJS вместо этого:
Экземпляр клиента может быть предварительно настроен при его создании.
Конфигурация
При создании экземпляра клиента можно настроить следующие параметры подключения:
Параметр | Описание | Значение по умолчанию | См. Также |
---|---|---|---|
url?: string | URL экземпляра 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 и Web. | - | - |
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¶m2=value2]
. В почти каждом случае имя конкретного параметра отражает его путь в интерфейсе параметров конфигурации, с несколькими исключениями. Поддерживаются следующие параметры:
Параметр | Тип |
---|---|
pathname | произвольная строка. |
application_id | произвольная строка. |
session_id | произвольная строка. |
request_timeout | неотрицательное число. |
max_open_connections | неотрицательное число, больше нуля. |
compression_request | булево. См. ниже (1) |
compression_response | булево. |
log_level | допустимые значения: OFF , TRACE , DEBUG , INFO , WARN , ERROR . |
keep_alive_enabled | булево. |
clickhouse_setting_* или ch_* | см. ниже (2) |
http_header_* | см. ниже (3) |
(только для Node.js) keep_alive_idle_socket_ttl | неотрицательное число. |
- (1) Для булевых значений допустимыми значениями будут
true
/1
иfalse
/0
. - (2) Любой параметр, начинающийся с
clickhouse_setting_
илиch_
, будет иметь этот префикс удален, а остальная часть добавлена в настройки клиентаclickhouse_settings
. Например,?ch_async_insert=1&ch_wait_for_async_insert=1
будет равносильно:
Примечание: булевые значения для clickhouse_settings
должны передаваться как 1
/0
в URL.
- (3) Аналогично (2), но для конфигурации
http_header
. Например,?http_header_x-clickhouse-auth=foobar
будет эквивалентно:
Подключение
Соберите детали подключения
Чтобы подключиться к ClickHouse с помощью HTTP(S), вам необходима следующая информация:
-
ХОСТ и ПОРТ: как правило, порт 8443 при использовании TLS или 8123 при отсутствии TLS.
-
ИМЯ БАЗЫ ДАННЫХ: по умолчанию существует база данных с именем
default
, используйте имя базы данных, к которой вы хотите подключиться. -
ИМЯ ПОЛЬЗОВАТЕЛЯ и ПАРОЛЬ: по умолчанию имя пользователя
default
. Используйте имя пользователя, подходящее для вашего случая.
Данные для вашего сервиса ClickHouse Cloud доступны в консоли ClickHouse Cloud. Выберите сервис, к которому вы хотите подключиться, и нажмите Подключиться:

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

Если вы используете самоуправляемый 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.
Идентификатор запроса
Каждый метод, который отправляет запрос или оператор (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
, и должен ожидаться. Ожидается, что возвращаемый набор результатов будет использован в приложении.
См. также: Базовые параметры для всех методов клиента.
Не указывайте оператор FORMAT в 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 для получения дополнительной информации.
Пример: (только Web) Итерация по ReadableStream
объектов.
Метод вставки
Это основной метод для вставки данных.
Возвращаемый тип минимален, так как мы не ожидаем, что сервер вернет какие-либо данные, и немедленно очищаем поток ответа.
Если пустой массив был передан в метод вставки, оператор вставки не будет отправлен на сервер; вместо этого метод сразу разрешится с { query_id: '...', executed: false }
. Если query_id
не был предоставлен в параметрах метода в этом случае, он будет пустой строкой в результате, так как возврат случайного UUID, сгенерированного клиентом, может вызвать путаницу, поскольку запрос с таким query_id
не будет существовать в таблице system.query_log
.
Если оператор вставки был отправлен на сервер, флаг executed
будет равен true
.
Метод вставки и потоковая передача в Node.js
Он может работать либо с Stream.Readable
, либо с обычным Array<T>
, в зависимости от формата данных, указанного в методе insert
. См. также этот раздел о файловой потоковой передаче.
Метод вставки должен ожидаться; однако возможно указать вводный поток и дождаться операции insert
позже, только когда поток завершится (что также разрешит промис insert
). Это может быть полезно для обработчиков событий и подобных сценариев, но обработка ошибок может быть нетривиальной с множеством нестандартных случаев на стороне клиента. Вместо этого рассмотрите возможность использования асинхронных вставок, как показано в этом примере.
Если у вас есть собственный оператор INSERT, который сложно смоделировать с помощью этого метода, рассмотрите возможность использования метода command.
Вы можете посмотреть, как он используется в примерах INSERT INTO ... VALUES или INSERT INTO ... SELECT.
См. также: Базовые параметры для всех методов клиента.
Запрос, отмененный с помощью abort_signal
, не гарантирует, что вставка данных не произошла, поскольку сервер мог получить часть передаваемых данных до отмены.
Пример: (Node.js/Web) Вставить массив значений. Исходный код.
Пример: (только Node.js) Вставка потока из CSV файла. Исходный код. См. также: поточная передача файлов.
Пример: Исключение определенных столбцов из оператора вставки.
С учетом такого определения таблицы:
Вставить только определенный столбец:
Исключите определенные столбцы:
Смотрите исходный код для получения дополнительных деталей.
Пример: Вставить в базу данных, отличную от той, что указана экземпляру клиента. Исходный код.
Ограничения веб-версии
В настоящее время вставки в @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) INSERT FROM SELECT
Запрос, отмененный с помощью abort_signal
, не гарантирует, что оператор не был выполнен сервером.
Метод exec
Если у вас есть собственный запрос, который не подходит для query
/insert
,
и вас интересует результат, вы можете использовать exec
как альтернативу command
.
exec
возвращает читаемый поток, который ДОЛЖЕН быть использован или уничтожен на стороне приложения.
См. также: Базовые параметры для всех методов клиента.
Тип возвращаемого потока отличается в версиях Node.js и Web.
Node.js:
Web:
Ping
Метод ping
, предназначенный для проверки статуса подключения, возвращает true
, если сервер доступен.
Если сервер недоступен, подлежающая ошибка также включается в результат.
Ping может быть полезным инструментом для проверки доступности сервера, когда приложение запускается, особенно с ClickHouse Cloud, где экземпляр может быть в ожидании и проснется после пинга: в этом случае вы можете попробовать снова несколько раз с задержкой между попытками.
Обратите внимание, что по умолчанию версия для Node.js использует конечную точку /ping
, в то время как веб-версия использует простой запрос SELECT 1
, чтобы достичь аналогичного результата, так как конечная точка /ping
не поддерживает CORS.
Пример: (Node.js/Web) Простой ping к экземпляру сервера ClickHouse. Примечание: для веб-версии захваченные ошибки будут различаться. Исходный код.
Пример: Если вы хотите также проверить учетные данные при вызове метода ping
, или указать дополнительные параметры, такие как query_id
, вы можете использовать его следующим образом:
Метод ping позволит использовать большинство стандартных параметров метода query
- смотрите определение типов PingParamsWithSelectQuery
.
Закрытие (только Node.js)
Закрывает все открытые соединения и освобождает ресурсы. Не выполняет никаких операций в веб-версии.
Потоковые файлы (только Node.js)
В репозитории клиента есть несколько примеров потоковой передачи файлов с популярными форматами данных (NDJSON, CSV, Parquet).
- Потоковая передача из файла NDJSON
- Потоковая передача из файла CSV
- Потоковая передача из файла Parquet
- Потоковая передача в файл 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[] |
(new) JSON | ✔️ | object |
Variant(T1, T2...) | ✔️ | T (в зависимости от варианта) |
Dynamic | ✔️ | T (в зависимости от варианта) |
Nested | ✔️ | T[] |
Tuple(T1, T2, ...) | ✔️ | [T1, T2, ...] |
Tuple(n1 T1, n2 T2...) | ✔️ | { n1: T1; n2: T2; ...} |
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> |
Time/Time64 | ✔️ | string |
Полный список поддерживаемых форматов ClickHouse доступен здесь.
Смотрите также:
Предупреждения по типам Date/Date32
Так как клиент вставляет значения без дополнительного преобразования типов, столбцы типа Date
/Date32
могут быть вставлены только как строки.
Пример: Вставить значение типа Date
.
Исходный код
Тем не менее, если вы используете столбцы DateTime
или DateTime64
, вы можете использовать как строки, так и объекты даты JS. Объекты даты JS могут быть переданы в insert
без изменений с установленным date_time_input_format
в значение best_effort
. Смотрите этот пример для получения более подробной информации.
Предупреждения по типам Decimal*
Можно вставлять Decimal с использованием форматов семейства 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 для получения дополнительных деталей.
Сжатие
NB: сжатие запросов в настоящее время недоступно в веб-версии. Сжатие ответов работает как обычно. Версия для 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-AliveDEBUG
- информация о ответах (без заголовков аутентификации и информации о хосте)INFO
- в основном не используется, будет выводить текущий уровень журнала при инициализации клиентаWARN
- нефатальные ошибки; неудачный запросping
регистрируется как предупреждение, так как основанная ошибка включена в возвращаемый результатERROR
- фатальные ошибки из методовquery
/insert
/exec
/command
, такие как неудачный запрос
Вы можете найти реализацию логгера по умолчанию здесь.
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
должно иметь значение значительно ниже, чем конфигурация сервера/балансировщика нагрузки. Основная причина заключается в том, что из-за HTTP/1.1 сервер может закрывать сокеты без уведомления клиента; если сервер или балансировщик нагрузки закрывает соединение до того, как клиент, клиент может пытаться повторно использовать закрытый сокет, что приведет к ошибке socket hang up
.
Если вы изменяете keep_alive.idle_socket_ttl
, имейте в виду, что оно всегда должно быть синхронизировано с вашей конфигурацией Keep-Alive на сервере/балансировщике нагрузки, и оно должно быть всегда ниже этого значения, обеспечивая тем самым, что сервер никогда не закрывает открытое соединение первым.
Настройка 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", которые будут указывать на то, что сервер закрывает соединения раньше клиента, и уменьшайте значение, пока ошибки не исчезнут.
Устранение неполадок
Если вы испытываете ошибки socket hang up
, даже используя последнюю версию клиента, есть несколько вариантов решения этой проблемы:
- Включите логи с уровнем журнала не ниже
WARN
. Это позволит проверить, есть ли в коде приложения неиспользуемый или зависший поток: уровень транспортного слоя будет регистрировать это на уровне WARN, так как это может привести к закрытию сокета сервером. Вы можете включить логирование в конфигурации клиента следующим образом:
-
Проверьте ваш код приложения с включенным правилом ESLint no-floating-promises, которое поможет выявить необработанные промисы, которые могут привести к зависшим потокам и сокетам.
-
Немного уменьшите значение настройки
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/web)
- Нет сопоставителей данных для наборов результатов, используются только примитивы языка. Определённые сопоставители типов данных запланированы с поддержкой RowBinary формата.
- Существуют некоторые предупреждения по типам Decimal* и Date* / DateTime*.
- Когда используются форматы семейства JSON*, числа больше Int32 представляются как строки, так как максимальные значения типов Int64+ больше
Number.MAX_SAFE_INTEGER
. См. раздел Целочисленные типы для получения более подробной информации.
Известные ограничения (web)
- Потоковая передача для выборок работает, но отключена для вставок (на уровне типов также).
- Сжатие запросов отключено, и конфигурация игнорируется. Сжатие ответов работает.
- Поддержка логирования пока отсутствует.
Советы по оптимизации производительности
- Для уменьшения потребления памяти приложением рассмотрите возможность использования потоков для больших вставок (например, из файлов) и выборок, когда это возможно. Для слушателей событий и аналогичных сценариев асинхронные вставки могут быть еще одной хорошей опцией, позволяя минимизировать или даже полностью избежать пакетной обработки на стороне клиента. Примеры асинхронных вставок доступны в репозитории клиента, с префиксом
async_insert_
в названии файла. - Клиент по умолчанию не включает сжатие запросов или ответов. Однако при выборке или вставке больших наборов данных вы можете рассмотреть возможность включения его через
ClickHouseClientConfigOptions.compression
(либо только дляrequest
, либо дляresponse
, либо для обоих). - Сжатие имеет значительные потери производительности. Включение его для
request
илиresponse
негативно скажется на скорости выборок или вставок соответственно, но уменьшит объем сетевого трафика, передаваемого приложением.
Свяжитесь с нами
Если у вас есть вопросы или нужна помощь, не стесняйтесь обращаться к нам в Community Slack (канал #clickhouse-js
) или через GitHub issues.