跳转到主内容
跳转到主内容

Java 客户端

用于通过协议与数据库服务器通信的 Java 客户端库。当前实现仅支持 HTTP 接口。 该库提供自己的 API 用于向服务器发送请求。该库还提供用于处理不同二进制数据格式(RowBinary* & Native*)的工具。

设置


<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>client-v2</artifactId>
    <version>0.9.6</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 是否与相应的 USER 匹配:
    • 从用户证书中获取 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

客户端配置

MethodArgumentsDescriptionDefaultKey
addEndpoint(String endpoint)endpoint - URL 格式的服务器地址将服务器端点添加到可用服务器列表。目前仅支持一个端点。nonenone
addEndpoint(Protocol protocol, String host, int port, boolean secure)protocol - 连接协议
host - IP 或主机名
secure - 使用 HTTPS
将服务器端点添加到可用服务器列表。目前仅支持一个端点。nonenone
enableConnectionPool(boolean enable)enable - 启用/禁用标志设置是否启用连接池trueconnection_pool_enabled
setMaxConnections(int maxConnections)maxConnections - 连接数量设置客户端对每个服务器端点最多可以打开的连接数。10max_open_connections
setConnectionTTL(long timeout, ChronoUnit unit)timeout - 超时值
unit - 时间单位
设置连接的生存时间 (TTL),超过该时间后连接将被视为不再活动-1connection_ttl
setKeepAliveTimeout(long timeout, ChronoUnit unit)timeout - 超时值
unit - 时间单位
设置 HTTP 连接的 Keep-Alive 超时时间。设置为 0 以禁用 Keep-Alive。-http_keep_alive_timeout
setConnectionReuseStrategy(ConnectionReuseStrategy strategy)strategy - LIFOFIFO选择连接池应使用的连接复用策略FIFOconnection_reuse_strategy
setDefaultDatabase(String database)database - 数据库名称设置默认数据库。defaultdatabase

服务器设置

服务器端设置可以在客户端创建时在客户端级别配置一次(参见 BuilderserverSetting 方法),也可以在操作级别进行配置(参见操作设置类的 serverSetting)。

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

        // Client level
        .serverSetting("max_threads", "10")
        .serverSetting("async_insert", "1")
        .serverSetting("roles", Arrays.asList("role1", "role2"))

        .build()) {

	// Operation level
	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 不支持针对该格式执行此操作

此客户端版本支持:

格式输入输出
TabSeparatedrawraw
TabSeparatedRawrawraw
TabSeparatedWithNamesrawraw
TabSeparatedWithNamesAndTypesrawraw
TabSeparatedRawWithNamesrawraw
TabSeparatedRawWithNamesAndTypesrawraw
Templaterawraw
TemplateIgnoreSpacesraw*
CSVrawraw
CSVWithNamesrawraw
CSVWithNamesAndTypesrawraw
CustomSeparatedrawraw
CustomSeparatedWithNames原始原始
CustomSeparatedWithNamesAndTypesrawraw
SQLInsert-raw
Valuesraw原始
Vertical*原始
JSONraw原始
JSONAsStringraw-
JSONAsObjectraw*
JSONStringsraw原始
JSONColumnsraw原样
JSONColumnsWithMetadata原始原始
JSONCompactraw原始
JSONCompactStrings-原始
JSONCompactColumnsrawraw
JSONEachRowrawraw
PrettyJSONEachRow*raw
JSONEachRowWithProgress-raw
JSONStringsEachRowrawraw
JSONStringsEachRowWithProgress*raw
JSONCompactEachRowrawraw
JSONCompactEachRowWithNamesrawraw
JSONCompactEachRowWithNamesAndTypesrawraw
JSONCompactStringsEachRowrawraw
JSONCompactStringsEachRowWithNamesrawraw
JSONCompactStringsEachRowWithNamesAndTypesrawraw
JSONObjectEachRowrawraw
BSONEachRowrawraw
TSKV原始原始
Pretty-原始
PrettyNoEscapes*原始
PrettyMonoBlock-原始
PrettyNoEscapesMonoBlock*原始
PrettyCompact-原始
PrettyCompactNoEscapes*原始
PrettyCompactMonoBlock-原始
PrettyCompactNoEscapesMonoBlock*原始
PrettySpace-原始
PrettySpaceNoEscapes*原始
PrettySpaceMonoBlock-原始
PrettySpaceNoEscapesMonoBlock*原始
Prometheus-raw
Protobufrawraw
ProtobufSinglerawraw
ProtobufListrawraw
Avrorawraw
AvroConfluentraw*
Parquetrawraw
ParquetMetadataraw-
Arrowrawraw
ArrowStreamrawraw
ORCrawraw
Oneraw*
Npyrawraw
RowBinary完整full
RowBinaryWithNamesfullfull
RowBinaryWithNamesAndTypesfullfull
RowBinaryWithDefaultsfull-
Nativefullraw
Null*raw
XML-raw
CapnProtorawraw
LineAsStringrawraw
Regexpraw*
RawBLOBrawraw
MsgPackrawraw
MySQLDumpraw-
DWARFraw*
Markdown-原始数据
Form原始数据*

插入 API

insert(String tableName, InputStream data, ClickHouseFormat format)

以指定格式的字节流(InputStream)接收数据。假定 dataformat 进行编码。

签名

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

参数

tableName - 目标表名。

data - 编码后数据的输入流。

format - 数据所采用的编码格式。

settings - 请求设置。

返回值

类型为 InsertResponse 的 Future —— 操作结果以及服务器端指标等附加信息。

示例

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

        log.info("Insert finished: {} rows written", response.getMetrics().getMetric(ServerMetrics.NUM_ROWS_WRITTEN).getLong());
    } catch (Exception e) {
        log.error("Failed to write JSONEachRow data", 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(数据传输对象)集合。

settings - 请求设置。

返回值

返回 InsertResponse 类型的 Future,包含操作结果以及服务器端指标等附加信息。

示例

// Important step (done once) - register class to pre-compile object serializer according to the table schema.
client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));

