DB 서버와 프로토콜을 통해 통신하기 위한 Java 클라이언트 라이브러리입니다. 현재 구현은 HTTP 인터페이스만 지원합니다. 이 라이브러리는 서버에 요청을 전송하기 위한 자체 API를 제공하며, 다양한 바이너리 데이터 포맷(RowBinary* & Native*)을 처리하기 위한 도구도 함께 제공합니다.
Setup
- Maven Central (프로젝트 웹 페이지): https://mvnrepository.com/artifact/com.clickhouse/client-v2
- 나이틀리 빌드(리포지토리 링크): https://central.sonatype.com/repository/maven-snapshots/
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>client-v2</artifactId>
<version>0.9.8</version>
</dependency>// https://mvnrepository.com/artifact/com.clickhouse/client-v2
implementation("com.clickhouse:client-v2:0.9.8")// https://mvnrepository.com/artifact/com.clickhouse/client-v2
implementation 'com.clickhouse:client-v2:0.9.8'초기화
Client 객체는 com.clickhouse.client.api.Client.Builder#build()를 통해 초기화됩니다. 각 클라이언트는 고유한 Context를 가지며, 클라이언트 간에 객체는 공유되지 않습니다.
Builder에는 편리한 설정을 위한 구성 메서드가 있습니다.
예시:
Client client = new Client.Builder()
.addEndpoint("https://clickhouse-cloud-instance:8443/")
.setUsername(user)
.setPassword(password)
.build();Client는 AutoCloseable이므로 더 이상 필요하지 않을 때 닫아야 합니다.
인증(Authentication)
인증은 초기화 단계에서 클라이언트별로 구성됩니다. 지원되는 인증 방법은 비밀번호, 액세스 토큰, SSL 클라이언트 인증서의 세 가지입니다.
password를 통한 인증(authentication)은 setUsername(String) 및 setPassword(String)을 호출하여 username과 password를 설정해야 합니다:
Client client = new Client.Builder()
.addEndpoint("https://clickhouse-cloud-instance:8443/")
.setUsername(user)
.setPassword(password)
.build();액세스 토큰을 통한 인증(authentication)을 사용하려면 setAccessToken(String)을 호출하여 액세스 토큰을 설정해야 합니다:
Client client = new Client.Builder()
.addEndpoint("https://clickhouse-cloud-instance:8443/")
.setAccessToken(userAccessToken)
.build();SSL 클라이언트 인증서로 인증하려면 setUsername(String), useSSLAuthentication(boolean), setClientCertificate(String), setClientKey(String)를 각각 호출하여 사용자 이름을 설정하고 SSL 인증을 활성화한 뒤 클라이언트 인증서와 클라이언트 키를 설정해야 합니다:
Client client = new Client.Builder()
.useSSLAuthentication(true)
.setUsername("some_user")
.setClientCertificate("some_user.crt")
.setClientKey("some_user.key")구성
모든 설정은 인스턴스 메서드(구성 메서드라고도 함)로 정의되며, 각 값의 범위와 Context를 명확하게 나타냅니다. 주요 구성 매개변수는 하나의 범위(클라이언트 또는 작업)에서 정의되고, 서로 재정의되지 않습니다.
구성은 클라이언트 생성 시 정의됩니다. com.clickhouse.client.api.Client.Builder를 참조하십시오.
클라이언트 구성
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
addEndpoint(String endpoint) |
endpoint - URL 형식의 서버 주소 |
사용 가능한 서버 목록에 서버 엔드포인트를 추가합니다. 현재는 엔드포인트 1개만 지원합니다. | none |
none |
addEndpoint(Protocol protocol, String host, int port, boolean secure) |
protocol - 연결 프로토콜host - IP 또는 호스트명secure - HTTPS 사용 여부 |
사용 가능한 서버 목록에 서버 엔드포인트를 추가합니다. 현재는 엔드포인트 1개만 지원합니다. | none |
none |
enableConnectionPool(boolean enable) |
enable - 활성화/비활성화 플래그 |
연결 풀 사용 여부를 설정합니다. | true |
connection_pool_enabled |
setMaxConnections(int maxConnections) |
maxConnections - 연결 수 |
클라이언트가 각 서버 엔드포인트에 대해 열 수 있는 연결 수를 설정합니다. | 10 |
max_open_connections |
setConnectionTTL(long timeout, ChronoUnit unit) |
timeout - timeout 값unit - 시간 단위 |
연결이 비활성 상태로 간주되기까지의 TTL을 설정합니다. | -1 |
connection_ttl |
setKeepAliveTimeout(long timeout, ChronoUnit unit) |
timeout - timeout 값unit - 시간 단위 |
HTTP 연결 keep-alive timeout을 설정합니다. Keep-Alive를 비활성화하려면 0으로 설정합니다. |
- | http_keep_alive_timeout |
setConnectionReuseStrategy(ConnectionReuseStrategy strategy) |
strategy - LIFO 또는 FIFO |
연결 풀이 사용할 전략을 선택합니다. | FIFO |
connection_reuse_strategy |
setDefaultDatabase(String database) |
database - 데이터베이스 이름 |
기본 데이터베이스를 설정합니다. | default |
database |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
setUsername(String username) |
username - 인증에 사용할 사용자 이름 |
추가 구성에서 선택하는 인증 메서드에 사용할 사용자 이름을 설정합니다 | default |
user |
setPassword(String password) |
password - 시크릿 값 |
비밀번호 인증에 사용할 시크릿을 설정하며, 해당 인증 메서드가 사실상 선택됩니다 | - | password |
setAccessToken(String accessToken) |
accessToken - 액세스 토큰 문자열 |
해당 인증 메서드에 사용할 액세스 토큰을 설정합니다 | - | access_token |
useSSLAuthentication(boolean useSSLAuthentication) |
useSSLAuthentication - SSL 인증 활성화 플래그 |
SSL 클라이언트 인증서를 인증 메서드로 설정합니다. | - | ssl_authentication |
useHTTPBasicAuth(boolean useBasicAuth) |
useBasicAuth - 활성화/비활성화 플래그 |
사용자 이름-비밀번호 인증에 기본 HTTP 인증을 사용할지 설정합니다. 특수 문자가 포함된 비밀번호에서 발생하는 문제를 해결합니다. | true |
http_use_basic_auth |
useBearerTokenAuth(String bearerToken) |
bearerToken - 인코딩된 Bearer 토큰 |
Bearer 인증 사용 여부와 사용할 토큰을 지정합니다. 토큰은 그대로 전송됩니다. | - | bearer_token |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
setConnectTimeout(long timeout, ChronoUnit unit) |
timeout - 제한 시간 값unit - 시간 단위 |
모든 아웃바운드 연결에 대한 연결 시작 timeout을 설정합니다. | - | connection_timeout |
setConnectionRequestTimeout(long timeout, ChronoUnit unit) |
timeout - 제한 시간 값unit - 시간 단위 |
연결 요청 timeout을 설정합니다. 이 설정은 풀에서 연결을 가져올 때만 적용됩니다. | 10000 |
connection_request_timeout |
setSocketTimeout(long timeout, ChronoUnit unit) |
timeout - 제한 시간 값unit - 시간 단위 |
읽기 및 쓰기 작업에 영향을 주는 소켓 timeout을 설정합니다. | 0 |
socket_timeout |
setExecutionTimeout(long timeout, ChronoUnit timeUnit) |
timeout - 제한 시간 값timeUnit - 시간 단위 |
쿼리의 최대 실행 timeout을 설정합니다. | 0 |
max_execution_time |
retryOnFailures(ClientFaultCause ...causes) |
causes - ClientFaultCause의 enum 상수 |
복구 가능하고 재시도할 수 있는 장애 유형을 설정합니다. | NoHttpResponse ConnectTimeout ConnectionRequestTimeout |
client_retry_on_failures |
setMaxRetries(int maxRetries) |
maxRetries - 재시도 횟수 |
retryOnFailures에서 정의한 실패에 대한 최대 재시도 횟수를 설정합니다. |
3 |
retry |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
setSocketRcvbuf(long size) |
size - 바이트 단위 크기 |
TCP 소켓 수신 버퍼를 설정합니다. 이 버퍼는 JVM 메모리 외부에 있습니다. | 8196 |
socket_rcvbuf |
setSocketSndbuf(long size) |
size - 바이트 단위 크기 |
TCP 소켓 송신 버퍼를 설정합니다. 이 버퍼는 JVM 메모리 외부에 있습니다. | 8196 |
socket_sndbuf |
setSocketKeepAlive(boolean value) |
value - 활성화/비활성화 플래그 |
모든 TCP 소켓에 SO_KEEPALIVE 옵션을 설정합니다. TCP Keep Alive는 연결 상태를 확인하는 메커니즘을 활성화합니다. |
- | socket_keepalive |
setSocketTcpNodelay(boolean value) |
value - 활성화/비활성화 플래그 |
모든 TCP 소켓에 SO_NODELAY 옵션을 설정합니다. 이 TCP 옵션은 소켓이 가능한 한 빨리 데이터를 전송하도록 합니다. |
- | socket_tcp_nodelay |
setSocketLinger(int secondsToWait) |
secondsToWait - 초 단위 값 |
클라이언트가 생성하는 모든 TCP 소켓의 linger 시간을 설정합니다. | - | socket_linger |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
compressServerResponse(boolean enabled) |
enabled - 활성화/비활성화 플래그 |
서버가 응답을 압축할지 설정합니다. | true |
compress |
compressClientRequest(boolean enabled) |
enabled - 활성화/비활성화 플래그 |
클라이언트가 요청을 압축할지 설정합니다. | false |
decompress |
useHttpCompression(boolean enabled) |
enabled - 활성화/비활성화 플래그 |
해당 옵션이 활성화된 경우 클라이언트/서버 통신에 HTTP 압축을 사용할지 설정합니다. | - | - |
appCompressedData(boolean enabled) |
enabled - 활성화/비활성화 플래그 |
압축이 애플리케이션에서 처리된다는 것을 클라이언트에 알립니다. | false |
app_compressed_data |
setLZ4UncompressedBufferSize(int size) |
size - 바이트 단위 크기 |
데이터 스트림의 비압축 부분을 수신할 버퍼의 크기를 설정합니다. | 65536 |
compression.lz4.uncompressed_buffer_size |
disableNativeCompression |
disable - 비활성화 플래그 |
네이티브 압축을 비활성화합니다. true로 설정하면 네이티브 압축이 비활성화됩니다. |
false |
disable_native_compression |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
setSSLTrustStore(String path) |
path - 로컬 시스템의 파일 경로 |
서버 호스트를 검증할 때 클라이언트가 SSL 트러스트스토어를 사용할지 설정합니다. | - | trust_store |
setSSLTrustStorePassword(String password) |
password - 시크릿 값 |
setSSLTrustStore로 지정한 SSL 트러스트스토어의 잠금을 해제하는 데 사용할 비밀번호를 설정합니다. |
- | key_store_password |
setSSLTrustStoreType(String type) |
type - 트러스트스토어 유형 이름 |
setSSLTrustStore로 지정한 트러스트스토어의 유형을 설정합니다. |
- | key_store_type |
setRootCertificate(String path) |
path - 로컬 시스템의 파일 경로 |
서버 호스트를 검증할 때 사용할 루트(CA) 인증서를 지정합니다. | - | sslrootcert |
setClientCertificate(String path) |
path - 로컬 시스템의 파일 경로 |
SSL 연결을 시작할 때 사용하며 SSL 인증에 사용할 클라이언트 인증서 경로를 설정합니다. | - | sslcert |
setClientKey(String path) |
path - 로컬 시스템의 파일 경로 |
서버와의 SSL 통신을 암호화하는 데 사용할 클라이언트 개인 키를 설정합니다. | - | ssl_key |
sslSocketSNI(String sni) |
sni - 서버 이름 문자열 |
SSL/TLS 연결에서 SNI(Server Name Indication)에 사용할 서버 이름을 설정합니다. | - | ssl_socket_sni |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
addProxy(ProxyType type, String host, int port) |
type - 프록시 유형host - 프록시 호스트명 또는 IPport - 프록시 포트 |
서버와 통신할 때 사용할 프록시를 설정합니다. | - | proxy_type, proxy_host, proxy_port |
setProxyCredentials(String user, String pass) |
user - 프록시 사용자 이름pass - 비밀번호 |
프록시 인증에 사용할 자격 증명을 설정합니다. | - | proxy_user, proxy_password |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
setHttpCookiesEnabled(boolean enabled) |
enabled - 활성화/비활성화 플래그 |
HTTP 쿠키를 저장하고 서버에 다시 전송할지 설정합니다. | - | - |
httpHeader(String key, String value) |
key - HTTP 헤더 키value - 문자열 값 |
단일 HTTP 헤더의 값을 설정합니다. 이전 값은 덮어씁니다. | none |
none |
httpHeader(String key, Collection values) |
key - HTTP 헤더 키values - 문자열 값 목록 |
단일 HTTP 헤더의 여러 값을 설정합니다. 이전 값은 덮어씁니다. | none |
none |
httpHeaders(Map headers) |
headers - HTTP headers를 담은 맵 |
여러 HTTP 헤더 값을 한 번에 설정합니다. | none |
none |
useHttpFormDataForQuery(boolean enable) |
enable - 활성화/비활성화 플래그 |
쿼리 매개변수를 URL 대신 요청 본문(request body)의 HTTP 폼 데이터로 전송할지 설정합니다. 서버 측 압축을 사용할 때만 동작합니다. 클라이언트 수준 압축이 활성화된 경우 각 매개변수가 multipart 콘텐츠로 전송되므로, 매개변수가 포함된 쿼리 요청에서는 해당 압축이 비활성화됩니다. | false |
client.http.use_form_request_for_query |
| Method | Arguments | Description | Default | Key |
|---|---|---|---|---|
serverSetting(String name, String value) |
name - 설정 이름value - 설정 값 |
각 쿼리와 함께 서버에 전달할 설정을 지정합니다. 개별 작업 설정에서 이를 재정의할 수 있습니다. 설정 목록 | none |
none |
serverSetting(String name, Collection values) |
name - 설정 이름values - 설정 값 |
여러 값을 사용해 서버에 전달할 설정을 지정합니다. 예를 들면 역할이 있습니다 | none |
none |
setOption("custom_settings_prefix", value) |
value - 접두사 문자열 |
서버에 전달되는 사용자 지정 설정의 접두사를 지정합니다. 서버 구성과 일치해야 합니다. ClickHouse Docs를 참조하십시오. | custom_ |
custom_settings_prefix |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
useServerTimeZone(boolean useServerTimeZone) |
useServerTimeZone - 활성화/비활성화 플래그 |
DateTime 및 Date 컬럼 값을 디코딩할 때 클라이언트가 서버 시간대를 사용할지 설정합니다. | true |
use_server_time_zone |
useTimeZone(String timeZone) |
timeZone - Java에서 유효한 시간대 ID |
DateTime 및 Date 컬럼 값을 디코딩할 때 지정된 시간대를 사용할지 설정합니다. 서버 시간대를 재정의합니다. | - | use_time_zone |
setServerTimeZone(String timeZone) |
timeZone - Java에서 유효한 시간대 ID |
서버 측 시간대를 설정합니다. 기본값으로 UTC 시간대가 사용됩니다. | UTC |
server_time_zone |
| 메서드 | 인수 | 설명 | 기본값 | 키 |
|---|---|---|---|---|
setOption(String key, String value) |
key - 구성 옵션 키value - 옵션 값 |
클라이언트 옵션의 원시값을 설정합니다. 속성 파일에서 구성을 읽어올 때 유용합니다. | - | - |
useAsyncRequests(boolean async) |
async - 활성화/비활성화 플래그 |
클라이언트가 요청을 별도 스레드에서 실행할지 설정합니다. 멀티스레드 작업을 어떻게 구성할지는 애플리케이션이 더 잘 알고 있으므로 기본적으로 비활성화되어 있습니다. | false |
async |
setSharedOperationExecutor(ExecutorService executorService) |
executorService - ExecutorService 인스턴스 |
작업 처리를 위한 ExecutorService를 설정합니다. | none |
none |
setQueryIdGenerator(Supplier<String> supplier) |
supplier - 쿼리 ID를 생성하는 Supplier<String> |
작업 설정(InsertSettings, QuerySettings)에 쿼리 ID가 지정되지 않은 경우 사용할 사용자 지정 쿼리 ID 생성기를 설정합니다. |
- | - |
setClientNetworkBufferSize(int size) |
size - 바이트 단위 크기 |
소켓과 애플리케이션 간에 데이터를 복사하는 데 사용하는 애플리케이션 메모리 공간의 버퍼 크기를 설정합니다. | 300000 |
client_network_buffer_size |
allowBinaryReaderToReuseBuffers(boolean reuse) |
reuse - 활성화/비활성화 플래그 |
활성화하면 리더가 숫자 트랜스코딩 시 미리 할당된 버퍼를 사용합니다. 숫자 데이터 처리 시 GC 부담을 줄여줍니다. | - | - |
columnToMethodMatchingStrategy(ColumnToMethodMatchingStrategy strategy) |
strategy - 매칭 전략 구현 |
DTO 등록 시 DTO 클래스 필드와 DB 컬럼을 매칭하는 데 사용할 사용자 지정 전략을 설정합니다. | none |
none |
setClientName(String clientName) |
clientName - 애플리케이션 이름 문자열 |
호출하는 애플리케이션에 대한 추가 정보를 설정합니다. User-Agent 헤더로 전달됩니다. |
- | client_name |
registerClientMetrics(Object registry, String name) |
registry - Micrometer registry 인스턴스name - 메트릭 그룹 이름 |
Micrometer(https://micrometer.io/) registry 인스턴스에 센서를 등록합니다. | - | - |
setServerVersion(String version) |
version - 서버 버전 문자열 |
버전 감지를 건너뛰도록 서버 버전을 설정합니다. | - | server_version |
typeHintMapping(Map typeHintMapping) |
typeHintMapping - 타입 힌트 맵 |
ClickHouse 타입에 대한 타입 힌트 매핑을 설정합니다. 예를 들어 다차원 배열이 Java 컨테이너로 표현되도록 할 수 있습니다. | - | type_hint_mapping |
클라이언트 식별
쿼리 로그에는 요청을 발생시킨 애플리케이션을 식별하는 두 필드가 있습니다: client_name과 http_user_agent. 네이티브 TCP 프로토콜은 애플리케이션을 식별하기 위해 client_name을 사용하고, HTTP 프로토콜은 http_user_agent를 사용합니다. 클라이언트 빌더에는 두 프로토콜에 대해 올바른 값을 설정하는 setClientName 메서드가 있습니다.
http_user_agent 필드는 User-Agent 헤더의 일반 형식인 application-name[/version] [(operating-system; architecture; ...)]에 따라 설정됩니다.
이 값 집합은 애플리케이션, 클라이언트 라이브러리, HTTP 클라이언트 라이브러리 등 각 계층마다 반복됩니다. setClientName 메서드로 설정한 값이 목록의 맨 앞에 옵니다.
예시:
client.setClientName("my-app-01/1.0");다음과 같은 http_user_agent 값이 생성됩니다:
my-app-01/1.0 clickhouse-java-v2/0.9.6-SNAPSHOT (Linux; jvm:17.0.17) Apache-HttpClient/5.4.4애플리케이션은 자신을 식별하기 위해 HTTP 헤더 User-Agent를 직접 설정할 수 있습니다. 단, clickhouse-java-v2/0.9.6-SNAPSHOT 부분이 헤더 끝에 자동으로 추가됩니다.
작업 식별
쿼리 로그에는 작업을 식별하고 쿼리 로그에 추가 정보를 남기는 데 사용할 수 있는 query_id와 log_comment라는 두 개의 필드가 더 있습니다.
query_id는 작업의 고유 식별자입니다. QuerySettings 클래스의 setQueryId 메서드를 호출하면 애플리케이션에서 직접 설정할 수 있습니다.
QuerySettings querySettings = new QuerySettings();
querySettings.setQueryId("some-query-id");log_comment은 쿼리 로그에 추가할 수 있는 주석입니다. QuerySettings 클래스의 logComment 메서드를 호출하면 애플리케이션에서 설정할 수 있습니다.
QuerySettings querySettings = new QuerySettings();
querySettings.logComment("some-comment");서버 설정
서버 측 설정은 클라이언트 생성 시 클라이언트 수준에서 한 번 지정하거나(Builder의 serverSetting 메서드 참조), 작업 수준에서도 지정할 수 있습니다(작업 설정 클래스의 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 headers는 모든 작업(클라이언트 수준) 또는 개별 작업(작업 수준)에 설정할 수 있습니다.
QuerySettings settings = new QuerySettings()
.httpHeader(HttpHeaders.REFERER, clientReferer)
.setQueryId(qId);setOption 메서드(Client.Builder 또는 작업 설정 클래스)를 통해 옵션을 설정하는 경우, 사용자 지정 헤더 이름에는 http_header_ 접두사를 붙여야 합니다. 이 경우 com.clickhouse.client.api.ClientConfigProperties#httpHeader() 메서드를 사용하면 편리합니다.
공통 정의
ClickHouseFormat
지원되는 포맷의 enum입니다. ClickHouse가 지원하는 모든 포맷이 포함됩니다.
raw- raw 데이터는 사용자가 직접 트랜스코딩해야 합니다full- 클라이언트가 직접 데이터를 트랜스코딩할 수 있으며, 원시 데이터 스트림을 수신합니다-- 이 포맷에서는 ClickHouse가 해당 작업을 지원하지 않습니다
이 클라이언트 버전에서 지원하는 기능은 다음과 같습니다:
삽입 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 - 요청 설정입니다.
반환 값
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(Data Transfer Object) 객체.
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) |
작업 실행 전에 설정할 DB 역할을 지정합니다. 컬렉션의 항목은 String 값이어야 합니다. |
setOption(String option, Object value) |
구성 옵션을 원시 포맷으로 설정합니다. 서버 설정은 아닙니다. |
InsertResponse
삽입 작업의 결과를 담는 응답 객체입니다. 클라이언트가 서버로부터 응답을 받은 경우에만 사용 가능합니다.
| 메서드 | 설명 |
|---|---|
OperationMetrics getMetrics() |
작업 메트릭이 포함된 객체를 반환합니다. |
String getQueryId() |
애플리케이션이 작업에 할당한 쿼리 ID(작업 설정을 통해 또는 서버가 할당)를 반환합니다. |
쿼리 API
query(String sqlQuery)
sqlQuery를 그대로 전송합니다. 응답 포맷은 쿼리 설정에 따라 결정됩니다. QueryResponse는 해당 포맷을 지원하는 리더(reader)가 읽어야 하는 응답 스트림에 대한 참조를 보유합니다.
서명
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 표현식입니다.
반환 값
결과 데이터에 행(row) 방식으로 접근할 수 있는 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) |
작업 실행 전에 설정할 DB 역할을 지정합니다. 컬렉션의 항목은 String 값이어야 합니다. |
setOption(String option, Object value) |
구성 옵션을 원시 포맷으로 설정합니다. 서버 설정은 아닙니다. |
QueryResponse
쿼리 실행 결과를 담는 응답 객체입니다. 클라이언트가 서버로부터 응답을 받은 경우에만 사용할 수 있습니다.
| 메서드 | 설명 |
|---|---|
ClickHouseFormat getFormat() |
응답 데이터가 인코딩되는 포맷을 반환합니다. |
InputStream getInputStream() |
지정된 포맷의 데이터에 대한 비압축 바이트 스트림을 반환합니다. |
OperationMetrics getMetrics() |
작업 메트릭을 담은 객체를 반환합니다. |
String getQueryId() |
애플리케이션이 작업에 할당한 쿼리 ID(작업 설정 또는 서버를 통해 할당됨)를 반환합니다. |
TimeZone getTimeZone() |
응답에서 Date/DateTime 타입을 처리할 때 사용해야 하는 시간대를 반환합니다. |
예시
공통 API
getTableSchema(String table)
table의 테이블 스키마(schema)를 가져옵니다.
서명
TableSchema getTableSchema(String table)
TableSchema getTableSchema(String table, String database)매개변수
table - 스키마 데이터를 가져올 테이블 이름입니다.
database - 대상 테이블이 정의된 데이터베이스입니다.
반환 값
테이블 컬럼 목록이 포함된 TableSchema 객체를 반환합니다.
getTableSchemaFromQuery(String sql)
SQL 구문(statement)에서 스키마(schema)를 가져옵니다.
서명
TableSchema getTableSchemaFromQuery(String sql)매개변수
sql - 스키마를 반환할 "SELECT" SQL 문입니다.
반환 값
sql 표현식에 맞는 컬럼이 포함된 TableSchema 객체를 반환합니다.
TableSchema
register(Class<?> clazz, TableSchema schema)
schema를 사용해 데이터를 읽고 쓰는 데 사용할 Java 클래스용 직렬화(serialization) 및 역직렬화(deserialization) 레이어를 컴파일합니다. 이 메서드는 getter/setter 쌍과 이에 대응하는 컬럼에 대한 직렬화기 및 역직렬화기를 생성합니다.
컬럼 매칭은 메서드 이름에서 컬럼 이름을 추출하여 수행됩니다. 예를 들어 getFirstName은 컬럼 first_name 또는 firstname에 해당합니다.
서명
void register(Class<?> clazz, TableSchema schema)매개변수
clazz - 데이터를 읽고 쓰는 데 사용되는 POJO를 나타내는 클래스입니다.
schema - POJO 속성과 매칭하는 데 사용하는 데이터 스키마입니다.
예시
client.register(ArticleViewEvent.class, client.getTableSchema(TABLE_NAME));사용 예시
전체 예시 코드는 저장소의 'example` 폴더에서 확인할 수 있습니다:
- client-v2 - 주요 예시 모음.
- demo-service - Spring Boot 애플리케이션에서 클라이언트를 사용하는 방법을 보여주는 예시입니다.
- demo-kotlin-service - Ktor(Kotlin) 애플리케이션에서 클라이언트를 사용하는 방법을 보여주는 예시입니다.
데이터 읽기
데이터를 읽는 일반적인 방법은 두 가지입니다:
- 데이터가 포함된
InputStream을 담은 저수준QueryResponse객체를 반환하는query()메서드입니다. 일반적으로 스트리밍 읽기를 위해ClickHouseBinaryFormatReader와 함께 사용되지만 다른 사용자 지정 리더 구현에서도 사용할 수 있습니다.QueryResponse는 결과 집합 메타데이터와 메트릭에도 접근할 수 있게 해줍니다. queryAll()메서드와GenericRecord를 사용하면 행에 더 편리하게 접근할 수 있습니다. 이 경우 전체 결과 세트가 메모리에 로드됩니다.queryRecords()메서드는GenericRecord객체를 위한 반복자인com.clickhouse.client.api.query.Records를 반환합니다. 이 메서드는 스트리밍 방식을 사용하므로 (데이터를 메모리에 로드하지 않음)GenericRecord를 통해 데이터에 접근합니다.
참고: 스트리밍 방식은 데이터를 네트워크 스트림에서 직접 읽으므로, 읽기 속도가 충분히 빠르지 않으면 서버 쓰기 timeout이 발생할 수 있습니다.
배열 읽기
ClickHouseBinaryFormatReader 메서드
getList(...)- 모든Array(...)를List<T>로 읽습니다. 유연한 타입 읽기에 적합한 기본값입니다. 중첩 배열도 지원합니다.getByteArray(...),getShortArray(...),getIntArray(...),getLongArray(...),getFloatArray(...),getDoubleArray(...),getBooleanArray(...)- 기본형과 호환되는 값으로 이루어진 1차원 배열에 가장 적합합니다.getStringArray(...)-Array(String)용(이름으로 표현된 enum 값도 포함).getObjectArray(...)- 중첩 배열을 포함한 모든Array(...)요소 타입에 사용할 수 있는 범용 옵션입니다. 널 허용 값을 포함하는 배열과 중첩 배열을 읽는 데 사용합니다.
모든 메서드에 대해 인덱스 기반 및 이름 기반 오버로드를 사용할 수 있습니다. 인덱스는 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(...)- 기본형과 호환되는 값으로 이루어진 1차원 배열에 가장 적합합니다.getStringArray(...)-Array(String)용(이름으로 표현된 enum 값도 포함).getObjectArray(...)- 중첩 배열을 포함한 모든Array(...)요소 타입에 사용할 수 있는 범용 옵션입니다. 널 허용 값을 포함하는 배열과 중첩 배열을 읽는 데 사용합니다.
모든 메서드에 대해 인덱스 기반 및 이름 기반 오버로드를 사용할 수 있습니다. 인덱스는 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
}
}마이그레이션 가이드
이전 클라이언트(V1)는 com.clickhouse.client.ClickHouseClient#builder를 시작점으로 사용했습니다. 새 클라이언트(V2)는 com.clickhouse.client.api.Client.Builder를 사용하는 유사한 패턴을 따릅니다. 주요 차이점은 다음과 같습니다:
- 구현을 가져오기 위해 service loader를 사용하지 않습니다.
com.clickhouse.client.api.Client는 향후 다양한 구현을 위한 파사드 클래스입니다. - 구성 소스 수가 더 적습니다. 하나는 빌더에 제공되고, 다른 하나는 작업 설정(
QuerySettings,InsertSettings)에 있습니다. 이전 버전에서는 노드별 구성을 사용했고, 경우에 따라 환경 변수도 불러왔습니다.
구성 매개변수 일치
V1에는 구성과 관련된 enum 클래스가 3개 있습니다:
com.clickhouse.client.config.ClickHouseDefaults- 대부분의 사용 사례에서 설정해야 하는 구성 매개변수입니다. 예를 들어USER및PASSWORD가 있습니다.com.clickhouse.client.config.ClickHouseClientOption- 클라이언트 전용 구성 매개변수입니다. 예:HEALTH_CHECK_INTERVAL.com.clickhouse.client.http.config.ClickHouseHttpOption- HTTP 인터페이스 전용 구성 매개변수입니다. 예:RECEIVE_QUERY_PROGRESS.
이는 매개변수를 그룹화하고 명확한 구분을 제공하기 위해 설계되었습니다. 그러나 일부 경우에는 혼란을 야기하기도 했습니다(com.clickhouse.client.config.ClickHouseDefaults#ASYNC와
com.clickhouse.client.config.ClickHouseClientOption#ASYNC 간에 차이가 있는지 불분명한 경우 등). 새로운 V2 클라이언트는 com.clickhouse.client.api.Client.Builder를 가능한 모든 클라이언트 구성 옵션의 단일 딕셔너리로 사용합니다. 모든 구성 매개변수 이름은
com.clickhouse.client.api.ClientConfigProperties에 나열되어 있습니다.
아래 표에서는 새 클라이언트에서 지원되는 기존 옵션과 해당 옵션의 새로운 의미를 확인할 수 있습니다.
범례: ✔ = 지원됨, ✗ = 삭제됨
| V1 구성 | V2 Builder 메서드 | 비고 |
|---|---|---|
ClickHouseDefaults#HOST |
Client.Builder#addEndpoint |
|
ClickHouseDefaults#PROTOCOL |
✗ | V2는 HTTP만 지원합니다 |
ClickHouseDefaults#DATABASEClickHouseClientOption#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_ALIVEClickHouseHttpOption#KEEP_ALIVE_TIMEOUT |
Client.Builder#setKeepAliveTimeout |
|
ClickHouseHttpOption#CONNECTION_REUSE_STRATEGY |
Client.Builder#setConnectionReuseStrategy |
|
ClickHouseHttpOption#USE_BASIC_AUTHENTICATION |
Client.Builder#useHTTPBasicAuth |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
ClickHouseDefaults#SSL_CERTIFICATE_TYPE |
✗ | |
ClickHouseDefaults#SSL_KEY_ALGORITHM |
✗ | |
ClickHouseDefaults#SSL_PROTOCOL |
✗ | |
ClickHouseClientOption#SSL |
✗ | Client.Builder#addEndpoint 참조 |
ClickHouseClientOption#SSL_MODE |
✗ | |
ClickHouseClientOption#SSL_ROOT_CERTIFICATE |
Client.Builder#setRootCertificate |
SSL 인증은 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 |
✗ | SNI를 설정하려면 Client.Builder#sslSocketSNI를 참조하십시오 |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
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 |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
ClickHouseClientOption#COMPRESS |
Client.Builder#compressServerResponse |
관련 항목: useHttpCompression |
ClickHouseClientOption#DECOMPRESS |
Client.Builder#compressClientRequest |
관련 항목: useHttpCompression |
ClickHouseClientOption#COMPRESS_ALGORITHM |
✗ | non-http는 LZ4를 사용합니다. Http는 Accept-Encoding을 사용합니다 |
ClickHouseClientOption#DECOMPRESS_ALGORITHM |
✗ | non-http는 LZ4를 사용합니다. Http는 Content-Encoding을 사용합니다 |
ClickHouseClientOption#COMPRESS_LEVEL |
✗ | |
ClickHouseClientOption#DECOMPRESS_LEVEL |
✗ |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
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 |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
ClickHouseClientOption#MAX_EXECUTION_TIME |
Client.Builder#setExecutionTimeout |
|
ClickHouseClientOption#RETRY |
Client.Builder#setMaxRetries |
관련 항목: 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 |
✗ |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
ClickHouseDefaults#SERVER_TIME_ZONEClickHouseClientOption#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 |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
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 |
✗ |
| V1 구성 | V2 Builder 메서드 | 비고 |
|---|---|---|
ClickHouseDefaults#ASYNCClickHouseClientOption#ASYNC |
Client.Builder#useAsyncRequests |
|
ClickHouseDefaults#MAX_SCHEDULER_THREADS |
✗ | setSharedOperationExecutor 참조 |
ClickHouseDefaults#MAX_THREADS |
✗ | setSharedOperationExecutor 참조 |
ClickHouseDefaults#THREAD_KEEPALIVE_TIMEOUT |
setSharedOperationExecutor 참조 |
|
ClickHouseClientOption#MAX_THREADS_PER_CLIENT |
✗ | |
ClickHouseClientOption#MAX_CORE_THREAD_TTL |
✗ |
| V1 구성 | V2 Builder 메서드 | 비고 |
|---|---|---|
ClickHouseHttpOption#CUSTOM_HEADERS |
Client.Builder#httpHeaders |
|
ClickHouseHttpOption#CUSTOM_PARAMS |
✗ | 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 |
✗ | Apache Http Client를 사용할 때는 항상 활성화됩니다 |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
ClickHouseDefaults#FORMATClickHouseClientOption#FORMAT |
✗ | 작업 설정(QuerySettings 및 InsertSettings)으로 이동했습니다 |
ClickHouseClientOption#QUERY_ID |
✗ | QuerySettings 및 InsertSettings를 참조하십시오 |
ClickHouseClientOption#LOG_LEADING_COMMENT |
✗ | QuerySettings#logComment 및 InsertSettings#logComment를 참조하십시오 |
ClickHouseClientOption#MAX_RESULT_ROWS |
✗ | 서버 측 설정입니다 |
ClickHouseClientOption#RESULT_OVERFLOW_MODE |
✗ | 서버 측 설정입니다 |
ClickHouseHttpOption#RECEIVE_QUERY_PROGRESS |
✗ | 서버 측 설정입니다 |
ClickHouseHttpOption#WAIT_END_OF_QUERY |
✗ | 서버 측 설정입니다 |
ClickHouseHttpOption#REMEMBER_LAST_SET_ROLES |
Client#setDBRoles |
이제 런타임 구성입니다. QuerySettings#setDBRoles 및 InsertSettings#setDBRoles도 참조하십시오 |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
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 |
✗ |
| V1 구성 | V2 빌더 메서드 | 비고 |
|---|---|---|
ClickHouseDefaults#AUTO_SESSION |
✗ | 세션 지원은 추후 검토될 예정입니다 |
ClickHouseDefaults#BUFFERING |
✗ | |
ClickHouseDefaults#MAX_REQUESTS |
✗ | |
ClickHouseDefaults#ROUNDING_MODE |
||
ClickHouseDefaults#SERVER_VERSIONClickHouseClientOption#SERVER_VERSION |
Client.Builder#setServerVersion |
|
ClickHouseDefaults#SRV_RESOLVE |
✗ | |
ClickHouseClientOption#CUSTOM_SETTINGS |
||
ClickHouseClientOption#PRODUCT_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 |
✗ |
일반적인 차이점
- Client V2는 이식성을 높이기 위해 전용 클래스 사용을 줄였습니다. 예를 들어 V2는 서버에 데이터를 쓰는 데
java.io.InputStream의 모든 구현을 사용할 수 있습니다. - Client V2에서
async설정의 기본값은off입니다. 즉, 추가 스레드가 생성되지 않으며 클라이언트 제어를 애플리케이션에서 더 많이 할 수 있습니다. 이 설정은 대부분의 사용 사례에서off로 유지해야 합니다.async를 활성화하면 요청마다 별도의 스레드가 생성됩니다. 이는 애플리케이션에서 제어하는 실행기를 사용할 때만 의미가 있습니다(참조:com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor)
데이터 쓰기
java.io.InputStream의 어떤 구현이든 사용할 수 있습니다. V1com.clickhouse.data.ClickHouseInputStream도 지원하지만 권장하지는 않습니다.- 입력 스트림의 끝이 감지되면 그에 맞게 처리됩니다. 그에 앞서 요청의 출력 스트림을 닫아야 합니다.
V1 TSV 포맷 데이터 삽입.
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)메서드를 사용해 레코드 컬렉션으로 읽을 수 있습니다. 이 메서드는 데이터를 메모리에 읽어 들인 뒤 connection을 해제합니다. 별도의 추가 처리는 필요하지 않습니다.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");
}DB 서버의 프로토콜을 통해 통신하기 위한 Java 클라이언트 라이브러리입니다. 현재 구현은 HTTP 인터페이스만 지원합니다. 이 라이브러리는 서버에 요청을 보내기 위한 자체 API를 제공합니다.
Setup
<!-- 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>// https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client
implementation("com.clickhouse:clickhouse-http-client:0.7.2")// https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client
implementation 'com.clickhouse:clickhouse-http-client:0.7.2'0.5.0 버전부터 driver는 새 클라이언트 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>// https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5
implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1")// https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'초기화
연결 URL 포맷: protocol://host[:port][/database][?param[=value][¶m[=value]][#tag[,tag]], 예시:
http://localhost:8443?ssl=true&sslmode=NONEhttps://(https://explorer@play.clickhouse.com:443
단일 노드에 연결:
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();
// 타입 변환
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`는 RowBinary 포맷의 데이터 소스입니다
.executeAndWait()) {
ClickHouseResponseSummary summary = response.getSummary();
summary.getWrittenRows();
}RowBinary 인코딩
RowBinary 포맷에 대한 자세한 내용은 해당 페이지를 참조하십시오.
코드 예시가 있습니다.
기능
압축(Compression)
클라이언트는 기본적으로 LZ4 압축(Compression)을 사용하며, 이를 위해 다음 의존성이 필요합니다:
<!-- https://mvnrepository.com/artifact/org.lz4/lz4-java -->
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>1.8.0</version>
</dependency>// https://mvnrepository.com/artifact/org.lz4/lz4-java
implementation("org.lz4:lz4-java:1.8.0")// https://mvnrepository.com/artifact/org.lz4/lz4-java
implementation 'org.lz4:lz4-java:1.8.0'연결 URL에 compress_algorithm=gzip을 설정하여 gzip을 대신 사용할 수도 있습니다.
또는 다음과 같은 몇 가지 방법으로 압축을 비활성화할 수 있습니다.
- connection URL에
compress=0을 설정해 비활성화합니다:http://localhost:8123/default?compress=0 - 클라이언트 구성에서 비활성화하십시오:
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()) {
//...
}
}노드 디스커버리
Java 클라이언트는 ClickHouse 노드를 자동으로 검색하는 디스커버리 기능을 제공합니다. 자동 디스커버리는 기본적으로 비활성화되어 있습니다. 활성화하려면 auto_discovery를 true로 설정하십시오:
properties.setProperty("auto_discovery", "true");또는 연결 URL에서:
jdbc:ch://my-server/system?auto_discovery=true자동 디스커버리가 활성화된 경우, 연결 URL에 모든 ClickHouse 노드를 지정하지 않아도 됩니다. URL에 지정된 노드는 시드(seed)로 처리되며, Java 클라이언트가 시스템 테이블(system tables) 및/또는 clickhouse-keeper나 ZooKeeper를 통해 추가 노드를 자동으로 검색합니다.
다음 옵션들은 자동 디스커버리 구성을 담당합니다:
| 속성 | 기본값 | 설명 |
|---|---|---|
| auto_discovery | false |
클라이언트가 시스템 테이블(system tables) 및/또는 clickhouse-keeper/ZooKeeper에서 추가 노드를 자동으로 찾을지 여부입니다. |
| node_discovery_interval | 0 |
밀리초 단위의 노드 디스커버리 간격이며, 값이 0 이하이면 1회성 디스커버리를 의미합니다. |
| node_discovery_limit | 100 |
한 번에 디스커버리할 수 있는 최대 노드 수입니다. 값이 0 이하이면 제한이 없습니다. |
로드 밸런싱
Java 클라이언트는 로드 밸런싱 정책에 따라 요청을 보낼 ClickHouse 노드를 선택합니다. 일반적으로 로드 밸런싱 정책은 다음 사항을 담당합니다.
- 관리형 노드 목록에서 노드를 조회합니다.
- 노드 상태 관리.
- 선택적으로 노드 디스커버리용 백그라운드 프로세스를 예약하고(자동 디스커버리가 활성화된 경우) 상태 점검을 실행합니다.
로드 밸런싱을 구성하는 옵션 목록은 다음과 같습니다:
| 속성 | 기본값 | 설명 |
|---|---|---|
| load_balancing_policy | "" |
로드 밸런싱 정책은 다음 중 하나로 설정할 수 있습니다: firstAlive - 요청이 관리 노드 목록에서 첫 번째 정상 노드로 전송됩니다random - 요청이 관리 노드 목록에서 임의의 노드로 전송됩니다 roundRobin - 요청이 관리 노드 목록의 각 노드로 순차적으로 전송됩니다.ClickHouseLoadBalancingPolicy를 구현하는 정규화된 클래스 이름 - 사용자 지정 로드 밸런싱 정책 |
| load_balancing_tags | "" |
노드를 필터링하기 위한 로드 밸런싱 태그입니다. 요청은 지정된 태그가 있는 노드로만 전송됩니다. |
| health_check_interval | 0 |
밀리초 단위의 상태 확인 간격입니다. 값이 0 이하이면 한 번만 실행됩니다. |
| health_check_method | ClickHouseHealthCheckMethod.SELECT_ONE |
헬스 체크 메서드입니다. 다음 중 하나를 사용할 수 있습니다: ClickHouseHealthCheckMethod.SELECT_ONE - select 1 쿼리로 확인ClickHouseHealthCheckMethod.PING - 프로토콜별 확인으로, 일반적으로 더 빠릅니다 |
| node_check_interval | 0 |
밀리초 단위의 노드 검사 간격입니다. 음수는 0으로 처리됩니다. 마지막 검사 이후 지정된 시간이 지나면 노드 상태를 검사합니다.health_check_interval과 node_check_interval의 차이점은 health_check_interval 옵션이 노드 목록(전체 또는 장애가 있는 노드)의 상태를 검사하는 백그라운드 작업을 예약하는 반면, node_check_interval은 특정 노드의 마지막 검사 이후 얼마나 시간이 지나야 하는지를 지정한다는 점입니다. |
| check_all_nodes | false |
모든 노드에 대해 헬스 체크를 수행할지, 아니면 장애가 있는 노드에 대해서만 수행할지를 지정합니다. |
장애 조치 및 재시도
Java 클라이언트는 실패한 쿼리에 대한 failover 및 retry 동작을 구성할 수 있는 옵션을 제공합니다:
| 속성 | 기본값 | 설명 |
|---|---|---|
| 장애 조치 | 0 |
요청에서 장애 조치가 발생할 수 있는 최대 횟수입니다. 0 또는 음수 값은 장애 조치를 수행하지 않음을 의미합니다. 장애 조치는 실패한 요청을 다른 노드로 전송하여(로드 밸런싱 정책에 따름) 장애를 복구합니다. |
| 재시도 | 0 |
요청에 대해 재시도할 수 있는 최대 횟수입니다. 0 또는 음수 값은 재시도하지 않음을 의미합니다. 재시도는 요청을 동일한 노드로 다시 보내며, ClickHouse 서버가 NETWORK_ERROR 오류 코드를 반환한 경우에만 수행됩니다. |
| repeat_on_session_lock | true |
세션이 잠긴 경우 시간 초과(session_timeout 또는 connect_timeout 기준)될 때까지 실행을 반복할지 여부입니다. ClickHouse 서버가 SESSION_IS_LOCKED 오류 코드를 반환하면 실패한 요청을 다시 시도합니다 |
사용자 지정 HTTP 헤더 추가하기
요청에 사용자 지정 HTTP 헤더를 추가해야 하는 경우 Java 클라이언트는 HTTP/S 전송 계층을 지원합니다.
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");