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

Java-клиент

Java-клиентская библиотека для взаимодействия с сервером БД по его протоколам. Текущая реализация поддерживает только HTTP-интерфейс. Библиотека предоставляет собственный API для отправки запросов к серверу, а также инструменты для работы с различными двоичными форматами данных (RowBinary* & Native*).

Настройка


<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>client-v2</artifactId>
    <version>0.9.1</version>
</dependency>

Инициализация

Объект Client инициализируется с помощью com.clickhouse.client.api.Client.Builder#build(). Каждый клиент имеет собственный контекст, и объекты между экземплярами не разделяются. У Builder есть методы конфигурирования для удобной настройки.

Пример:

 Client client = new Client.Builder()
                .addEndpoint("https://clickhouse-cloud-instance:8443/")
                .setUsername(user)
                .setPassword(password)
                .build();

Client реализует интерфейс AutoCloseable, и его следует закрывать, когда он больше не нужен.

Аутентификация

Аутентификация настраивается для каждого клиента на этапе инициализации. Поддерживаются три метода аутентификации: по паролю, по токену доступа, по SSL‑клиентскому сертификату.

Аутентификация по паролю требует указания имени пользователя и пароля с помощью вызовов setUsername(String) и setPassword(String):

 Client client = new Client.Builder()
        .addEndpoint("https://clickhouse-cloud-instance:8443/")
        .setUsername(user)
        .setPassword(password)
        .build();

Для аутентификации по токену доступа необходимо задать токен, вызвав setAccessToken(String)‌:

 Client client = new Client.Builder()
        .addEndpoint("https://clickhouse-cloud-instance:8443/")
        .setAccessToken(userAccessToken)
        .build();

Аутентификация с использованием клиентского SSL-сертификата требует указания имени пользователя, включения SSL-аутентификации, а также задания клиентского сертификата и клиентского ключа путём вызова методов setUsername(String), useSSLAuthentication(boolean), setClientCertificate(String) и setClientKey(String) соответственно:

Client client = new Client.Builder()
        .useSSLAuthentication(true)
        .setUsername("some_user")
        .setClientCertificate("some_user.crt")
        .setClientKey("some_user.key")
Примечание

Аутентификацию по SSL может быть сложно отлаживать в продакшене, поскольку многие ошибки из SSL‑библиотек содержат недостаточно информации. Например, если клиентский сертификат и ключ не совпадают, сервер немедленно разорвёт соединение (в случае HTTP это произойдёт на стадии установления соединения, когда HTTP‑запросы ещё не отправляются, поэтому и ответа не будет).

Используйте инструменты вроде openssl для проверки сертификатов и ключей:

  • проверить целостность ключа: openssl rsa -in [key-file.key] -check -noout
  • проверить, что у клиентского сертификата корректное значение CN для пользователя:
    • получить CN из сертификата пользователя — openssl x509 -noout -subject -in [user.cert]
    • убедиться, что то же значение установлено в базе данных: select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate' (запрос выведет auth_params с чем‑то вроде {"common_names":["some_user"]})

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

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

Конфигурация задаётся при создании клиента. См. com.clickhouse.client.api.Client.Builder.

Настройка клиента

Способ настройкиАргументыОписание
addEndpoint(String endpoint)* endpoint — адрес сервера в формате URL.Добавляет конечную точку сервера в список доступных серверов. В настоящее время поддерживается только одна конечная точка.

По умолчанию: none
Перечисление: none
Ключ: none
addEndpoint(Protocol protocol, String host, int port, boolean secure)- protocol - протокол соединения com.clickhouse.client.api.enums.Protocol#HTTP.
- host - IP-адрес или имя хоста сервера.
- secure - следует ли использовать защищённую версию протокола (HTTPS)
Добавляет конечную точку сервера в список доступных серверов. В настоящее время поддерживается только одна конечная точка.

По умолчанию: none
Перечисление: none
Ключ: none
setOption(String key, String value)* key - строковый ключ опции конфигурации клиента.
- value - строковое значение опции
Устанавливает «сырое» значение параметров клиента. Полезно при чтении конфигурации из файлов свойств.
setUsername(String username)- username - имя пользователя, используемое для аутентификацииЗадает имя пользователя для метода аутентификации, выбираемого дальнейшей конфигурацией

По умолчанию: default
Enum: ClientConfigProperties.USER
Ключ: user
setPassword(String password)* password — секретное значение для аутентификации по паролюЗадает секрет для аутентификации по паролю и фактически выбирает этот метод аутентификации

По умолчанию: -
Enum: ClientConfigProperties.PASSWORD
Key: password
setAccessToken(String accessToken)- accessToken - строковая форма токена доступаУстанавливает токен доступа для аутентификации и настраивает соответствующий метод аутентификации

По умолчанию: -
Enum: ClientConfigProperties.ACCESS_TOKEN
Ключ: access_token
useSSLAuthentication(boolean useSSLAuthentication)* useSSLAuthentication - флаг, указывающий, следует ли использовать аутентификацию SSLЗадает клиентский SSL-сертификат как метод аутентификации.

По умолчанию: -
Перечисление: ClientConfigProperties.SSL_AUTH
Ключ: ssl_authentication
enableConnectionPool(boolean enable)- enable - флаг, указывающий, следует ли включить этот параметрОпределяет, включен ли пул подключений

По умолчанию: true
Enum: ClientConfigProperties.CONNECTION_POOL_ENABLED
Key: connection_pool_enabled
setConnectTimeout(long timeout, ChronoUnit unit)* timeout - значение тайм-аута в определённой единице времени.
- unit - единица времени для timeout
Устанавливает таймаут инициализации соединения для любого исходящего соединения. Это влияет на время ожидания установления соединения по сокету.