List<ArticleViewEvent> events = loadBatch();

try (InsertResponse response = client.insert(TABLE_NAME, events).get()) {
    // handle response, then it will be closed and connection that served request will be released.
}

InsertSettings

用于插入操作的配置项。

配置方法

方法描述
setQueryId(String queryId)设置要分配给该操作的查询 ID。默认值: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

用于保存插入操作结果的响应对象。仅当客户端收到来自服务器的响应时才可用。

注意

应尽快关闭此对象以释放连接,因为在完全读取完前一个响应的所有数据之前,该连接无法被重用。

方法说明
OperationMetrics getMetrics()返回一个包含该操作各项指标的对象。
String getQueryId()返回为该操作分配的查询 ID,该 ID 由应用程序(通过操作设置)指定或由服务器生成。

查询 API

query(String sqlQuery)

按原样发送 sqlQuery。响应格式由查询设置决定。QueryResponse 将保存对响应流的引用,该响应流应由支持该格式的读取器消费。

签名

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

参数

sqlQuery - 单条 SQL 语句。查询会按原样发送到服务器。

settings - 请求设置。

返回值

QueryResponse 类型的 Future - 结果数据集及服务器端指标等附加信息。使用完数据集后应关闭 Response 对象。

示例

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

// Default format is RowBinaryWithNamesAndTypesFormatReader so reader have all information about columns
try (QueryResponse response = client.query(sql).get(3, TimeUnit.SECONDS);) {

    // Create a reader to access the data in a convenient way
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

    while (reader.hasNext()) {
        reader.next(); // Read the next record from stream and parse it

        // get values
        double id = reader.getDouble("id");
        String title = reader.getString("title");
        String url = reader.getString("url");

        // collecting data
    }
} catch (Exception e) {
    log.error("Failed to read data", e);
}

// put business logic outside of the reading block to release http connection asap.

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 - 变量映射,用于在服务器端完成 SQL 表达式。

settings - 请求设置。

返回值

QueryResponse 类型的 Future——包含结果数据集以及诸如服务器端指标之类的附加信息。使用完数据集后应关闭 Response 对象。

示例


// define parameters. They will be sent to the server along with the request.
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()) {

    // Create a reader to access the data in a convenient way
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);

    while (reader.hasNext()) {
        reader.next(); // Read the next record from stream and parse it

        // reading data
    }

} catch (Exception e) {
    log.error("Failed to read data", e);
}

queryAll(String sqlQuery)

RowBinaryWithNamesAndTypes 格式查询数据。结果以集合返回。读取性能与使用 reader 相同,但需要更多内存来保存整个数据集。

签名

List<GenericRecord> queryAll(String sqlQuery)

参数

sqlQuery - 用于从服务器查询数据的 SQL 表达式。

返回值

完整数据集由 GenericRecord 对象列表表示,这些对象以行形式提供对结果数据的访问。

示例

try {
    log.info("Reading whole table and process record by record");
    final String sql = "select * from " + TABLE_NAME + " where title <> ''";

    // Read whole result set and process it record by record
    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("Failed to read data", e);
}

QuerySettings

查询操作的配置选项。

配置方法

方法说明
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

用于保存查询执行结果的响应对象。仅当客户端从服务器收到响应时才可用。

注意

应尽快关闭此对象以释放连接,因为在完全读取完上一个响应的所有数据之前,连接无法被重用。

方法说明
ClickHouseFormat getFormat()返回响应数据的编码格式。
InputStream getInputStream()返回按指定格式编码的未压缩数据字节流。
OperationMetrics getMetrics()返回一个包含该操作各项指标的对象。
String getQueryId()返回为该操作分配的查询 ID,该 ID 由应用程序(通过操作设置)指定或由服务器生成。
TimeZone getTimeZone()返回用于解析响应中 Date/DateTime 类型的时区。

示例

通用 API

getTableSchema(String table)

获取 table 的表结构。

签名

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

参数

table - 需要获取其 schema 数据的表名。

database - 目标表所在的数据库。

返回值

返回一个包含表的列列表的 TableSchema 对象。

getTableSchemaFromQuery(String sql)

从 SQL 语句中获取 schema 信息。

方法签名

TableSchema getTableSchemaFromQuery(String sql)

参数

sql - 用于返回其 schema 的 "SELECT" SQL 语句。

返回值

返回一个与 sql 表达式匹配列的 TableSchema 对象。

TableSchema

register(Class<?> clazz, TableSchema schema)

