Перейти к основному содержанию
Официальный JS-клиент для подключения к ClickHouse. Клиент написан на TypeScript и предоставляет типы для публичного API клиента. У него нет зависимостей, он оптимизирован для максимальной производительности и протестирован с различными версиями и конфигурациями ClickHouse (одиночный узел в собственной инфраструктуре, кластер в собственной инфраструктуре и ClickHouse Cloud). Доступны две версии клиента для разных сред:
  • @clickhouse/client - только для Node.js
  • @clickhouse/client-web - браузеры (Chrome/Firefox), Cloudflare workers
При использовании TypeScript убедитесь, что используется как минимум версия 4.5, в которой поддерживается встроенный синтаксис import и export. Исходный код клиента доступен в репозитории ClickHouse-JS на GitHub.
Навыки AI agentJS-клиент включает навыки AI agent, которые помогают агентам для написания кода работать с клиентом. Установите их командой:

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

Для запуска клиента в окружении должен быть доступен Node.js. Клиент совместим со всеми поддерживаемыми версиями Node.js. Как только версия Node.js приближается к окончанию жизненного цикла, клиент прекращает её поддержку, поскольку она считается устаревшей и небезопасной. Сейчас поддерживаются следующие версии Node.js:

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

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

Установка

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

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

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

Примеры

Мы стремимся охватить различные сценарии использования клиента в примерах в репозитории клиента. Обзор доступен в README с примерами. Если в примерах или в приведённой ниже документации что-то непонятно либо чего-то не хватает, не стесняйтесь связаться с нами.

API клиента

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

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

При необходимости можно создать любое количество экземпляров клиента с помощью фабрики createClient:
Если ваша среда не поддерживает модули ESM, вместо них можно использовать синтаксис CJS:
При создании экземпляр клиента можно предварительно настроить.

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

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

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

Настройка URL

Настройка URL всегда переопределяет значения, жестко заданные в коде, и в этом случае в журнал будет записано предупреждение.
Большинство параметров экземпляра клиента можно настроить через URL. Формат URL: http[s]://[username:password@]hostname:port[/database][?param1=value1&param2=value2]. Почти во всех случаях имя конкретного параметра соответствует его пути в интерфейсе параметров конфигурации, за несколькими исключениями. Поддерживаются следующие параметры:
  • (1) Для логических значений допустимы true/1 и false/0.
  • (2) У любого параметра с префиксом clickhouse_setting_ или ch_ этот префикс будет удален, а оставшаяся часть добавлена в clickhouse_settings клиента. Например, ?ch_async_insert=1&ch_wait_for_async_insert=1 эквивалентно:
Примечание: логические значения для clickhouse_settings следует передавать в URL как 1/0.
  • (3) Аналогично (2), но для конфигурации http_header. Например, ?http_header_x-clickhouse-auth=foobar будет эквивалентен:

Подключение

Подготовьте сведения о подключении

Чтобы подключиться к ClickHouse по HTTP(S), вам понадобится следующая информация: Сведения о подключении для вашего сервиса ClickHouse Cloud доступны в консоли ClickHouse Cloud. Выберите сервис и нажмите Connect: Выберите HTTPS. Сведения о подключении будут показаны в примере команды curl. Если вы используете самоуправляемый ClickHouse, сведения о подключении задаёт ваш администратор ClickHouse.

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

Клиент поддерживает подключение по протоколу HTTP или HTTPS. Поддержка RowBinary находится в разработке, см. соответствующий issue. Следующий пример показывает, как настроить подключение к ClickHouse Cloud. Предполагается, что значения url (включая протокол и порт) и password заданы через переменные окружения, а также используется пользователь default. Пример: создание экземпляра клиента Node.js с использованием переменных окружения для настройки.
В репозитории клиента есть несколько примеров, в которых используются переменные окружения, например создание таблицы в ClickHouse Cloud, использование асинхронных вставок и ряд других.

Пул соединений (только Node.js)

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

Query ID

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

Общий параметр для всех клиентских методов

Для всех клиентских методов (query/command/insert/exec) доступно несколько общих параметров.

Метод query