По умолчанию: -
Enum: ClientConfigProperties.CONNECTION_TIMEOUT
Key: connection_timeout
setConnectionRequestTimeout(long timeout, ChronoUnit unit)- timeout - значение тайм-аута в некоторой единице измерения времени.
- unit - единица измерения времени для параметра timeout
Устанавливает таймаут запроса соединения. Применяется только при получении соединения из пула.

По умолчанию: 10000
Enum: ClientConfigProperties.CONNECTION_REQUEST_TIMEOUT
Key: connection_request_timeout
setMaxConnections(int maxConnections)* maxConnections - максимальное количество соединенийЗадает, сколько соединений может клиент открыть к каждой конечной точке сервера.

По умолчанию: 10
Enum: ClientConfigProperties.HTTP_MAX_OPEN_CONNECTIONS
Key: max_open_connections
setConnectionTTL(long timeout, ChronoUnit unit)- timeout - тайм-аут в заданных единицах времени.
- unit - единица измерения времени для timeout
Устанавливает время жизни (TTL) соединения, по истечении которого соединение будет считаться неактивным

По умолчанию: -1
Enum: ClientConfigProperties.CONNECTION_TTL
Key: connection_ttl
setKeepAliveTimeout(long timeout, ChronoUnit unit)* timeout - тайм-аут в определённой единице времени.
- unit - единица времени для значения timeout
Устанавливает тайм-аут поддержания активности HTTP-соединения (keep-alive). Этот параметр можно использовать для отключения Keep-Alive, установив тайм-аут равным нулю — 0

По умолчанию: -
Enum: ClientConfigProperties.HTTP_KEEP_ALIVE_TIMEOUT
Ключ: http_keep_alive_timeout
setConnectionReuseStrategy(ConnectionReuseStrategy strategy)- strategy - константа перечисления (enum) com.clickhouse.client.api.ConnectionReuseStrategyОпределяет стратегию, которую должен использовать пул соединений: LIFO — если соединение должно переиспользоваться сразу после возврата в пул, или FIFO — чтобы использовать соединения в порядке их появления (возвращённые соединения не используются немедленно).