为 Java 类编译一个序列化/反序列化层,以便在基于 schema 进行数据读写时使用。该方法将为 getter/setter 方法对及其对应的列创建序列化器和反序列化器。 列的匹配是通过从方法名中提取列名来完成的。例如,getFirstName 将对应列 first_namefirstname

方法签名

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

参数

clazz - 表示用于读取/写入数据的 POJO 的 Class。

schema - 用于与 POJO 属性进行匹配的数据模式。

示例

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

使用示例

完整示例代码存放在代码仓库的 'example` 文件夹 中:

  • client-v2 - 主要示例集。
  • demo-service - 演示如何在 Spring Boot 应用中使用客户端的示例。
  • demo-kotlin-service - 示例,演示如何在 Ktor(Kotlin)应用中使用该客户端。

读取数据

读取数据的常用方式有两种:

  • query() 方法会返回底层的 QueryResponse 对象,该对象包含承载数据的 InputStream。通常与 ClickHouseBinaryFormatReader 组合使用以进行流式读取,但也可以配合任何其他自定义 reader 实现使用。QueryResponse 还提供对结果集元数据和指标的访问能力。
  • queryAll() 方法并使用 GenericRecord 以便按行方便访问数据。在这种情况下,整个结果集会被一次性加载到内存中。
  • queryRecords() 方法返回 com.clickhouse.client.api.query.Records —— 一个用于迭代 GenericRecord 对象的迭代器。该方法采用流式处理方式(不会将全部数据加载到内存中),并利用 GenericRecord 来访问数据。

注意: 流式方法需要快速读取,否则可能导致服务器写入超时,因为数据是直接从网络流中读取的。

读取数组

ClickHouseBinaryFormatReader 方法

  • getList(...) - 将任意 Array(...) 读取为 List<T>。适合作为类型灵活读取的默认选项。支持嵌套数组。
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - 最适用于由与基本类型兼容的值构成的一维数组。
  • getStringArray(...) - 用于 Array(String)(以及以名称形式表示的枚举值)。
  • getObjectArray(...) - 适用于任意 Array(...) 元素类型(包括嵌套数组)的通用选项。用于读取包含 Nullable 值以及嵌套数组的数组。

所有方法都提供基于索引和基于名称的重载。索引从 1 开始计数。基于索引的重载会直接访问对应的列。 基于名称的方法每次调用都需要执行一次索引查找。

try (QueryResponse response = client.query("SELECT * FROM my_table").get()) {
    ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);
    while (reader.next() != null) {
        
        Object[] uint64 = reader.getObjectArray("uint64_arr"); // Array(UInt64) -> BigInteger[]
        Object[] arr2d = reader.getObjectArray("arr2d");       // Array(Array(Int64)) -> Object[]

        // nested arrays are returned as nested Object[]:
        Object[] firstInner = (Object[]) arr2d[0];
        Long firstValue = (Long) firstInner[0];
    }
}

GenericRecord 方法

  • getList(...) - 将任意 Array(...) 解析为 List<T>。适合作为灵活类型读取的默认选项,支持嵌套数组。
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - 最适用于由与原始类型兼容的值组成的一维数组。
  • getStringArray(...) - 用于 Array(String)(以及以名称表示的枚举类型值)。
  • getObjectArray(...) - 针对任意 Array(...) 元素类型(包括嵌套数组)的通用选项。用于读取包含 Nullable 值以及嵌套数组的数组。

对于所有方法,都提供基于索引和基于名称的重载。索引从 1 开始。基于索引的重载直接访问列。 基于名称的方法每次都需要进行索引查找。

try (QueryResponse response = client.query("SELECT * FROM my_table").get()) {
    List<GenericRecord> rows = client.queryAll(
        "SELECT int_arr, arr2d_nullable FROM test_arrays ORDER BY id");

    for (GenericRecord row : rows) {
        Object[] intArr = row.getObjectArray("int_arr");                 // Array(Int32) -> Integer[]
        Object[] arr2d = row.getObjectArray("arr2d_nullable");           // Array(Array(Nullable(Int32)))

        Object[] inner = (Object[]) arr2d[0];
        Object maybeNull = inner[1]; // may be null
    }
}


## Migration Guide                   


Old client (V1) was using `com.clickhouse.client.ClickHouseClient#builder` as start point. The new client (V2) uses similar pattern with `com.clickhouse.client.api.Client.Builder`. Main
differences are:
- no service loader is used to grab implementation. The `com.clickhouse.client.api.Client` is facade class for all kinds of implementation in the future.
- a fewer sources of configuration: one is provided to the builder and one is with operation settings (`QuerySettings`, `InsertSettings`). Previous version had configuration per node and was loading
env. variables in some cases.

### Configuration Parameters Match                            

There are 3 enum classes related to configuration in V1:
- `com.clickhouse.client.config.ClickHouseDefaults` - configuration parameters that supposed to be set in most use cases. Like `USER` and `PASSWORD`.
- `com.clickhouse.client.config.ClickHouseClientOption` - configuration parameters specific for the client. Like `HEALTH_CHECK_INTERVAL`.
- `com.clickhouse.client.http.config.ClickHouseHttpOption` - configuration parameters specific for HTTP interface. Like `RECEIVE_QUERY_PROGRESS`.