Этот метод используется для большинства команд, которые могут возвращать ответ, например SELECT, а также для отправки DDL-запросов, таких как CREATE TABLE, поэтому его нужно вызывать с await. Предполагается, что возвращённый результирующий набор будет обрабатываться в приложении.
Для вставки данных есть отдельный метод insert, а для DDL-запросов — command.
См. также: Общий параметр для всех клиентских методов.
Не указывайте предложение FORMAT в query, вместо этого используйте параметр format.

Абстракции результирующего набора и строки

ResultSet предоставляет несколько удобных методов для обработки данных в приложении. Реализация ResultSet для Node.js использует Stream.Readable, а веб-версия — Web API ReadableStream. Вы можете прочитать ResultSet, вызвав методы text или json, и загрузить в память весь набор строк, возвращённый запросом. Начинать чтение 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'), но может негативно сказаться на производительности. Подробнее см. в этом issue в репозитории Node.js.
Пример: (Только для Web) Итерация по ReadableStream объектов.

Метод INSERT

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

Метод INSERT и стриминг в Node.js

Этот метод может работать либо с Stream.Readable, либо с обычным Array<T> — в зависимости от формата данных, указанного для метода insert. См. также раздел о потоковой передаче файлов. Метод INSERT следует вызывать с await; однако можно передать входной поток и дождаться завершения операции 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>:
В будущем это может измениться. См. также: Общий параметр для всех клиентских методов.

Метод Command