По умолчанию: FIFO
Enum: ClientConfigProperties.CONNECTION_REUSE_STRATEGY
Ключ: connection_reuse_strategy
setSocketTimeout(long timeout, ChronoUnit unit)`*timeout- таймаут в заданной единице измерения времени.
-unit- единица измерения времени дляtimeout
Задает тайм-аут сокета для операций чтения и записи

По умолчанию:0
Enum:ClientConfigProperties.SOCKET&#95;OPERATION&#95;TIMEOUT
Key:socket&#95;timeout
setSocketRcvbuf(long size)-size— размер в байтахЗадает размер приемного буфера TCP-сокета. Этот буфер размещается вне памяти JVM.

Default:8196
Enum:ClientConfigProperties.SOCKET&#95;RCVBUF&#95;OPT
Key:socket&#95;rcvbuf
setSocketSndbuf(long size)*size- размер в байтахУстанавливает буфер приёма TCP-сокета. Этот буфер располагается вне памяти JVM.

По умолчанию:8196
Enum:ClientConfigProperties.SOCKET&#95;SNDBUF&#95;OPT
Ключ:socket&#95;sndbuf
setSocketKeepAlive(boolean value)-value- флаг, указывающий, нужно ли включить параметр.Устанавливает опциюSO&#95;KEEPALIVEдля каждого TCP-сокета, создаваемого клиентом. TCP Keep Alive включает механизм, который проверяет активность соединения и помогает обнаруживать соединения, разорванные внезапно.

По умолчанию: -
Enum:ClientConfigProperties.SOCKET&#95;KEEPALIVE&#95;OPT
Key:socket&#95;keepalive
setSocketTcpNodelay(boolean value)*value— флаг, указывающий, нужно ли включать эту опцию.Устанавливает опциюSO&#95;NODELAYдля каждого TCP-сокета, создаваемого клиентом. Эта TCP-опция заставляет сокет передавать данные как можно скорее.

По умолчанию: -
Enum:ClientConfigProperties.SOCKET&#95;TCP&#95;NO&#95;DELAY&#95;OPT
Key:socket&#95;tcp&#95;nodelay
setSocketLinger(int secondsToWait)-secondsToWait- количество секунд.Задаёт время ожидания при закрытии (linger) для каждого TCP-сокета, создаваемого клиентом.

По умолчанию: -
Enum:ClientConfigProperties.SOCKET&#95;LINGER&#95;OPT
Key:socket&#95;linger
compressServerResponse(boolean enabled)*enabled- флаг, определяющий, нужно ли включать эту опциюОпределяет, должен ли сервер сжимать свои ответы.

По умолчанию:true
Enum:ClientConfigProperties.COMPRESS&#95;SERVER&#95;RESPONSE
Ключ:compress
compressClientRequest(boolean enabled)-enabled— флаг, указывающий, включена ли опцияОпределяет, должен ли клиент сжимать свои запросы.

По умолчанию:false
Enum:ClientConfigProperties.COMPRESS&#95;CLIENT&#95;REQUEST
Ключ:decompress
useHttpCompression(boolean enabled)*enabled- флаг, определяющий, должен ли быть включён параметрОпределяет, следует ли использовать HTTP-сжатие для обмена данными между клиентом и сервером, если включены соответствующие опции
appCompressedData(boolean enabled)-enabled- флаг, указывающий, должна ли опция быть включенаСообщает клиенту, что сжатие данных будет выполняться приложением.

По умолчанию:false
Enum:ClientConfigProperties.APP&#95;COMPRESSED&#95;DATA
Ключ:app&#95;compressed&#95;data
setLZ4UncompressedBufferSize(int size)*size— размер в байтахУстанавливает размер буфера, который будет принимать несжатую часть потока данных. Если размер буфера занижен — будет создан новый буфер, а в логах появится соответствующее предупреждение.

По умолчанию:65536
Enum:ClientConfigProperties.COMPRESSION&#95;LZ4&#95;UNCOMPRESSED&#95;BUF&#95;SIZE
Key:compression.lz4.uncompressed&#95;buffer&#95;size
disableNativeCompression-disable- флаг, определяющий, нужно ли отключить опциюОтключить нативное сжатие. Если установлено в true, нативное сжатие будет отключено.

По умолчанию:false
Enum:ClientConfigProperties.DISABLE&#95;NATIVE&#95;COMPRESSION
Ключ:disable&#95;native&#95;compression
setDefaultDatabase(String database)*database- название базы данныхЗадает базу данных по умолчанию.

По умолчанию:default
Enum:ClientConfigProperties.DATABASE
Ключ:database
addProxy(ProxyType type, String host, int port)-type- тип прокси-сервера.
-host- имя хоста или IP-адрес прокси-сервера.
-port- порт прокси-сервера
Задает прокси-сервер, используемый для связи с сервером. Настройка прокси обязательна, если для работы через него требуется аутентификация.

По умолчанию: -
Enum:ClientConfigProperties.PROXY&#95;TYPE
Key:proxy&#95;type

По умолчанию: -
Enum:ClientConfigProperties.PROXY&#95;HOST
Key:proxy&#95;host

По умолчанию: -
Enum:ClientConfigProperties.PROXY&#95;PORT
Key:proxy&#95;port
setProxyCredentials(String user, String pass)*user- имя пользователя для прокси.
-pass- пароль
Задает учетные данные пользователя для аутентификации на прокси-сервере.

По умолчанию: -
Enum:ClientConfigProperties.PROXY&#95;USER
Ключ:proxy&#95;user

По умолчанию: -
Enum:ClientConfigProperties.PROXY&#95;PASSWORD
Ключ:proxy&#95;password
setExecutionTimeout(long timeout, ChronoUnit timeUnit)-timeout- тайм-аут, заданный в некоторой единице времени.
-timeUnit- единица времени для параметраtimeout
Устанавливает максимальное время выполнения запросов

Значение по умолчанию:0
Enum:ClientConfigProperties.MAX&#95;EXECUTION&#95;TIME
Ключ:max&#95;execution&#95;time
setHttpCookiesEnabled(boolean enabled)enabled- флаг, определяющий, должна ли быть включена опцияОпределяет, нужно ли запоминать HTTP‑cookie и отправлять их обратно на сервер.
setSSLTrustStore(String path)path— путь к файлу в локальной системе (на стороне клиента)Определяет, должен ли клиент использовать SSL truststore для проверки хоста сервера.

По умолчанию: -
Enum:ClientConfigProperties.SSL&#95;TRUST&#95;STORE
Key:trust&#95;store
setSSLTrustStorePassword(String password)password— секретУстанавливает пароль, который будет использоваться для доступа к SSL truststore, указанному с помощьюsetSSLTrustStore(String path)

По умолчанию: -
Перечисление:ClientConfigProperties.SSL&#95;KEY&#95;STORE&#95;PASSWORD
Ключ:key&#95;store&#95;password
setSSLTrustStoreType(String type)type— имя типа хранилища доверенных сертификатовЗадаёт тип хранилища доверенных сертификатов, указанного вsetSSLTrustStore(String path).

По умолчанию: -
Enum: ClientConfigProperties.SSL&#95;KEYSTORE&#95;TYPE
Ключ:key&#95;store&#95;type
setRootCertificate(String path)path— путь к файлу в локальной системе (на стороне клиента)Определяет, должен ли клиент использовать указанный корневой (CA) сертификат для проверки подлинности узла сервера.

По умолчанию: -
Enum:ClientConfigProperties.CA&#95;CERTIFICATE
Key:sslrootcert
setClientCertificate(String path)path— путь к файлу в локальной системе (на стороне клиента)Устанавливает путь к клиентскому сертификату, который будет использоваться при установлении SSL-соединения и для SSL-аутентификации.

По умолчанию: -
Enum:ClientConfigProperties.SSL&#95;CERTIFICATE
Key:sslcert
setClientKey(String path)path— путь к файлу в локальной системе (на стороне клиента)Задаёт закрытый ключ клиента, используемый для шифрования SSL-соединения с сервером.

По умолчанию: -
Enum:ClientConfigProperties.SSL&#95;KEY
Ключ:ssl&#95;key
useServerTimeZone(boolean useServerTimeZone)useServerTimeZone- флаг, определяющий, следует ли включать эту опциюОпределяет, должен ли клиент использовать временную зону сервера при декодировании значений столбцов DateTime и Date. Если параметр включён, временная зона сервера должна быть установлена с помощьюsetServerTimeZone(String timeZone)

По умолчанию:true
Enum:ClientConfigProperties.USE&#95;SERVER&#95;TIMEZONE
Ключ:use&#95;server&#95;time&#95;zone
useTimeZone(String timeZone)timeZone- строковое значение допустимого идентификатора часового пояса Java (см.java.time.ZoneId)Определяет, следует ли использовать указанную временную зону при декодировании значений столбцов DateTime и Date. Переопределяет временную зону сервера.

По умолчанию: -
Enum: ClientConfigProperties.USE&#95;TIMEZONE
Key:use&#95;time&#95;zone
setServerTimeZone(String timeZone)timeZone— строковое значение допустимого идентификатора часового пояса в Java (см.java.time.ZoneId)Устанавливает часовой пояс сервера. По умолчанию используется часовой пояс UTC.

По умолчанию: UTC
Enum:ClientConfigProperties.SERVER&#95;TIMEZONE
Ключ:server&#95;time&#95;zone
useAsyncRequests(boolean async)async- флаг, указывающий, нужно ли включить эту опцию.Определяет, должен ли клиент выполнять запрос в отдельном потоке. По умолчанию параметр отключён, так как приложение обычно лучше понимает, как организовывать многопоточные задачи, а запуск задач в отдельном потоке не улучшает производительность.

По умолчанию:false
Enum:ClientConfigProperties.ASYNC&#95;OPERATIONS
Key:async
setSharedOperationExecutor(ExecutorService executorService)executorService— экземпляр службы исполнителей.Задает сервис выполнения задач операции.

По умолчанию:none
Enum:none
Ключ:none
setClientNetworkBufferSize(int size)*size— размер в байтахЗадает размер буфера в пространстве памяти приложения, который используется для копирования данных между сокетом и приложением в обоих направлениях. Увеличение этого размера уменьшает количество системных вызовов к TCP-стеку, но увеличивает объем памяти, расходуемой на каждое соединение. Этот буфер также подлежит сборке мусора, поскольку соединения кратковременные. Обратите также внимание, что выделение большого непрерывного блока памяти может быть проблемой.

По умолчанию:300000
Enum:ClientConfigProperties.CLIENT&#95;NETWORK&#95;BUFFER&#95;SIZE
Key:client&#95;network&#95;buffer&#95;size
retryOnFailures(ClientFaultCause ...causes)-causes- константа перечисленияenum com.clickhouse.client.api.ClientFaultCauseЗадаёт типы ошибок, при которых выполняется повторная попытка.

По умолчанию:NoHttpResponse,ConnectTimeout,ConnectionRequestTimeout
Enum:ClientConfigProperties.CLIENT&#95;RETRY&#95;ON&#95;FAILURE
Ключ:client&#95;retry&#95;on&#95;failures
setMaxRetries(int maxRetries)*maxRetries- число повторных попытокУстанавливает максимальное количество повторных попыток для сбоев, определённых вretryOnFailures(ClientFaultCause ...causes)

По умолчанию:3
Enum:ClientConfigProperties.RETRY&#95;ON&#95;FAILURE
Ключ:retry
allowBinaryReaderToReuseBuffers(boolean reuse)-reuse— флаг, указывающий, должна ли быть включена опцияБольшинство наборов данных содержат числовые данные, закодированные в виде небольших последовательностей байт. По умолчанию ридер выделяет необходимый буфер, считывает в него данные, а затем преобразует их в целевой класс Number. Это может создавать значительную нагрузку на сборщик мусора (GC), поскольку создаётся и освобождается большое количество мелких объектов. Если эта опция включена, ридер будет использовать заранее выделенные буферы для преобразования чисел. Это безопасно, поскольку у каждого ридера есть собственный набор буферов, и каждый экземпляр ридера используется только одним потоком.
httpHeader(String key, String value)*key- ключ заголовка HTTP.
-value- строковое значение этого заголовка.
Устанавливает значение для одного HTTP-заголовка. Предыдущее значение перезаписывается.

По умолчанию:none
Допустимые значения (enum):none
Ключ:none
httpHeader(String key, Collection values)-key- ключ заголовка HTTP.
-values- список строковых значений.
Задает значение одного HTTP-заголовка. Предыдущее значение переопределяется.

По умолчанию:none
Перечисление:none
Ключ:none
httpHeaders(Map headers)*header— карта (map) HTTP-заголовков и их значений.Задает несколько значений HTTP-заголовков одновременно.

По умолчанию:none
Перечисление:none
Ключ:none
serverSetting(String name, String value)-name- имя настройки на уровне запроса.
-value- строковое значение настройки.
Задает, какие настройки передавать серверу вместе с каждым запросом. Настройки отдельных операций могут их переопределять. Список настроек

Default:none
Enum:none
Key:none
serverSetting(String name, Collection values)*name- имя настройки уровня запроса.
-values- строковые значения этой настройки.
Определяет, какие настройки передавать серверу вместе с каждым запросом. Отдельные настройки операций могут их переопределять. См. список настроек. Этот метод полезен, когда нужно задать настройки с несколькими значениями, например roles.

По умолчанию:none
Перечисление:none
Ключ:none
columnToMethodMatchingStrategy(ColumnToMethodMatchingStrategy strategy)-strategy— реализация стратегии сопоставления столбцов с полямиЗадает пользовательскую стратегию, используемую для сопоставления полей класса DTO и столбцов БД при регистрации DTO.

По умолчанию:none
Enum:none
Ключ:none
useHTTPBasicAuth(boolean useBasicAuth)*useBasicAuth- флаг, указывающий, нужно ли включить эту опциюЗадаёт, следует ли использовать базовую HTTP-аутентификацию для проверки имени пользователя и пароля. По умолчанию включено. Использование этого типа аутентификации устраняет проблемы с паролями, содержащими специальные символы, которые не могут быть корректно переданы в HTTP-заголовках.

По умолчанию:true
Enum:ClientConfigProperties.HTTP&#95;USE&#95;BASIC&#95;AUTH
Key:http&#95;use&#95;basic&#95;auth
setClientName(String clientName)-clientName- строка с именем приложенияЗадает дополнительную информацию о клиентском приложении. Эта строка будет передана серверу как имя клиента. В случае использования протокола HTTP она будет передана как заголовокUser-Agent.

Default: -
Enum: ClientConfigProperties.CLIENT&#95;NAME
Key:client&#95;name
useBearerTokenAuth(String bearerToken)*bearerToken— токен типа Bearer в закодированном видеУказывает, следует ли использовать Bearer-аутентификацию и какой токен применять. Токен будет отправлен без изменений, поэтому его следует закодировать перед передачей этому методу.

По умолчанию: -
Enum:ClientConfigProperties.BEARERTOKEN&#95;AUTH
Ключ:bearer&#95;token
registerClientMetrics(Object registry, String name)-registry- экземпляр реестра Micrometer
-name- имя группы метрик
Регистрирует сенсоры в экземпляре реестра Micrometer (https://micrometer.io/).
setServerVersion(String version)*version- строковое значение версии сервераЗадает версию сервера, чтобы исключить ее определение автоматически.

По умолчанию: -
Перечисление:ClientConfigProperties.SERVER&#95;VERSION
Ключ:server&#95;version
typeHintMapping(Map typeHintMapping)-typeHintMapping- карта подсказок типовЗадает сопоставление подсказок типов для типов ClickHouse. Например, чтобы многомерные массивы представлялись в виде контейнеров Java вместо отдельных объектов Array.

По умолчанию: -
Enum:ClientConfigProperties.TYPE&#95;HINT&#95;MAPPING
Key:type&#95;hint&#95;mapping
sslSocketSNI(String sni)*sni- значение имени сервера в виде строкиУстанавливает имя сервера, используемое для SNI (Server Name Indication) в SSL/TLS-соединении.

По умолчанию: -
Enum:ClientConfigProperties.SSL&#95;SOCKET&#95;SNI
Key:ssl&#95;socket&#95;sni

Настройки сервера

Параметры на стороне сервера можно задавать как один раз на уровне клиента при его создании (см. метод serverSetting у Builder), так и на уровне операции (см. serverSetting для класса настроек операции).

 try (Client client = new Client.Builder().addEndpoint(Protocol.HTTP, "localhost", mockServer.port(), false)
        .setUsername("default")
        .setPassword(ClickHouseServerForTest.getPassword())
        .compressClientRequest(true)

        // Уровень клиента
        .serverSetting("max_threads", "10")
        .serverSetting("async_insert", "1")
        .serverSetting("roles", Arrays.asList("role1", "role2"))

        .build()) {

	// Уровень операции
	QuerySettings querySettings = new QuerySettings();
	querySettings.serverSetting("session_timezone", "Europe/Zurich");

	...
}

При задании параметров через метод setOption (либо в Client.Builder, либо в классе настроек операции) имя настройки сервера должно начинаться с префикса clickhouse_setting_. В этом случае может быть полезен метод com.clickhouse.client.api.ClientConfigProperties#serverSetting().

Пользовательский HTTP-заголовок

Пользовательские HTTP-заголовки можно задать глобально для всех операций (на уровне клиента) или для отдельной операции (на уровне операции).


QuerySettings settings = new QuerySettings()
    .httpHeader(HttpHeaders.REFERER, clientReferer)
    .setQueryId(qId);

Когда параметры задаются через метод setOption (либо в Client.Builder, либо в классе настроек операции), имя пользовательского заголовка должно начинаться с префикса http_header_. В этом случае может быть полезен метод com.clickhouse.client.api.ClientConfigProperties#httpHeader().

Основные определения

ClickHouseFormat

Перечисление поддерживаемых форматов. Оно включает все форматы, которые поддерживает ClickHouse.

  • raw — пользователь должен транскодировать необработанные данные
  • full — клиент может транскодировать данные самостоятельно и принимает поток необработанных данных
  • - — операция не поддерживается ClickHouse для этого формата

Эта версия клиента поддерживает:

ФорматВводВывод
TabSeparatedнеобработанныйсырой
TabSeparatedRawнеобработанныйнеобработанный
TabSeparatedWithNamesнеобработанныенеобработанные данные
TabSeparatedWithNamesAndTypesнеобработанныйнеобработанные данные
TabSeparatedRawWithNamesсыройнеобработанный
TabSeparatedRawWithNamesAndTypesнеобработанныйнеобработанные
Шаблонrawв исходном виде
TemplateIgnoreSpacesraw*
CSVнеобработанныесырой
CSVWithNamesсырые данныесырой
CSVWithNamesAndTypesнеобработанные данныебез обработки
CustomSeparatedнеобработанныесырой
CustomSeparatedWithNamesсырые данныенеобработанные
CustomSeparatedWithNamesAndTypesнеобработанныйнеобработанный
SQLInsert-исходные данные
Valuesнеобработанныеraw
Vertical*необработанный
JSONнеобработанныеraw
JSONAsStringв исходном виде-
JSONAsObjectсырой*
JSONStringsнеобработанныеraw
JSONColumnsв исходном виденеобработанные
JSONColumnsWithMetadataсырыесырой
JSONCompactсыройсырой
JSONCompactStrings-необработанный
JSONCompactColumnsсырыенеобработанный
JSONEachRowнеобработанныйсырой
PrettyJSONEachRow*в исходном виде
JSONEachRowWithProgress-сырые данные
JSONStringsEachRowнеобработанныйнеобработанный
JSONStringsEachRowWithProgress*необработанные данные
JSONCompactEachRowисходныйсырые данные
JSONCompactEachRowWithNamesсыройнеобработанные
JSONCompactEachRowWithNamesAndTypesсырые данныенеобработанные
JSONCompactStringsEachRowrawсырой
JSONCompactStringsEachRowWithNamesсыройнеобработанный
JSONCompactStringsEachRowWithNamesAndTypesнеобработанныенеобработанный
JSONObjectEachRowсыройraw
BSONEachRowсыройсырой
TSKVсырыенеобработанный
Pretty-сырой
PrettyNoEscapes*необработанный
PrettyMonoBlock-raw
PrettyNoEscapesMonoBlock*без обработки
PrettyCompact-сырой
PrettyCompactNoEscapes*необработанные
PrettyCompactMonoBlock-сырой
PrettyCompactNoEscapesMonoBlock*необработанные
PrettySpace-необработанный
PrettySpaceNoEscapes*исходный
PrettySpaceMonoBlock-необработанный
PrettySpaceNoEscapesMonoBlock*необработанный
Prometheus-необработанный
Protobufнеобработанныйнеобработанные
ProtobufSingleнеобработанныесырой
ProtobufListсырыенеобработанный
Avroсыройraw
AvroConfluentсырые данные*
Parquetнеобработанныенеобработанный
ParquetMetadataнеобработанные-
Arrowнеобработанныесырой
ArrowStreamнеобработанныйнеобработанные
ORCсыройисходный
Oneнеобработанные*
Npyнеобработанныйсырые
RowBinaryполныйполный
RowBinaryWithNamesполныйполный
RowBinaryWithNamesAndTypesполныйполный
RowBinaryWithDefaultsполный-
Nativeполныйнеобработанный
Null*сырой
XML-raw
CapnProtoнеобработанныйraw
LineAsStringсырые данныесырой
Regexpсырой*
RawBLOBнеобработанные данныесырой
MsgPackНеобработанныйнеобработанный
MySQLDumpнеобработанный-
DWARFнеобработанные*
Markdown-необработанные
Форманеобработанные*

API вставки данных

insert(String tableName, InputStream data, ClickHouseFormat format)

Принимает данные в виде потока байт (InputStream) в указанном формате. Предполагается, что data закодированы в формате format.

Сигнатуры

CompletableFuture<InsertResponse> insert(String tableName, InputStream data, ClickHouseFormat format, InsertSettings settings)
CompletableFuture<InsertResponse> insert(String tableName, InputStream data, ClickHouseFormat format)

Параметры

tableName - имя целевой таблицы.

data - входной поток данных в закодированном виде.

format - формат, в котором закодированы данные.

settings - настройки запроса.

Возвращаемое значение

Объект Future типа InsertResponse — результат операции и дополнительная информация, например серверные метрики.

Примеры

try (InputStream dataStream = getDataStream()) {
    try (InsertResponse response = client.insert(TABLE_NAME, dataStream, ClickHouseFormat.JSONEachRow,
            insertSettings).get(3, TimeUnit.SECONDS)) {

        log.info("Вставка завершена: записано строк: {}", response.getMetrics().getMetric(ServerMetrics.NUM_ROWS_WRITTEN).getLong());
    } catch (Exception e) {
        log.error("Не удалось записать данные в формате JSONEachRow", e);
        throw new RuntimeException(e);
    }
}

insert(String tableName, List<?> data, InsertSettings settings)

Отправляет запрос на запись в базу данных. Список объектов преобразуется в эффективный формат и затем отправляется на сервер. Класс элементов списка необходимо заранее зарегистрировать с помощью метода register(Class, TableSchema).

Сигнатуры

client.insert(String tableName, List<?> data, InsertSettings settings)
client.insert(String tableName, List<?> data)

Параметры

tableName - имя целевой таблицы.

data - коллекция DTO-объектов (Data Transfer Object).

settings - настройки запроса.

Возвращаемое значение

Объект Future типа InsertResponse — результат операции и дополнительная информация, например, метрики на стороне сервера.

Примеры

// Важный шаг (выполняется однократно) — регистрация класса для предварительной компиляции сериализатора объектов согласно схеме таблицы. 
client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));

List<ArticleViewEvent> events = loadBatch();

try (InsertResponse response = client.insert(TABLE_NAME, events).get()) {
    // обработка ответа, затем он будет закрыт и соединение, обслужившее запрос, будет освобождено. 
}

insert(String tableName, DataStreamWriter writer, ClickHouseFormat format, InsertSettings settings)

Бета

Этот метод API позволяет передать объект writer, который будет кодировать данные непосредственно в выходной поток. Сжатие данных будет выполняться на стороне клиента. В InsertSettings есть параметр конфигурации appCompressedData, который позволяет отключить сжатие на стороне клиента и передавать в приложение ответственность за отправку уже сжатого потока. Примеры демонстрируют основные варианты использования, для которых был разработан этот API.

com.clickhouse.client.api.DataStreamWriter — это функциональный интерфейс с методом onOutput, который вызывается клиентом, когда выходной поток готов к записи данных. У этого интерфейса есть ещё один метод onRetry с реализацией по умолчанию. Этот метод вызывается, когда срабатывает логика повторного запроса, и в основном используется для сброса источника данных, если это применимо.

Сигнатуры

CompletableFuture<InsertResponse> insert(String tableName,              // имя целевой таблицы
                                         DataStreamWriter writer,       // экземпляр объекта записи данных
                                         ClickHouseFormat format,       // формат данных, в котором объект записи кодирует данные
                                         InsertSettings settings)       // настройки операции

Параметры

tableName - имя целевой таблицы.

writer - экземпляр объекта записи данных.

format - формат данных, в котором writer кодирует данные.

settings - настройки запроса.

Возвращаемое значение

Future типа InsertResponse — результат операции и дополнительная информация, например, серверные метрики.

Примеры

Запись коллекции JSON-объектов, закодированных в виде строковых значений, с использованием формата JSONEachRow:


final int EXECUTE_CMD_TIMEOUT = 10; // секунд
final String tableName = "events";
final String tableCreate = "CREATE TABLE \"" + tableName + "\" " +
        " (name String, " +
        "  v1 Float32, " +
        "  v2 Float32, " +
        "  attrs Nullable(String), " +
        "  corrected_time DateTime('UTC') DEFAULT now()," +
        "  special_attr Nullable(Int8) DEFAULT -1)" +
        "  Engine = MergeTree ORDER by ()";

client.execute("DROP TABLE IF EXISTS " + tableName).get(EXECUTE_CMD_TIMEOUT, TimeUnit.SECONDS);
client.execute(createTableSQL).get(EXECUTE_CMD_TIMEOUT, TimeUnit.SECONDS);

String correctedTime = Instant.now().atZone(ZoneId.of("UTC")).format(DataTypeUtils.DATETIME_FORMATTER);
String[] rows = new String[] {
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6, \"attrs\": \"a=1,b=2,c=5\", \"corrected_time\": \"" + correctedTime + "\", \"special_attr\": 10}",
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6, \"attrs\": \"a=1,b=2,c=5\", \"corrected_time\": \"" + correctedTime + "\"}",
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6, \"attrs\": \"a=1,b=2,c=5\" }",
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6 }",
};


try (InsertResponse response = client.insert(tableName, out -> {
    // запись сырых байтов 
    for (String row : rows) {
        out.write(row.getBytes());
    }

}, ClickHouseFormat.JSONEachRow, new InsertSettings()).get()) {

    System.out.println("Записано строк: " + response.getWrittenRows());
}

Запись уже сжатых данных:

String tableName = "very_long_table_name_with_uuid_" + UUID.randomUUID().toString().replace('-', '_');
String tableCreate = "CREATE TABLE \"" + tableName + "\" " +
        " (name String, " +
        "  v1 Float32, " +
        "  v2 Float32, " +
        "  attrs Nullable(String), " +
        "  corrected_time DateTime('UTC') DEFAULT now()," +
        "  special_attr Nullable(Int8) DEFAULT -1)" +
        "  Engine = MergeTree ORDER by ()";

client.execute("DROP TABLE IF EXISTS " + tableName).get(EXECUTE_CMD_TIMEOUT, TimeUnit.SECONDS);
client.execute(createTableSQL).get(EXECUTE_CMD_TIMEOUT, TimeUnit.SECONDS);

String correctedTime = Instant.now().atZone(ZoneId.of("UTC")).format(DataTypeUtils.DATETIME_FORMATTER);
String[] data = new String[] {
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6, \"attrs\": \"a=1,b=2,c=5\", \"corrected_time\": \"" + correctedTime + "\", \"special_attr\": 10}",
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6, \"attrs\": \"a=1,b=2,c=5\", \"corrected_time\": \"" + correctedTime + "\"}",
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6, \"attrs\": \"a=1,b=2,c=5\" }",
        "{ \"name\": \"foo1\", \"v1\": 0.3, \"v2\": 0.6 }",
};


// Этот шаг приведён только для демонстрации. В реальном приложении данные уже были бы сжаты. 
byte[][] compressedData = new byte[data.length][];
for (int i = 0 ; i < data.length; i++) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    GZIPOutputStream gz = new GZIPOutputStream(baos);
    gz.write(data[i].getBytes(StandardCharsets.UTF_8));
    gz.finish();
    compressedData[i] = baos.toByteArray();
}

InsertSettings insertSettings = new InsertSettings()
        .appCompressedData(true, "gzip"); // определение алгоритма сжатия (передаётся через HTTP-заголовки)

try (InsertResponse response = client.insert(tableName, out -> {
    // Запись данных 
    for (byte[] row : compressedData) {
        out.write(row);
    }
}, ClickHouseFormat.JSONEachRow, insertSettings).get()) {
    System.out.println("Записано строк: " + response.getWrittenRows());
}    

InsertSettings

Параметры конфигурации операций вставки.

Методы конфигурации

MethodDescription
setQueryId(String queryId)Устанавливает идентификатор запроса, который будет присвоен операции. По умолчанию: null.
setDeduplicationToken(String token)Устанавливает токен дедупликации. Этот токен будет отправлен на сервер и может быть использован для идентификации запроса. По умолчанию: null.
setInputStreamCopyBufferSize(int size)Размер буфера копирования. Буфер используется при операциях записи для копирования данных из предоставленного пользователем входного потока в выходной поток. По умолчанию: 8196.
serverSetting(String name, String value)Устанавливает отдельные настройки сервера для операции.
serverSetting(String name, Collection values)Устанавливает отдельные настройки сервера с несколькими значениями для операции. Элементы коллекции должны иметь тип String.
setDBRoles(Collection dbRoles)Устанавливает роли БД, которые будут заданы перед выполнением операции. Элементы коллекции должны иметь тип String.
setOption(String option, Object value)Устанавливает параметр конфигурации в необработанном виде. Это не настройка сервера.

InsertResponse

Объект ответа, который содержит результат операции вставки. Доступен только в том случае, если клиент получил ответ от сервера.

Примечание

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

MethodDescription
OperationMetrics getMetrics()Возвращает объект с метриками операции.
String getQueryId()Возвращает идентификатор запроса, назначенный операции приложением (через настройки операции) или сервером.

API для запросов

query(String sqlQuery)

Отправляет sqlQuery как есть. Формат ответа задаётся настройками запроса. QueryResponse будет содержать ссылку на поток ответа, который должен быть прочитан объектом Reader, поддерживающим соответствующий формат.

Сигнатуры

CompletableFuture<QueryResponse> query(String sqlQuery, QuerySettings settings)
CompletableFuture<QueryResponse> query(String sqlQuery)

Параметры

sqlQuery — одиночный SQL-оператор. Запрос отправляется на сервер как есть.

settings — настройки запроса.

Возвращаемое значение

Future типа QueryResponse, представляющий результирующий набор данных и дополнительную информацию, такую как серверные метрики. Объект QueryResponse необходимо закрыть после чтения набора данных.

Примеры

final String sql = "select * from " + TABLE_NAME + " where title <> '' limit 10";

// Формат по умолчанию — RowBinaryWithNamesAndTypesFormatReader, поэтому reader имеет всю информацию о столбцах
try (QueryResponse response = client.query(sql).get(3, TimeUnit.SECONDS);) {

    // Создаём reader для удобного доступа к данным
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

    while (reader.hasNext()) {
        reader.next(); // Читаем следующую запись из потока и парсим её

        // получаем значения
        double id = reader.getDouble("id");
        String title = reader.getString("title");
        String url = reader.getString("url");

        // собираем данные 
    }
} catch (Exception e) {
    log.error("Не удалось прочитать данные", e);
}

// размещайте бизнес-логику вне блока чтения, чтобы как можно быстрее освободить HTTP-соединение.  

query(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)

Отправляет sqlQuery без изменений. Также отправляет параметры запроса, чтобы сервер мог скомпилировать SQL-выражение.

Сигнатуры

CompletableFuture<QueryResponse> query(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)

Параметры

sqlQuery — SQL-выражение с плейсхолдерами {}.

queryParams — отображение (map) переменных для формирования SQL-выражения на стороне сервера.

settings — настройки запроса.

Возвращаемое значение

Объект Future типа QueryResponse — результирующий набор данных и дополнительная информация, такая как метрики на стороне сервера. Объект ответа должен быть закрыт после чтения набора данных.

Примеры


// определяем параметры. Они будут отправлены на сервер вместе с запросом.   
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("param1", 2);

try (QueryResponse response =
        client.query("SELECT * FROM " + table + " WHERE col1 >= {param1:UInt32}", queryParams, new QuerySettings()).get()) {

    // Создаём reader для удобного доступа к данным
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

    while (reader.hasNext()) {
        reader.next(); // Читаем следующую запись из потока и парсим её

        // чтение данных 
    }

} catch (Exception e) {
    log.error("Не удалось прочитать данные", e);
}

queryAll(String sqlQuery)

Выполняет запрос и возвращает данные в формате RowBinaryWithNamesAndTypes. Результат возвращается в виде коллекции. Скорость чтения такая же, как при использовании reader, но для хранения всего набора данных требуется больше памяти.

Сигнатуры

List<GenericRecord> queryAll(String sqlQuery)

Параметры

sqlQuery - SQL-выражение для выборки данных с сервера.

Возвращаемое значение

Полный набор данных, представленный списком объектов GenericRecord, которые обеспечивают построчный доступ к данным результата.

Примеры

try {
    log.info("Чтение всей таблицы и построчная обработка записей");
    final String sql = "select * from " + TABLE_NAME + " where title <> ''";

    // Чтение всего набора результатов и построчная обработка записей
    client.queryAll(sql).forEach(row -> {
        double id = row.getDouble("id");
        String title = row.getString("title");
        String url = row.getString("url");

        log.info("id: {}, title: {}, url: {}", id, title, url);
    });
} catch (Exception e) {
    log.error("Ошибка чтения данных", e);
}

QuerySettings

Параметры конфигурации операций с запросами.

Методы настройки

MethodDescription
setQueryId(String queryId)Устанавливает ID запроса, который будет присвоен операции.
setFormat(ClickHouseFormat format)Устанавливает формат ответа. Полный список см. в RowBinaryWithNamesAndTypes.
setMaxExecutionTime(Integer maxExecutionTime)Устанавливает время выполнения операции на сервере. Не влияет на тайм‑аут чтения.
waitEndOfQuery(Boolean waitEndOfQuery)Запрашивает у сервера дождаться завершения запроса перед отправкой ответа.
setUseServerTimeZone(Boolean useServerTimeZone)Для разбора типов даты/времени в результате операции будет использоваться часовой пояс сервера (см. конфигурацию клиента). По умолчанию — false.
setUseTimeZone(String timeZone)Запрашивает у сервера использовать timeZone для преобразования времени. См. session_timezone.
serverSetting(String name, String value)Устанавливает отдельный параметр серверной настройки для операции.
serverSetting(String name, Collection values)Устанавливает отдельный параметр серверной настройки с несколькими значениями для операции. Элементы коллекции должны быть строками (String).
setDBRoles(Collection dbRoles)Устанавливает роли БД, которые будут заданы перед выполнением операции. Элементы коллекции должны быть строками (String).
setOption(String option, Object value)Устанавливает параметр конфигурации в «сыром» формате. Это не параметр серверной настройки.

QueryResponse

Объект ответа, который содержит результат выполнения запроса. Доступен только в том случае, если клиент получил ответ от сервера.

Примечание

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

MethodDescription
ClickHouseFormat getFormat()Возвращает формат, в котором закодированы данные в ответе.
InputStream getInputStream()Возвращает несжатый байтовый поток данных в указанном формате.
OperationMetrics getMetrics()Возвращает объект с метриками операции.
String getQueryId()Возвращает ID запроса, назначенный операции приложением (через настройки операции или сервером).
TimeZone getTimeZone()Возвращает часовой пояс, который должен использоваться для обработки типов Date/DateTime в ответе.

Примеры

Общий API

getTableSchema(String table)

Возвращает схему таблицы для table.

Сигнатуры

TableSchema getTableSchema(String table)
TableSchema getTableSchema(String table, String database)

Параметры

table - имя таблицы, для которой нужно получить схему.

database - база данных, в которой определена целевая таблица.

Возвращаемое значение

Возвращает объект TableSchema со списком столбцов таблицы.

getTableSchemaFromQuery(String sql)

Извлекает схему из SQL-запроса.

Сигнатуры

TableSchema getTableSchemaFromQuery(String sql)

Параметры

sql — SQL-выражение SELECT, схема которого должна быть возвращена.

Возвращаемое значение

Возвращает объект TableSchema со столбцами, соответствующими выражению sql.

TableSchema

register(Class<?> clazz, TableSchema schema)

Компилирует слой сериализации и десериализации для Java-класса, который будет использоваться для записи и чтения данных в соответствии со схемой schema. Метод создаст сериализатор и десериализатор для пары getter/setter и соответствующего столбца. Соответствие столбца определяется по имени, извлечённому из имени метода. Например, getFirstName будет соответствовать столбцу first_name или firstname.

Сигнатуры

void register(Class<?> clazz, TableSchema schema)

Параметры

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

schema - схема данных, используемая для сопоставления со свойствами POJO.

Примеры

client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));

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

Полные примеры кода можно найти в репозитории в папке examples:

  • client-v2 — основной набор примеров.
  • demo-service — пример использования клиента в приложении Spring Boot.
  • demo-kotlin-service — пример использования клиента в приложении Ktor (Kotlin).