They were designed to group parameters and provide clear separation. However in some cases it lead to a confusion (is there a difference between `com.clickhouse.client.config.ClickHouseDefaults#ASYNC` and
`com.clickhouse.client.config.ClickHouseClientOption#ASYNC`). The new V2 client uses `com.clickhouse.client.api.Client.Builder` as single dictionary of all possible client configuration options.There is
`com.clickhouse.client.api.ClientConfigProperties` where all configuration parameter names are listed.

Table below shows what old options are supported in the new client and their new meaning.

**Legend:** ✔ = supported, ✗ = dropped

<Tabs groupId="v1-migration">
<TabItem value="connection-auth" label="Connection & Auth">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#HOST` | `Client.Builder#addEndpoint` | |
| `ClickHouseDefaults#PROTOCOL` | ✗ | Only HTTP supported in V2 |
| `ClickHouseDefaults#DATABASE`<br/>`ClickHouseClientOption#DATABASE` | `Client.Builder#setDefaultDatabase` | |
| `ClickHouseDefaults#USER` | `Client.Builder#setUsername` | |
| `ClickHouseDefaults#PASSWORD` | `Client.Builder#setPassword` | |
| `ClickHouseClientOption#CONNECTION_TIMEOUT` | `Client.Builder#setConnectTimeout` | |
| `ClickHouseClientOption#CONNECTION_TTL` | `Client.Builder#setConnectionTTL` | |
| `ClickHouseHttpOption#MAX_OPEN_CONNECTIONS` | `Client.Builder#setMaxConnections` | |
| `ClickHouseHttpOption#KEEP_ALIVE`<br/>`ClickHouseHttpOption#KEEP_ALIVE_TIMEOUT` | `Client.Builder#setKeepAliveTimeout` | |
| `ClickHouseHttpOption#CONNECTION_REUSE_STRATEGY` | `Client.Builder#setConnectionReuseStrategy` | |
| `ClickHouseHttpOption#USE_BASIC_AUTHENTICATION` | `Client.Builder#useHTTPBasicAuth` | |

</TabItem>

<TabItem value="ssl" label="SSL & Security">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#SSL_CERTIFICATE_TYPE` | ✗ | |
| `ClickHouseDefaults#SSL_KEY_ALGORITHM` | ✗ | |
| `ClickHouseDefaults#SSL_PROTOCOL` | ✗ | |
| `ClickHouseClientOption#SSL` | ✗ | See `Client.Builder#addEndpoint` |
| `ClickHouseClientOption#SSL_MODE` | ✗ | |
| `ClickHouseClientOption#SSL_ROOT_CERTIFICATE` | `Client.Builder#setRootCertificate` | SSL Auth should be enabled by `useSSLAuthentication` |
| `ClickHouseClientOption#SSL_CERTIFICATE` | `Client.Builder#setClientCertificate` | |
| `ClickHouseClientOption#SSL_KEY` | `Client.Builder#setClientKey` | |
| `ClickHouseClientOption#KEY_STORE_TYPE` | `Client.Builder#setSSLTrustStoreType` | |
| `ClickHouseClientOption#TRUST_STORE` | `Client.Builder#setSSLTrustStore` | |
| `ClickHouseClientOption#KEY_STORE_PASSWORD` | `Client.Builder#setSSLTrustStorePassword` | |
| `ClickHouseClientOption#SSL_SOCKET_SNI` | `Client.Builder#sslSocketSNI` | |
| `ClickHouseClientOption#CUSTOM_SOCKET_FACTORY` | ✗ | |
| `ClickHouseClientOption#CUSTOM_SOCKET_FACTORY_OPTIONS` | ✗ | See `Client.Builder#sslSocketSNI` to set SNI |

</TabItem>

<TabItem value="socket" label="Socket Options">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseClientOption#SOCKET_TIMEOUT` | `Client.Builder#setSocketTimeout` | |
| `ClickHouseClientOption#SOCKET_REUSEADDR` | `Client.Builder#setSocketReuseAddress` | |
| `ClickHouseClientOption#SOCKET_KEEPALIVE` | `Client.Builder#setSocketKeepAlive` | |
| `ClickHouseClientOption#SOCKET_LINGER` | `Client.Builder#setSocketLinger` | |
| `ClickHouseClientOption#SOCKET_IP_TOS` | ✗ | |
| `ClickHouseClientOption#SOCKET_TCP_NODELAY` | `Client.Builder#setSocketTcpNodelay` | |
| `ClickHouseClientOption#SOCKET_RCVBUF` | `Client.Builder#setSocketRcvbuf` | |
| `ClickHouseClientOption#SOCKET_SNDBUF` | `Client.Builder#setSocketSndbuf` | |

</TabItem>

<TabItem value="compression" label="Compression">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseClientOption#COMPRESS` | `Client.Builder#compressServerResponse` | See also `useHttpCompression` |
| `ClickHouseClientOption#DECOMPRESS` | `Client.Builder#compressClientRequest` | See also `useHttpCompression` |
| `ClickHouseClientOption#COMPRESS_ALGORITHM` | ✗ | `LZ4` for non-http. Http uses `Accept-Encoding` |
| `ClickHouseClientOption#DECOMPRESS_ALGORITHM` | ✗ | `LZ4` for non-http. Http uses `Content-Encoding` |
| `ClickHouseClientOption#COMPRESS_LEVEL` | ✗ | |
| `ClickHouseClientOption#DECOMPRESS_LEVEL` | ✗ | |

