클라이언트와 드라이버 (clickhouse-client, HTTP, Python, JS, Go, JDBC, chDB)
ClickHouse 에 붙는 인터페이스(네이티브 TCP, HTTP, MySQL 과 PostgreSQL 호환 포트, Arrow Flight) 와 언어별 공식 클라이언트의 특징, 연결과 재시도, 타임아웃, 압축처럼 운영에서 실제로 신경 쓸 것을 정리합니다.
인터페이스부터
클라이언트 라이브러리는 모두 아래 인터페이스 중 하나 위에서 동작합니다. 포트 번호는 셀프 호스팅 기본값이고 ClickHouse Cloud 는 TLS 포트(9440, 8443) 만 열려 있습니다.
| 인터페이스 | 기본 포트 | 특징 |
|---|---|---|
| 네이티브 TCP | 9000 (TLS 9440) | ClickHouse 전용 프로토콜. Native 블록으로 주고받아 가장 빠르고 진행률, 프로파일 이벤트, 로그 스트림을 받음 |
| HTTP | 8123 (TLS 8443) | 어디서나 쓸 수 있는 REST 스타일. 로드밸런서, 프록시, 브라우저와 잘 맞음. 공식 Python, JS 클라이언트가 이 위에서 동작 |
| MySQL 호환 | 9004 | MySQL 프로토콜로 접속. 기존 MySQL 클라이언트와 일부 BI 도구용 |
| PostgreSQL 호환 | 9005 | PostgreSQL 프로토콜로 접속. 기능 제한 있음 |
| gRPC | 9100 | 설정으로 켬. 스트리밍 쿼리 |
| Arrow Flight | 설정으로 지정 | 25.8 에 처음 들어온 열 지향 교환 프로토콜. PyArrow 등에서 Arrow 로 바로 받음 |
| SSH | 9022 | 25.4 부터. ssh 로 서버에 붙어 쿼리 (키 기반 인증) |
| Prometheus | 9363 | /metrics 노출용. 모니터링 |
어떤 인터페이스를 쓰든 쿼리 설정(SETTINGS 또는 파라미터), 쿼리 ID, 세션은 같은 개념으로 다룹니다.
clickhouse-client 와 clickhouse-local
curl https://clickhouse.com/ | sh # 단일 바이너리. clickhouse client, server, local 이 한 파일
./clickhouse client --host h --secure --user u --password 'p' --database shop
./clickhouse client -q "SELECT count() FROM events" --format JSONEachRow
cat events.jsonl | ./clickhouse client -q "INSERT INTO events FORMAT JSONEachRow"
./clickhouse local -q "SELECT count() FROM file('*.parquet')" # 서버 없이 파일 분석- 대화형에서는
\?로 명령 목록, 위아래 화살표로 히스토리, 여러 줄 쿼리는 세미콜론으로 끝냅니다. 최근 버전은--multiquery가 기본이라 세미콜론으로 나눈 여러 문장을 한 번에 보낼 수 있습니다. --progress,--time,--format Pretty가 유용하고,--param_name=value로{name:UInt64}파라미터 쿼리를 안전하게 씁니다.- 설정 파일
~/.clickhouse-client/config.xml에 호스트와 비밀번호를 두면 매번 안 쳐도 됩니다. 25.7 부터clickhouse-client에 AI 보조 SQL 생성(??접두어로 자연어 질문) 이 들어왔습니다. API 키를 설정에 넣어야 동작합니다. clickhouse-local은 서버 없이 같은 엔진으로 파일을 분석하는 도구입니다. 25.4 부터 데이터베이스를 디스크에 남겨 재실행해도 유지되고, 25.5 부터는SELECT없이 파일 경로만 넘겨도 암시적으로 테이블을 만들어 줍니다.
HTTP 인터페이스 직접 쓰기
# 조회: GET 또는 POST. 설정은 쿼리 파라미터로
curl -sS 'https://host:8443/?database=shop&max_execution_time=30' \
-H 'X-ClickHouse-User: reader' -H 'X-ClickHouse-Key: ...' \
--data-binary 'SELECT event, count() c FROM events GROUP BY event FORMAT JSONEachRow'
# 적재: 본문을 압축해서
zstd -c events.jsonl | curl -sS 'https://host:8443/?query=INSERT%20INTO%20events%20FORMAT%20JSONEachRow' \
-H 'Content-Encoding: zstd' -H 'X-ClickHouse-User: writer' -H 'X-ClickHouse-Key: ...' --data-binary @-- 응답 헤더
X-ClickHouse-Query-Id,X-ClickHouse-Summary(읽은 행과 바이트) 를 로그에 남기면 느린 쿼리 추적이 쉬워집니다.query_id를 직접 지정해 보내면KILL QUERY WHERE query_id = '...'로 취소할 수 있습니다. - 결과 압축은
enable_http_compression=1과Accept-Encoding: zstd를 함께 보냅니다. 큰 결과를 받을 때 네트워크 시간이 크게 줄어듭니다. session_id파라미터로 세션을 만들면SET과 임시 테이블이 유지됩니다. 로드밸런서 뒤에서는 같은 노드로 가야 하니 스티키 세션이 필요합니다.- 긴 쿼리에서 중간에 연결이 끊기는 것을 막으려면
send_progress_in_http_headers=1과http_headers_progress_interval_ms로 진행 헤더를 흘려 주거나,wait_end_of_query=1로 결과를 서버가 버퍼링하게 합니다(오류를 HTTP 상태 코드로 정확히 받을 수 있는 대신 첫 바이트가 늦어짐).
언어별 공식 클라이언트
| 언어 | 패키지 | 프로토콜 | 메모 |
|---|---|---|---|
| Python | clickhouse-connect | HTTP | 공식. query_df, insert_df(pandas), query_arrow, Numpy 지원. SQLAlchemy 방언 포함, 비동기 클라이언트(get_async_client) |
| Python | clickhouse-driver | 네이티브 | 커뮤니티. 오래 쓰였고 빠름. 유지보수 상태 확인 |
| Python | chdb | 임베디드 | 서버 없이 프로세스 안에서 ClickHouse 엔진 실행. 아래 참고 |
| JavaScript, TypeScript | @clickhouse/client (Node), @clickhouse/client-web (브라우저, Cloudflare Workers) | HTTP | 공식. 스트림 insert, ResultSet.json(), 쿼리 설정 객체 |
| Go | clickhouse-go v2 | 네이티브 또는 HTTP | 공식. database/sql 과 네이티브 API 둘 다. 저수준은 ch-go |
| Java | clickhouse-java (client-v2), JDBC 드라이버 0.8 이상 | HTTP | 공식. 새 client-v2 가 기본. JDBC 0.8 은 client-v2 위에서 재작성 |
| Rust | clickhouse 크레이트 | HTTP | 공식(2024년 이관). serde 기반 행 매핑 |
| C# | ClickHouse.Client(커뮤니티), 공식 .NET 네이티브 TCP 클라이언트(2026-10 발표) | ADO.NET | 공식 클라이언트는 아직 새로움. 문서에서 상태 확인 |
| ODBC | clickhouse-odbc | HTTP | Excel, Power BI, Tableau 등 범용 |
| 그 밖 | Ruby, PHP, Elixir, C++ (clickhouse-cpp) | 다양 | 대부분 커뮤니티. 깃허브 활동 확인 후 선택 |
Python: clickhouse-connect
import clickhouse_connect
client = clickhouse_connect.get_client(
host="xxxx.ap-northeast-2.aws.clickhouse.cloud", port=8443, secure=True,
username="app", password="...", database="shop",
settings={"max_execution_time": 60}, compress=True,
)
df = client.query_df("SELECT event, count() c FROM events WHERE ts >= {d:Date} GROUP BY event",
parameters={"d": "2026-10-01"})
client.insert("events", rows, column_names=["ts", "event", "user_id"]) # 리스트의 리스트
client.insert_df("events", df) # pandas
client.command("ALTER TABLE events ADD COLUMN IF NOT EXISTS region LowCardinality(String)")파라미터는 {name:Type} 서버 측 바인딩(parameters=) 을 쓰세요. 문자열 포맷팅으로 쿼리를 조립하면 인젝션뿐 아니라 타입 오류도 잦습니다. insert_df 는 DataFrame 타입을 ClickHouse 타입에 맞추려 애쓰지만 Nullable, DateTime64 정밀도, 정수형 범위는 테이블 정의가 기준이니 미리 맞춰 두는 것이 안전합니다.
JavaScript: @clickhouse/client
import { createClient } from "@clickhouse/client";
const client = createClient({ url: "https://host:8443", username: "app", password: "...",
clickhouse_settings: { async_insert: 1, wait_for_async_insert: 1 } });
const rs = await client.query({ query: "SELECT * FROM events LIMIT 10", format: "JSONEachRow" });
const rows = await rs.json<{ ts: string; event: string }>();
await client.insert({ table: "events", values: rows, format: "JSONEachRow" });Node 에서는 values 에 Readable 스트림을 넘겨 큰 파일을 메모리에 올리지 않고 흘려 넣을 수 있습니다. 브라우저와 Workers 용 client-web 은 fetch 기반이라 스트림 insert 와 일부 압축 옵션이 다릅니다. Cloudflare Workers 에서 ClickHouse Cloud 로 쿼리하는 구성이 바로 이 조합입니다.
Go: clickhouse-go
conn, err := clickhouse.Open(&clickhouse.Options{
Addr: []string{"h1:9440", "h2:9440"}, Protocol: clickhouse.Native,
TLS: &tls.Config{}, Auth: clickhouse.Auth{Database: "shop", Username: "app", Password: "..."},
Compression: &clickhouse.Compression{Method: clickhouse.CompressionLZ4},
Settings: clickhouse.Settings{"max_execution_time": 60},
})
batch, _ := conn.PrepareBatch(ctx, "INSERT INTO events (ts, event, user_id)")
for _, e := range events { _ = batch.Append(e.TS, e.Event, e.UserID) }
_ = batch.Send()Addr 에 복제본 여러 개를 주면 연결 실패 시 다음 주소로 넘어갑니다(ConnOpenStrategy 로 라운드로빈). PrepareBatch 와 Send 가 곧 배치 INSERT 라서, 행 하나마다 Exec 를 부르는 코드만 피하면 됩니다.
Java: JDBC 와 client-v2
Properties p = new Properties();
p.setProperty("user", "app"); p.setProperty("password", "...");
p.setProperty("ssl", "true");
try (Connection c = DriverManager.getConnection("jdbc:ch://host:8443/shop", p);
PreparedStatement ps = c.prepareStatement("INSERT INTO events (ts, event, user_id) VALUES (?, ?, ?)")) {
for (Event e : events) { ps.setObject(1, e.ts()); ps.setString(2, e.event()); ps.setLong(3, e.userId()); ps.addBatch(); }
ps.executeBatch();
}JDBC 0.8 이상은 jdbc:ch:// URL 과 client-v2 기반입니다. Spring Data, Flink, Spark 커넥터가 이 드라이버를 쓰므로 버전을 맞춰 두세요. 기존 0.6 대의 jdbc:clickhouse:// 는 호환 모드로 동작하지만 새 프로젝트는 0.8 로 시작합니다.
chDB: 서버 없는 ClickHouse
import chdb
print(chdb.query("SELECT count() FROM file('events/*.parquet')", "Pretty"))
from chdb import session
s = session.Session("/tmp/chdb-shop") # 경로를 주면 데이터가 디스크에 남음
s.query("CREATE TABLE t ENGINE = MergeTree ORDER BY id AS SELECT number id FROM numbers(1e6)")
import pandas as pd
df = pd.read_parquet("events.parquet")
chdb.query("SELECT event, count() FROM Python(df) GROUP BY event") # DataFrame 을 테이블처럼chDB 는 ClickHouse 엔진을 라이브러리로 만든 것입니다. 노트북에서 Parquet 수십 GB 를 집계하거나, 람다 안에서 전처리하거나, 테스트에서 진짜 서버 없이 같은 SQL 을 검증할 때 씁니다. 결과를 Arrow 로 받아 pandas, Polars 와 바로 잇는 것도 가능합니다. ClickStack 과 chDB 에서 더 다룹니다.
운영에서 신경 쓸 것
- 배치로 INSERT 어떤 언어든 행 단위 INSERT 반복은 금물입니다. 라이브러리의 배치 API 를 쓰거나 비동기 INSERT 설정을 연결에 걸어 둡니다. INSERT 모범 사례.
- 타임아웃 세 가지 연결(
connect_timeout), 서버 쪽 실행 제한(max_execution_time), 클라이언트 소켓 읽기 타임아웃. 대용량 INSERT 와 긴 집계는 클라이언트 읽기 타임아웃이 서버 제한보다 길어야 합니다. 짝이 안 맞으면 서버는 계속 일하는데 클라이언트만 끊겨 재시도가 겹칩니다. - 재시도 조회는 그냥 재시도해도 됩니다. INSERT 는 같은 배치를 그대로 다시 보내야 블록 중복 제거가 받아 줍니다. 멱등성 토큰(
insert_deduplication_token) 을 쓰면 더 확실합니다. - 압축 네이티브는 LZ4 가 기본이고, HTTP 는 요청과 응답 압축을 각각 켜야 합니다. 클라우드 환경에서는 압축이 곧 전송 비용입니다.
- 연결 수 HTTP 클라이언트는 연결 풀 크기를, 네이티브는
max_open_connections류 옵션을 둡니다. ClickHouse 는 연결당 스레드가 아니지만 동시 쿼리 수(max_concurrent_queries) 제한에 걸릴 수 있습니다. - 사용자 분리 읽기 전용 사용자(
readonly = 1), 쓰기 전용 사용자, 관리 사용자를 나누고 각자 설정 프로필(메모리, 실행 시간, 쿼터) 을 다르게 둡니다. 서버 설정. - 쿼리 ID 와 로그 애플리케이션 요청 ID 를
query_id로 넘기면system.query_log에서 바로 찾습니다. 느린 쿼리 분석은 느린 쿼리 진단.
BI, 시각화, 도구 연동
Grafana(공식 플러그인), Metabase, Apache Superset, Tableau(공식 커넥터), Power BI(공식 커넥터와 ODBC), Looker Studio, DBeaver, DataGrip 이 ClickHouse 를 지원합니다. 변환 도구는 dbt(dbt-clickhouse), 오케스트레이션은 Airflow 공식 provider(apache-airflow-providers-clickhousedb), AI 에이전트 연동은 공식 MCP 서버(mcp-clickhouse) 가 있습니다. 대부분 HTTP 인터페이스를 쓰므로 8443 과 전용 읽기 사용자만 열어 주면 됩니다.