Его можно использовать для команд без вывода, когда предложение FORMAT неприменимо или когда ответ вас вообще не интересует. Пример такой команды — CREATE TABLE или ALTER TABLE. Его следует вызывать с await. Поток ответа немедленно закрывается, а базовый сокет освобождается.
См. также: Общий параметр для всех клиентских методов. Пример: (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 и веб-версии. Node.js:
Веб:

Ping

Метод ping, предназначенный для проверки состояния подключения, возвращает true, если сервер доступен. Если сервер недоступен, в результат также включается исходная ошибка.
Ping может быть полезным способом проверить, доступен ли сервер при запуске приложения, особенно с ClickHouse Cloud, где инстанс может находиться в режиме простоя и «проснуться» после ping. В таком случае может иметь смысл повторить попытку несколько раз с задержкой между ними. Обратите внимание: по умолчанию версия для Node.js использует конечную точку /ping, а веб-версия — простой запрос SELECT 1, чтобы добиться аналогичного результата, поскольку конечная точка /ping не поддерживает CORS. Пример: (Node.js/Web) Простой ping инстанса сервера ClickHouse. Примечание: в веб-версии перехваченные ошибки будут отличаться. Исходный код.
Пример: Если вы хотите при вызове метода ping также проверять учетные данные или указывать дополнительные параметры, такие как query_id, это можно сделать следующим образом:
Метод ping поддерживает большинство стандартных параметров метода query — см. определение типа PingParamsWithSelectQuery.

Close (только Node.js)

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

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

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

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

Клиент работает с форматами данных JSON и текста. Если указать format как один из форматов семейства JSON (JSONEachRow, JSONCompactEachRow и т. д.), клиент будет сериализовать и десериализовать данные при передаче по сети. Данные в “сырых” текстовых форматах (семейства CSV, TabSeparated и CustomSeparated) передаются по сети без дополнительных преобразований.
Возможна путаница между JSON как форматом в целом и форматом ClickHouse JSON.Клиент поддерживает потоковую обработку объектов JSON в таких форматах, как JSONEachRow (другие форматы, подходящие для стриминга, см. в таблице ниже; также см. select_streaming_ примеры в репозитории клиента).Дело лишь в том, что такие форматы, как ClickHouse JSON, и некоторые другие возвращаются в ответе как единый объект, поэтому клиент не может обрабатывать их в потоковом режиме.
Для Parquet основной сценарий использования select, вероятно, — запись результирующего потока в файл. См. пример в репозитории клиента. JSONEachRowWithProgress — это формат только для вывода, поддерживающий передачу информации о Прогрессе в потоке. Подробнее см. в этом примере. Полный список форматов ввода и вывода ClickHouse доступен здесь.

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

Соответствующий тип JS применим ко всем форматам JSON*, кроме тех, которые представляют всё в виде строки (например, JSONStringEachRow)
Полный список поддерживаемых форматов ClickHouse доступен здесь. См. также:

Ограничения типов Date/Date32

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

Особенности типов Decimal*

Значения Decimal можно вставлять с помощью форматов семейства JSON*. Предположим, у нас есть таблица, определённая следующим образом:
Мы можем вставлять значения без потери точности, используя их строковое представление:
Однако при запросе данных в форматах JSON* ClickHouse по умолчанию возвращает значения Decimal как числа, что может привести к потере точности. Чтобы этого избежать, в запросе можно привести значения Decimal к строке:
См. этот пример для более подробной информации.

Целочисленные типы: 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 поддерживает и то и другое. Приложения для работы с данными, передающие по сети большие объёмы данных, могут выиграть от включения сжатия. В настоящее время через zlib поддерживается только GZIP.
Параметры конфигурации:
  • response: true указывает ClickHouse server возвращать сжатое тело ответа. Значение по умолчанию: response: false
  • request: true включает сжатие тела запроса клиента. Значение по умолчанию: request: false

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

Логирование — экспериментальная возможность и в будущем может измениться.
Реализация логгера по умолчанию выводит записи журнала в stdout через методы console.debug/info, а в stderr — через методы console.warn/error. Вы можете настроить логику логирования, указав LoggerClass, и выбрать нужный уровень логирования с помощью параметра level (по умолчанию — WARN):
В настоящее время клиент записывает в журнал следующие события:
  • TRACE - низкоуровневая информация о жизненном цикле сокетов Keep-Alive
  • DEBUG - информация об ответе (без заголовков авторизации и сведений о хосте)
  • INFO - в основном не используется; при инициализации клиента выводит текущий уровень логирования
  • WARN - нефатальные ошибки; неудачный запрос ping записывается как предупреждение, поскольку исходная ошибка включается в возвращаемый результат
  • ERROR - фатальные ошибки в методах query/insert/exec/command, например при сбое запроса
Реализацию Logger по умолчанию можно найти здесь.

Сертификаты TLS (только для Node.js)

Клиент Node.js при необходимости поддерживает как односторонний TLS (только центр сертификации), так и взаимный 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” — они указывают на то, что сервер закрывает соединения раньше, чем клиент; уменьшайте значение, пока ошибки не исчезнут.

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

Если вы сталкиваетесь с ошибками socket hang up даже при использовании последней версии клиента, проблему можно попытаться решить следующими способами:
  • Включите логирование как минимум с уровнем WARN (по умолчанию). Это позволит проверить, нет ли в прикладном коде непрочитанного или зависшего потока: транспортный уровень запишет это в лог на уровне WARN, так как в противном случае сервер может закрыть сокет. Включить логирование в конфигурации клиента можно так:
  • Убедитесь, что нужная конфигурация применяется к правильному экземпляру клиента. Если в приложении используется несколько экземпляров клиента, перепроверьте, что у того, который вы используете для запросов, задано корректное значение keep_alive.idle_socket_ttl.
  • Уменьшите значение keep_alive.idle_socket_ttl в конфигурации клиента на 500 миллисекунд. В некоторых ситуациях, например при высокой сетевой задержке между клиентом и сервером, это может помочь исключить сценарий, при котором исходящий запрос получает сокет, который сервер уже собирается закрыть.
  • Если эта ошибка возникает во время длительно выполняющихся запросов без входящих или исходящих данных (например, при длительном INSERT FROM SELECT), причиной может быть балансировщик нагрузки или другие сетевые компоненты, закрывающие долгоживущие соединения или запросы, которые выполняются слишком долго. В таком случае можно попробовать принудительно отправлять некоторые данные во время выполнения длительных запросов, используя комбинацию следующих настроек ClickHouse:
    Однако имейте в виду, что в последних версиях Node.js общий размер полученных заголовков ограничен 16 КБ; после получения определенного количества заголовков прогресса — в наших тестах это было около 70–80 — будет сгенерировано исключение. Также можно использовать совершенно другой подход, полностью исключив ожидание передачи данных по сети; для этого можно воспользоваться особенностью HTTP interface, заключающейся в том, что мутации не отменяются при потере соединения. Подробнее см. в этом примере (часть 2).
  • Возможность Keep-Alive можно полностью отключить. В этом случае клиент также будет добавлять заголовок Connection: close к каждому запросу, а базовый HTTP-агент не будет повторно использовать соединения. Настройка keep_alive.idle_socket_ttl будет игнорироваться, так как бездействующих сокетов не будет. Это приведет к дополнительным накладным расходам, поскольку для каждого запроса будет устанавливаться новое соединение.
  • Исключите возможные проблемы в остальной части сетевого стека, включая сам Node.js, выполнив простой тест из командной строки с тем же экземпляром ClickHouse и по тому же сетевому пути (то есть с той же машины или из того же сегмента сети, например из Kubernetes пода), например с помощью curl:
    Возможно, стоит запустить его в цикле на несколько минут. Если вы видите похожие ошибки в curl, скорее всего, проблема связана не с конфигурацией клиента, а с сетевым стеком или конфигурацией сервера.
  • Чтобы проверить соединение средствами самого Node.js, можно попробовать создать простой HTTP-запрос к серверу ClickHouse, используя встроенный API fetch:
  • В некоторых случаях прикладной код или адаптеры фреймворка могут добавлять упреждающий ping() перед фактическим выполнением запроса. В результате ping() может завершиться успешно, а следующий запрос — завершиться ошибкой “socket hang up” из-за той же проблемы с бездействующими соединениями. Если вы видите такую картину в журнале, проверьте, можно ли отключить упреждающие ping() в используемом фреймворке или прикладном коде. Это также должно снизить вероятность того, что промежуточные сетевые компоненты начнут ограничивать трафик.
  • Убедитесь, что самому приложению выделяется достаточно процессорного времени и что сеть не ограничивается хостинг-провайдером. Различные средства мониторинга, такие как метрики пауз GC, метрики задержки цикла событий и другие подобные показатели, тоже могут помочь исключить возможные проблемы, связанные с нехваткой ресурсов.
  • Попробуйте проверять свой прикладной код с включенным правилом ESLint no-floating-promises — оно поможет выявить необработанные промисы, которые могут приводить к зависающим потокам и сокетам.

Пользователи в режиме «только для чтения»

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

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

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

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

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

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

Это экспериментальная возможность, которая в будущих релизах может измениться несовместимым с предыдущими версиями образом. Реализации и настроек, используемых клиентом по умолчанию, должно быть достаточно для большинства сценариев. Используйте эту возможность, только если уверены, что она вам действительно нужна.
По умолчанию клиент настраивает базовый HTTP- или HTTPS-агент, используя параметры из конфигурации клиента (например, max_open_connections, keep_alive.enabled, tls), и именно он будет управлять подключениями к серверу ClickHouse. Кроме того, если используются TLS-сертификаты, базовый агент будет настроен с необходимыми сертификатами, а также будут применяться корректные заголовки TLS-аутентификации. Начиная с версии 1.2.0, клиенту можно передать пользовательский HTTP- или HTTPS-агент, заменив стандартный базовый агент. Это может быть полезно в случае сложных сетевых конфигураций. Если передан пользовательский агент, действуют следующие условия:
  • Параметры max_open_connections и tls не будут иметь эффекта и будут игнорироваться клиентом, так как относятся к конфигурации базового агента.
  • keep_alive.enabled будет регулировать только значение по умолчанию заголовка Connection (true -> Connection: keep-alive, false -> Connection: close).
  • Хотя управление бездействующими keep-alive-сокетами по-прежнему будет работать (поскольку оно привязано не к агенту, а к конкретному сокету), теперь его можно полностью отключить, установив значение keep_alive.idle_socket_ttl в 0.

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

Использование собственного HTTP- или HTTPS-агента без сертификатов:
Использование пользовательского 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)

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

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

  • Чтобы снизить потребление памяти приложением, при работе с большими вставками (например, из файлов) и выборками там, где это уместно, стоит использовать потоки. Для обработчиков событий и похожих сценариев хорошим вариантом также могут быть async inserts: они позволяют свести к минимуму или даже полностью избежать батчинга на стороне клиента. Примеры async insert доступны в client repository; префикс имени файла — async_insert_.
  • По умолчанию клиент не включает сжатие запросов и ответов. Однако при выборке или вставке больших объёмов данных можно рассмотреть его включение через ClickHouseClientConfigOptions.compression (либо только для request или response, либо для обоих).
  • Сжатие даёт заметный штраф по производительности. Включение сжатия для request или response отрицательно скажется соответственно на скорости выборок или вставок, но уменьшит объём сетевого трафика, передаваемого приложением.

Свяжитесь с нами

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