</TabItem>

<TabItem value="proxy" label="Proxy">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseClientOption#PROXY_TYPE` | `Client.Builder#addProxy` | |
| `ClickHouseClientOption#PROXY_HOST` | `Client.Builder#addProxy` | |
| `ClickHouseClientOption#PROXY_PORT` | `Client.Builder#addProxy` | |
| `ClickHouseClientOption#PROXY_USERNAME` | `Client.Builder#setProxyCredentials` | |
| `ClickHouseClientOption#PROXY_PASSWORD` | `Client.Builder#setProxyCredentials` | |

</TabItem>

<TabItem value="timeouts-retry" label="Timeouts & Retry">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseClientOption#MAX_EXECUTION_TIME` | `Client.Builder#setExecutionTimeout` | |
| `ClickHouseClientOption#RETRY` | `Client.Builder#setMaxRetries` | See also `retryOnFailures` |
| `ClickHouseHttpOption#AHC_RETRY_ON_FAILURE` | `Client.Builder#retryOnFailures` | |
| `ClickHouseClientOption#FAILOVER` | ✗ | |
| `ClickHouseClientOption#REPEAT_ON_SESSION_LOCK` | ✗ | |
| `ClickHouseClientOption#SESSION_ID` | ✗ | |
| `ClickHouseClientOption#SESSION_CHECK` | ✗ | |
| `ClickHouseClientOption#SESSION_TIMEOUT` | ✗ | |

</TabItem>

<TabItem value="timezone" label="Timezone">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#SERVER_TIME_ZONE`<br/>`ClickHouseClientOption#SERVER_TIME_ZONE` | `Client.Builder#setServerTimeZone` | |
| `ClickHouseClientOption#USE_SERVER_TIME_ZONE` | `Client.Builder#useServerTimeZone` | |
| `ClickHouseClientOption#USE_SERVER_TIME_ZONE_FOR_DATES` | | |
| `ClickHouseClientOption#USE_TIME_ZONE` | `Client.Builder#useTimeZone` | |

</TabItem>

<TabItem value="buffers" label="Buffers & Performance">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseClientOption#BUFFER_SIZE` | `Client.Builder#setClientNetworkBufferSize` | |
| `ClickHouseClientOption#BUFFER_QUEUE_VARIATION` | ✗ | |
| `ClickHouseClientOption#READ_BUFFER_SIZE` | ✗ | |
| `ClickHouseClientOption#WRITE_BUFFER_SIZE` | ✗ | |
| `ClickHouseClientOption#REQUEST_CHUNK_SIZE` | ✗ | |
| `ClickHouseClientOption#REQUEST_BUFFERING` | ✗ | |
| `ClickHouseClientOption#RESPONSE_BUFFERING` | ✗ | |
| `ClickHouseClientOption#MAX_BUFFER_SIZE` | ✗ | |
| `ClickHouseClientOption#MAX_QUEUED_BUFFERS` | ✗ | |
| `ClickHouseClientOption#MAX_QUEUED_REQUESTS` | ✗ | |
| `ClickHouseClientOption#REUSE_VALUE_WRAPPER` | ✗ | |

</TabItem>

<TabItem value="threading" label="Threading & Async">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#ASYNC`<br/>`ClickHouseClientOption#ASYNC` | `Client.Builder#useAsyncRequests` | |
| `ClickHouseDefaults#MAX_SCHEDULER_THREADS` | ✗ | see `setSharedOperationExecutor` |
| `ClickHouseDefaults#MAX_THREADS` | ✗ | see `setSharedOperationExecutor` |
| `ClickHouseDefaults#THREAD_KEEPALIVE_TIMEOUT` | see `setSharedOperationExecutor` | |
| `ClickHouseClientOption#MAX_THREADS_PER_CLIENT` | ✗ | |
| `ClickHouseClientOption#MAX_CORE_THREAD_TTL` | ✗ | |

</TabItem>

<TabItem value="http-headers" label="HTTP & Headers">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseHttpOption#CUSTOM_HEADERS` | `Client.Builder#httpHeaders` | |
| `ClickHouseHttpOption#CUSTOM_PARAMS` | ✗ | See `Client.Builder#serverSetting` |
| `ClickHouseClientOption#CLIENT_NAME` | `Client.Builder#setClientName` | |
| `ClickHouseHttpOption#CONNECTION_PROVIDER` | ✗ | |
| `ClickHouseHttpOption#DEFAULT_RESPONSE` | ✗ | |
| `ClickHouseHttpOption#SEND_HTTP_CLIENT_ID` | ✗ | |
| `ClickHouseHttpOption#AHC_VALIDATE_AFTER_INACTIVITY` | ✗ | Always enabled when Apache Http Client is used |

</TabItem>

