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

Требования к окружению (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:
Кнопка подключения сервиса ClickHouse Cloud
Выберите HTTPS. Сведения о подключении будут показаны в примере команды curl.
Сведения о подключении к ClickHouse Cloud по HTTPS
Если вы используете самоуправляемый 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. Нет гарантии, что для последующих запросов будет использоваться одно и то же соединение из пула, если только пользователь не установит 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 — хороший выбор.

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

Есть несколько параметров, которые можно использовать для всех клиентских методов (запрос/command/вставка/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 не был передан в params метода, в результате это будет пустая строка, так как возврат случайного 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-файла. Исходный код. См. также: потоковая передача файлов.
Пример: Исключите определённые столбцы из оператора INSERT. Например, для такого определения таблицы:
Вставка только в указанный столбец:
Исключите некоторые столбцы:
См. исходный код, чтобы получить дополнительные сведения. Пример: Выполните вставку в базу данных, отличную от той, которая указана для экземпляра клиента. Исходный код.

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

В настоящее время операции вставки в @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 и Web. 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.

Сжатие

NB: сжатие запросов сейчас недоступно в веб-версии. Сжатие ответов работает как обычно. Версия Node.js поддерживает и то, и другое. Приложения для работы с данными, которые передают большие объёмы данных, могут выиграть от включения сжатия. Сейчас поддерживается только GZIP с использованием zlib.
Параметры конфигурации:
  • 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 (только CA), так и взаимный TLS (CA и клиентские сертификаты). Пример настройки одностороннего 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 — будет сгенерировано исключение. Также можно использовать совершенно другой подход, полностью избежав ожидания on the wire; для этого можно воспользоваться «особенностью» HTTP-интерфейса: мутации не отменяются при потере соединения. Подробнее см. в этом примере (часть 2).
  • Возможность Keep-Alive можно полностью отключить. В этом случае клиент также будет добавлять заголовок Connection: close в каждый запрос, а базовый HTTP-агент не будет повторно использовать соединения. Настройка keep_alive.idle_socket_ttl будет игнорироваться, так как бездействующих сокетов не будет. Это приведёт к дополнительным накладным расходам, поскольку для каждого запроса будет устанавливаться новое соединение.
  • Исключите возможные проблемы с остальной частью сетевого стека, включая сам Node.js, выполнив простой тест из командной строки с тем же экземпляром ClickHouse и по тому же сетевому пути (то есть с той же машины или из того же сетевого сегмента, например из pod 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. Подробнее см. в разделе Integral types.

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

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

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

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

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

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