DB 서버와 프로토콜을 통해 통신하기 위한 Java 클라이언트 라이브러리입니다. 현재 구현은 HTTP 인터페이스만 지원합니다.
이 라이브러리는 서버에 요청을 전송하기 위한 자체 API를 제공하며, 다양한 바이너리 데이터 포맷(RowBinary* & Native*)을 처리하기 위한 도구도 함께 제공합니다.
액세스 토큰을 통한 인증(authentication)은 SSL 클라이언트 인증서로 인증하려면
다음과 같은 애플리케이션은 자신을 식별하기 위해 HTTP 헤더 ⚠️ 매개변수매개변수매개변수매개변수매개변수매개변수매개변수매개변수V2 TSV 포맷 데이터 삽입.
Setup
- Maven Central (프로젝트 웹 페이지): https://mvnrepository.com/artifact/com.clickhouse/client-v2
- 나이틀리 빌드(리포지토리 링크): https://central.sonatype.com/repository/maven-snapshots/
- 이전 Nightly 빌드용 아티팩토리(리포지토리 링크): https://s01.oss.sonatype.org/content/repositories/snapshots/
- Maven
- Gradle (Kotlin)
- Gradle
초기화
Client 객체는com.clickhouse.client.api.Client.Builder#build()를 통해 초기화됩니다. 각 클라이언트는 고유한 Context를 가지며, 클라이언트 간에 객체는 공유되지 않습니다.
Builder에는 편리한 설정을 위한 구성 메서드가 있습니다.예시:showLineNumbers
Client는 AutoCloseable이므로 더 이상 필요하지 않을 때 닫아야 합니다.인증(Authentication)
인증은 초기화 단계에서 클라이언트별로 구성됩니다. 지원되는 인증 방법은 비밀번호, 액세스 토큰, SSL 클라이언트 인증서의 세 가지입니다.password를 통한 인증(authentication)은setUsername(String) 및 setPassword(String)을 호출하여 username과 password를 설정해야 합니다:showLineNumbers
setAccessToken(String)을 호출하여 액세스 토큰을 설정해야 합니다:showLineNumbers
setUsername(String), useSSLAuthentication(boolean), setClientCertificate(String), setClientKey(String)를 각각 호출하여 사용자 이름을 설정하고 SSL 인증을 활성화한 뒤 클라이언트 인증서와 클라이언트 키를 설정해야 합니다:showLineNumbers
SSL 인증은 SSL 라이브러리에서 발생하는 많은 오류가 충분한 정보를 제공하지 않기 때문에 운영 환경(production)에서는 트러블슈팅이 어려울 수 있습니다. 예를 들어 클라이언트 인증서와 키가 일치하지 않으면 서버가 즉시 connection을 종료합니다(HTTP의 경우, HTTP request가 전송되기 전인 connection 초기화 단계에서 종료되므로 응답도 전송되지 않습니다).인증서와 키를 검증하려면 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"]}와 같은 값이 출력됩니다)
- 사용자 인증서에서 CN 가져오기 -
구성
모든 설정은 인스턴스 메서드(구성 메서드라고도 함)로 정의되며, 각 값의 범위와 Context를 명확하게 나타냅니다. 주요 구성 매개변수는 하나의 범위(클라이언트 또는 작업)에서 정의되고, 서로 재정의되지 않습니다.구성은 클라이언트 생성 시 정의됩니다.com.clickhouse.client.api.Client.Builder를 참조하십시오.클라이언트 구성
- 연결 및 엔드포인트
- 인증
- 타임아웃 및 재시도
- 소켓 옵션
- 압축
- SSL/보안
- 프록시
- HTTP 및 헤더
- 서버 설정
- 시간대
- 고급
클라이언트 식별
쿼리 로그에는 요청을 발생시킨 애플리케이션을 식별하는 두 필드가 있습니다: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 메서드로 설정한 값이 목록의 맨 앞에 옵니다.예시:showLineNumbers
http_user_agent 값이 생성됩니다:User-Agent를 직접 설정할 수 있습니다. 단, clickhouse-java-v2/0.9.6-SNAPSHOT 부분이 헤더 끝에 자동으로 추가됩니다.작업 식별
쿼리 로그에는 작업을 식별하고 쿼리 로그에 추가 정보를 남기는 데 사용할 수 있는query_id와 log_comment라는 두 개의 필드가 더 있습니다.query_id는 작업의 고유 식별자입니다. QuerySettings 클래스의 setQueryId 메서드를 호출하면 애플리케이션에서 직접 설정할 수 있습니다.showLineNumbers
log_comment은 쿼리 로그에 추가할 수 있는 주석입니다. QuerySettings 클래스의 logComment 메서드를 호출하면 애플리케이션에서 설정할 수 있습니다.showLineNumbers
서버 설정
서버 측 설정은 클라이언트 생성 시 클라이언트 수준에서 한 번 지정하거나(Builder의 serverSetting 메서드 참조), 작업 수준에서도 지정할 수 있습니다(작업 설정 클래스의 serverSetting 참조).showLineNumbers
setOption 메서드(Client.Builder 또는 작업 설정 클래스)를 통해 옵션을 설정하는 경우, 서버 설정 이름 앞에 clickhouse_setting_을 접두사로 추가해야 합니다. 이 경우 com.clickhouse.client.api.ClientConfigProperties#serverSetting()을 사용하면 편리합니다.사용자 지정 HTTP 헤더
사용자 정의 HTTP headers는 모든 작업(클라이언트 수준) 또는 개별 작업(작업 수준)에 설정할 수 있습니다.showLineNumbers
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으로 인코딩되어 있어야 합니다.서명tableName - 대상 테이블 이름입니다.data - 인코딩된 데이터의 입력 스트림입니다.format - 데이터가 인코딩되는 포맷입니다.settings - 요청 설정입니다.반환 값InsertResponse 유형의 Future - 작업 결과와 서버 측 메트릭 등의 추가 정보입니다.예시showLineNumbers
insert(String tableName, List<?> data, InsertSettings settings)
데이터베이스에 쓰기 요청을 보냅니다. 객체 목록은 효율적인 형식으로 변환된 후 서버로 전송됩니다. 목록 항목의 클래스는register(Class, TableSchema) 메서드를 사용해 사전에 등록해야 합니다.서명tableName - 대상 테이블의 이름입니다.data - 컬렉션 DTO(Data Transfer Object) 객체.settings - 요청 설정입니다.반환 값InsertResponse 유형의 Future로, 작업 결과 및 서버 측 메트릭 등의 추가 정보를 포함합니다.예시showLineNumbers
InsertSettings
삽입 작업의 구성 옵션입니다.구성 방법InsertResponse
삽입 작업의 결과를 담는 응답 객체입니다. 클라이언트가 서버로부터 응답을 받은 경우에만 사용 가능합니다.이 객체는 연결을 해제하기 위해 가능한 한 빨리 닫아야 합니다. 이전 응답의 데이터를 모두 완전히 읽기 전까지는 해당 연결을 재사용할 수 없기 때문입니다.
쿼리 API
query(String sqlQuery)
sqlQuery를 그대로 전송합니다. 응답 포맷은 쿼리 설정에 따라 결정됩니다. QueryResponse는 해당 포맷을 지원하는 리더(reader)가 읽어야 하는 응답 스트림에 대한 참조를 보유합니다.서명sqlQuery - 단일 SQL 구문입니다. 쿼리는 수정 없이 그대로 서버로 전송됩니다.settings - 요청 설정입니다.반환 값QueryResponse 유형의 Future로, 결과 데이터셋과 서버 측 메트릭 등의 추가 정보를 포함합니다. Response 객체는 데이터셋을 사용한 후 반드시 닫아야 합니다.예시query(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)
sqlQuery를 그대로 전송합니다. 또한 서버가 SQL 표현식을 컴파일할 수 있도록 쿼리 매개변수도 함께 전송합니다.서명sqlQuery - 자리 표시자 {}가 포함된 SQL 표현식입니다.queryParams - 서버에서 SQL 표현식을 완성하는 데 사용되는 변수들의 맵입니다.settings - 요청 설정입니다.반환 값QueryResponse 유형의 Future - 결과 데이터셋과 서버 측 메트릭 등의 추가 정보를 포함합니다. Response 객체는 데이터셋을 모두 사용한 후에는 반드시 닫아야 합니다.예시showLineNumbers
queryAll(String sqlQuery)
RowBinaryWithNamesAndTypes 포맷으로 데이터를 쿼리합니다. 결과를 컬렉션으로 반환합니다. 읽기 성능은 reader와 동일하지만, 전체 데이터셋을 메모리에 유지해야 하므로 더 많은 메모리가 필요합니다.서명sqlQuery - 서버에서 데이터를 쿼리하기 위한 SQL 표현식입니다.반환 값결과 데이터에 행(row) 방식으로 접근할 수 있는 GenericRecord 객체 목록으로 표현된 전체 데이터셋입니다.예시showLineNumbers
QuerySettings
쿼리 작업에 대한 구성 옵션입니다.구성 방법QueryResponse
쿼리 실행 결과를 담는 응답 객체입니다. 클라이언트가 서버로부터 응답을 받은 경우에만 사용할 수 있습니다.이 객체는 연결을 해제하기 위해 가능한 한 빨리 닫아야 합니다. 이전 응답의 데이터를 모두 완전히 읽기 전까지는 해당 연결을 재사용할 수 없기 때문입니다.
예시
공통 API
getTableSchema(String table)
table의 테이블 스키마(schema)를 가져옵니다.서명table - 스키마 데이터를 가져올 테이블 이름입니다.database - 대상 테이블이 정의된 데이터베이스입니다.반환 값테이블 컬럼 목록이 담긴 TableSchema 객체를 반환합니다.getTableSchemaFromQuery(String sql)
SQL 구문(statement)에서 스키마(schema)를 가져옵니다.서명sql - 스키마를 반환할 “SELECT” SQL 문입니다.반환 값sql 표현식에 맞는 컬럼이 포함된 TableSchema 객체를 반환합니다.TableSchema
register(Class<?> clazz, TableSchema schema)
schema를 사용하여 데이터를 쓰고 읽기 위한 Java 클래스의 직렬화(serialization) 및 역직렬화(deserialization) 레이어를 컴파일합니다. 이 메서드는 getter/setter 쌍과 해당 컬럼에 대한 직렬화기 및 역직렬화기를 생성합니다.
컬럼 매칭은 메서드 이름에서 컬럼 이름을 추출하는 방식으로 수행됩니다. 예를 들어, getFirstName은 컬럼 first_name 또는 firstname에 해당합니다.서명clazz - 데이터를 읽고 쓰는 데 사용되는 POJO를 나타내는 클래스입니다.schema - POJO 속성과 매칭하는 데 사용하는 데이터 스키마입니다.예시showLineNumbers
사용 예시
전체 예시 코드는 저장소의 ‘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를 통해 데이터에 접근합니다.
배열 읽기
ClickHouseBinaryFormatReader 메서드getList(...)- 모든Array(...)를List<T>로 읽습니다. 유연한 타입 읽기에 적합한 기본값입니다. 중첩 배열도 지원합니다.getByteArray(...),getShortArray(...),getIntArray(...),getLongArray(...),getFloatArray(...),getDoubleArray(...),getBooleanArray(...)- 기본형과 호환되는 값으로 이루어진 1차원 배열에 가장 적합합니다.getStringArray(...)-Array(String)용(이름으로 표현된 enum 값도 포함).getObjectArray(...)- 중첩 배열을 포함한 모든Array(...)요소 타입에 사용할 수 있는 범용 옵션입니다. 널 허용 값을 포함하는 배열과 중첩 배열을 읽는 데 사용합니다.
GenericRecord 메서드getList(...)- 모든Array(...)를List<T>로 읽습니다. 유연한 타입 읽기에 적합한 기본값입니다. 중첩 배열도 지원합니다.getByteArray(...),getShortArray(...),getIntArray(...),getLongArray(...),getFloatArray(...),getDoubleArray(...),getBooleanArray(...)- 기본형과 호환되는 값으로 이루어진 1차원 배열에 가장 적합합니다.getStringArray(...)-Array(String)용(이름으로 표현된 enum 값도 포함).getObjectArray(...)- 중첩 배열을 포함한 모든Array(...)요소 타입에 사용할 수 있는 범용 옵션입니다. 널 허용 값을 포함하는 배열과 중첩 배열을 읽는 데 사용합니다.
마이그레이션 가이드
이전 클라이언트(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에 나열되어 있습니다.아래 표에서는 새 클라이언트에서 지원되는 기존 옵션과 해당 옵션의 새로운 의미를 확인할 수 있습니다.범례: ✔ = 지원됨, ✗ = 삭제됨- 연결 및 인증
- SSL 및 보안
- 소켓 옵션
- 압축
- 프록시
- 타임아웃 및 재시도
- 시간대
- 버퍼 및 성능
- 스레딩 & 비동기
- HTTP 및 헤더
- 포맷 및 쿼리
- 노드 디스커버리 및 부하 분산
- 기타
일반적인 차이점
- 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도 지원하지만 권장하지는 않습니다.- 입력 스트림의 끝이 감지되면 그에 맞게 처리됩니다. 그에 앞서 요청의 출력 스트림을 닫아야 합니다.
- 호출할 메서드는 하나뿐입니다. 추가 요청 객체를 생성하지 않아도 됩니다.
- 모든 데이터가 복사되면 요청 본문 스트림이 자동으로 닫힙니다.
- 새로운 저수준 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는 데이터에 접근할 수 있게 해 주며, 일부 변환 기능도 제공합니다.