<TabItem value="format-query" label="Format & Query">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#FORMAT`<br/>`ClickHouseClientOption#FORMAT` | ✗ | Moved to operation settings (`QuerySettings` and `InsertSettings`) |
| `ClickHouseClientOption#QUERY_ID` | ✗ | See `QuerySettings` and `InsertSettings` |
| `ClickHouseClientOption#LOG_LEADING_COMMENT` | ✗ | See `QuerySettings#logComment` and `InsertSettings#logComment` |
| `ClickHouseClientOption#MAX_RESULT_ROWS` | ✗ | Is server side setting |
| `ClickHouseClientOption#RESULT_OVERFLOW_MODE` | ✗ | Is server side setting |
| `ClickHouseHttpOption#RECEIVE_QUERY_PROGRESS` | ✗ | Server side setting |
| `ClickHouseHttpOption#WAIT_END_OF_QUERY` | ✗ | Server side setting |
| `ClickHouseHttpOption#REMEMBER_LAST_SET_ROLES` | `Client#setDBRoles` | Runtime config now. See also `QuerySettings#setDBRoles` and `InsertSettings#setDBRoles` |

</TabItem>

<TabItem value="node-discovery" label="Node Discovery & Load Balancing">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseClientOption#AUTO_DISCOVERY` | ✗ | |
| `ClickHouseClientOption#LOAD_BALANCING_POLICY` | ✗ | |
| `ClickHouseClientOption#LOAD_BALANCING_TAGS` | ✗ | |
| `ClickHouseClientOption#HEALTH_CHECK_INTERVAL` | ✗ | |
| `ClickHouseClientOption#HEALTH_CHECK_METHOD` | ✗ | |
| `ClickHouseClientOption#NODE_DISCOVERY_INTERVAL` | ✗ | |
| `ClickHouseClientOption#NODE_DISCOVERY_LIMIT` | ✗ | |
| `ClickHouseClientOption#NODE_CHECK_INTERVAL` | ✗ | |
| `ClickHouseClientOption#NODE_GROUP_SIZE` | ✗ | |
| `ClickHouseClientOption#CHECK_ALL_NODES` | ✗ | |

</TabItem>

<TabItem value="misc" label="Miscellaneous">

| V1 Configuration | V2 Builder Method | Comments |
|------------------|-------------------|----------|
| `ClickHouseDefaults#AUTO_SESSION` | ✗ | Session support will be reviewed |
| `ClickHouseDefaults#BUFFERING` | ✗ | |
| `ClickHouseDefaults#MAX_REQUESTS` | ✗ | |
| `ClickHouseDefaults#ROUNDING_MODE` | | |
| `ClickHouseDefaults#SERVER_VERSION`<br/>`ClickHouseClientOption#SERVER_VERSION` | `Client.Builder#setServerVersion` | |
| `ClickHouseDefaults#SRV_RESOLVE` | ✗ | |
| `ClickHouseClientOption#CUSTOM_SETTINGS` | | |
| `ClickHouseClientOption#PRODUCT_NAME` | ✗ | Use client name |
| `ClickHouseClientOption#RENAME_RESPONSE_COLUMN` | ✗ | |
| `ClickHouseClientOption#SERVER_REVISION` | ✗ | |
| `ClickHouseClientOption#TRANSACTION_TIMEOUT` | ✗ | |
| `ClickHouseClientOption#WIDEN_UNSIGNED_TYPES` | ✗ | |
| `ClickHouseClientOption#USE_BINARY_STRING` | ✗ | |
| `ClickHouseClientOption#USE_BLOCKING_QUEUE` | ✗ | |
| `ClickHouseClientOption#USE_COMPILATION` | ✗ | |
| `ClickHouseClientOption#USE_OBJECTS_IN_ARRAYS` | ✗ | |
| `ClickHouseClientOption#MAX_MAPPER_CACHE` | ✗ | |
| `ClickHouseClientOption#MEASURE_REQUEST_TIME` | ✗ | |

</TabItem>
</Tabs>


### General Differences

- Client V2 uses less proprietary classes to increase portability. For example, V2 works with any implementation of `java.io.InputStream` for
writing data to a server.
- Client V2 `async` settings is `off` by default. It means no extra threads and more application control over client. This setting should be `off` for majority of use cases. Enabling `async` will create a separate thread for a request. It only make sense when using application controlled
executor (see `com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor`)

### Writing Data

- use any implementation of `java.io.InputStream`. V1 `com.clickhouse.data.ClickHouseInputStream` is supported but NOT recommended.
- once end of input stream is detected it handled accordingly. Previously output stream of a request should be closed.

__V1 Insert TSV formatted data.__
```java
InputStream inData = getInData();
ClickHouseRequest.Mutation request = client.read(server)
        .write()
        .table(tableName)
        .format(ClickHouseFormat.TSV);
ClickHouseConfig config = request.getConfig();
CompletableFuture<ClickHouseResponse> future;
try (ClickHousePipedOutputStream requestBody = ClickHouseDataStreamFactory.getInstance()
        .createPipedOutputStream(config)) {
    // start the worker thread which transfer data from the input into ClickHouse
    future = request.data(requestBody.getInputStream()).execute();

    // Copy data from inData stream to requestBody stream

    // We need to close the stream before getting a response
    requestBody.close();

    try (ClickHouseResponse response = future.get()) {
        ClickHouseResponseSummary summary = response.getSummary();
        Assert.assertEquals(summary.getWrittenRows(), numRows, "Num of written rows");
    }
}

V2 插入 TSV 格式的数据。

InputStream inData = getInData();
InsertSettings settings = new InsertSettings().setInputStreamCopyBufferSize(8198 * 2); // set copy buffer size
try (InsertResponse response = client.insert(tableName, inData, ClickHouseFormat.TSV, settings).get(30, TimeUnit.SECONDS)) {

  // Insert is complete at this point

} catch (Exception e) {
 // Handle exception
}
  • 只需调用一个方法,无需单独创建请求对象。
  • 请求体数据流会在所有数据复制完成后自动关闭。
  • 现已提供新的低级 API:com.clickhouse.client.api.Client#insert(java.lang.String, java.util.List<java.lang.String>, com.clickhouse.client.api.DataStreamWriter, com.clickhouse.data.ClickHouseFormat, com.clickhouse.client.api.insert.InsertSettings)com.clickhouse.client.api.DataStreamWriter 专为实现自定义数据写入逻辑而设计,例如从队列中读取数据。

读取数据

  • 默认情况下,数据以 RowBinaryWithNamesAndTypes 格式读取。当需要进行数据绑定时,目前仅支持该格式。
  • 可以使用 List<GenericRecord> com.clickhouse.client.api.Client#queryAll(java.lang.String) 方法将数据读取为一组记录。该方法会将数据读入内存并释放连接,无需额外处理。GenericRecord 提供对数据的访问能力,并实现了一些类型转换。
Collection<GenericRecord> records = client.queryAll("SELECT * FROM table");
for (GenericRecord record : records) {
    int rowId = record.getInteger("rowID");
    String name = record.getString("name");
    LocalDateTime ts = record.getLocalDateTime("ts");
}

用于通过协议与数据库服务器通信的 Java 客户端库。当前实现仅支持 HTTP 接口。该库提供自己的 API,用于向服务器发送请求。

弃用

该库即将弃用。新项目请使用最新的 Java 客户端

设置

<!-- https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client -->
<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>clickhouse-http-client</artifactId>
    <version>0.7.2</version>
</dependency>

从版本 0.5.0 开始,驱动程序使用新的 HTTP 客户端库,需要将其添加为依赖项。

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version>
</dependency>

初始化

连接 URL 的格式为:protocol://host[:port][/database][?param[=value][&param[=value]][#tag[,tag]],例如:

连接到单个节点:

ClickHouseNode server = ClickHouseNode.of("http://localhost:8123/default?compress=0");

连接到多节点集群:

ClickHouseNodes servers = ClickHouseNodes.of(
    "jdbc:ch:http://server1.domain,server2.domain,server3.domain/my_db"
    + "?load_balancing_policy=random&health_check_interval=5000&failover=2");

查询 API

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from numbers limit :limit")
        .params(1000)
        .executeAndWait()) {
            ClickHouseResponseSummary summary = response.getSummary();
            long totalRows = summary.getTotalRowsToRead();
}

流式查询 API

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from numbers limit :limit")
        .params(1000)
        .executeAndWait()) {
            for (ClickHouseRecord r : response.records()) {
            int num = r.getValue(0).asInteger();
            // type conversion
            String str = r.getValue(0).asString();
            LocalDate date = r.getValue(0).asDate();
        }
}

请参阅代码仓库中的完整代码示例

插入 API


try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers).write()
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("insert into my_table select c2, c3 from input('c1 UInt8, c2 String, c3 Int32')")
        .data(myInputStream) // `myInputStream` is source of data in RowBinary format
        .executeAndWait()) {
            ClickHouseResponseSummary summary = response.getSummary();
            summary.getWrittenRows();
}

请参阅代码仓库中的完整代码示例

RowBinary 编码

有关 RowBinary 格式的说明,请参见其页面

以下是一个 代码示例

功能

压缩

客户端默认使用 LZ4 压缩,这需要以下依赖项:

<!-- https://mvnrepository.com/artifact/org.lz4/lz4-java -->
<dependency>
    <groupId>org.lz4</groupId>
    <artifactId>lz4-java</artifactId>
    <version>1.8.0</version>
</dependency>

您也可以在连接 URL 中将 compress_algorithm 设置为 gzip,以改用 gzip。

另外,您也可以通过以下几种方式禁用压缩。

  1. 在连接 URL 中将 compress 设置为 0 即可禁用压缩:http://localhost:8123/default?compress=0
  2. 在客户端配置中禁用:
ClickHouseClient client = ClickHouseClient.builder()
   .config(new ClickHouseConfig(Map.of(ClickHouseClientOption.COMPRESS, false)))
   .nodeSelector(ClickHouseNodeSelector.of(ClickHouseProtocol.HTTP))
   .build();

请参阅压缩文档,以进一步了解可用的压缩选项。

多条查询

在同一会话中由一个工作线程依次执行多个查询:

CompletableFuture<List<ClickHouseResponseSummary>> future = ClickHouseClient.send(servers.apply(servers.getNodeSelector()),
    "create database if not exists my_base",
    "use my_base",
    "create table if not exists test_table(s String) engine=Memory",
    "insert into test_table values('1')('2')('3')",
    "select * from test_table limit 1",
    "truncate table test_table",
    "drop table if exists test_table");
List<ClickHouseResponseSummary> results = future.get();

命名参数

您可以按名称传递参数,而不是仅依赖参数在参数列表中的位置。该功能可通过 params 函数实现。

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from my_table where name=:name limit :limit")
        .params("Ben", 1000)
        .executeAndWait()) {
            //...
        }
}
参数

所有涉及 String 类型的 params 签名(StringString[]Map<String, String>)均假定传入的键为有效的 ClickHouse SQL 字符串。例如:

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from my_table where name=:name")
        .params(Map.of("name","'Ben'"))
        .executeAndWait()) {
            //...
        }
}

如果您不想手动将 String 对象解析为 ClickHouse SQL,可以使用位于 com.clickhouse.data 的辅助函数 ClickHouseValues.convertToSqlExpression

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
     ClickHouseResponse response = client.read(servers)
        .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
        .query("select * from my_table where name=:name")
        .params(Map.of("name", ClickHouseValues.convertToSqlExpression("Ben's")))
        .executeAndWait()) {
            //...
        }
}

在上述示例中,ClickHouseValues.convertToSqlExpression 会转义其中的单引号,并使用有效的单引号将该变量包裹起来。

其他类型,如 IntegerUUIDArrayEnum,会在 params 中自动进行转换。

节点发现

Java 客户端支持自动发现 ClickHouse 节点。自动发现功能默认禁用。要手动启用它,请将 auto_discovery 设置为 true

properties.setProperty("auto_discovery", "true");

或在连接 URL 中:

jdbc:ch://my-server/system?auto_discovery=true

启用自动发现后,无需在连接 URL 中指定所有 ClickHouse 节点。URL 中指定的节点将作为种子节点,Java 客户端会自动从系统表以及/或 clickhouse-keeper 或 zookeeper 中发现更多节点。

以下选项用于自动发现相关配置:

属性默认值描述
auto_discoveryfalse客户端是否应从 system 表以及/或 clickhouse-keeper/zookeeper 中自动发现更多节点。
node_discovery_interval0以毫秒为单位的节点发现间隔,值为零或负数表示仅进行一次发现。
node_discovery_limit100单次可发现的最大节点数;设置为零或负值表示不限制。

负载均衡

Java 客户端根据负载均衡策略选择 ClickHouse 节点来发送请求。通常,负载均衡策略负责以下事项:

  1. 从托管的节点列表中获取一个节点。
  2. 管理节点的状态。
  3. (可选)调度一个用于节点发现的后台进程(如果已启用自动发现),并执行健康检查。

以下是配置负载均衡的选项列表:

属性默认值描述
load_balancing_policy""负载均衡策略可以是以下之一:
  • firstAlive - 请求将被发送到受管节点列表中第一个健康节点
  • random - 请求将被发送到受管节点列表中随机选取的一个节点
  • roundRobin - 请求将按照轮询方式依次发送到受管节点列表中的每个节点
  • 实现 ClickHouseLoadBalancingPolicy 的全限定类名 - 自定义负载均衡策略
  • 如果未指定该策略,请求将被发送到受管节点列表中的第一个节点
    load_balancing_tags""用于筛选节点的负载均衡标签。只有具有指定标签的节点才会接收请求。
    health_check_interval0健康检查的时间间隔(毫秒)。值为 0 或负数表示只执行一次检查。
    health_check_methodClickHouseHealthCheckMethod.SELECT_ONE健康检查方法。可以是以下之一:
  • ClickHouseHealthCheckMethod.SELECT_ONE - 通过 select 1 查询进行检查
  • ClickHouseHealthCheckMethod.PING - 协议特定的检查,通常更快
  • node_check_interval0以毫秒为单位的节点检查间隔,负数将被视为 0。仅当自上次检查以来已过去指定的时间时,才会检查节点状态。
    health_check_intervalnode_check_interval 的区别在于,health_check_interval 选项会调度一个后台任务,对节点列表(全部节点或故障节点)执行状态检查,而 node_check_interval 则指定针对某个特定节点,自上次检查以来在再次检查前至少需要经过的时间间隔。
    check_all_nodesfalse是否对所有节点执行健康检查,还是仅对故障节点执行检查。

    故障转移和重试

    Java 客户端提供一些配置选项,用于配置故障转移和失败查询的重试行为:

    参数默认值说明
    failover0针对单个请求允许执行故障转移的最大次数。值为 0 或负数表示不进行故障转移。发生故障转移时,客户端会根据负载均衡策略将失败的请求发送到其他节点,以从故障中恢复。
    retry0单个请求允许重试的最大次数。为零或负值时表示不进行重试。重试时,请求会发送到同一节点,并且仅当 ClickHouse 服务器返回 NETWORK_ERROR 错误码时才会执行重试。
    repeat_on_session_locktrue当会话被锁定时,是否重复执行直到会话超时(超时时间由 session_timeoutconnect_timeout 决定)。如果 ClickHouse 服务器返回 SESSION_IS_LOCKED 错误码,则会重试该失败请求。

    添加自定义 HTTP 请求头

    Java 客户端在使用 HTTP/S 传输层时支持为请求添加自定义 HTTP 请求头。 应使用 custom_http_headers 属性,多个请求头之间使用 , 分隔,单个请求头中的键和值使用 = 分隔。

    Java 客户端支持

    options.put("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");
    

    JDBC 驱动

    properties.setProperty("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");