ClickHouse — как с ним разговариваютClickHouse — how it's talked to
Один сервер, два независимых протокола на разных портах: HTTP (простой, универсальный, за прокси) и нативный TCP-протокол (быстрее, используется `clickhouse-client` и большинством драйверов). Выбор протокола — не деталь подключения, а решение, влияющее на производительность вставки и совместимость с инфраструктурой.One server, two independent protocols on different ports: HTTP (simple, universal, proxy-friendly) and the native TCP protocol (faster, used by clickhouse-client and most drivers). Protocol choice isn't a connection detail — it's a decision that affects insert performance and infrastructure compatibility.
Официальный CLI — интерактивная консоль поверх нативного протокола (порт `9000` по умолчанию), с автодополнением, подсветкой синтаксиса и прогресс-баром на долгих запросах (полезно на терабайтных сканах — видно, сколько строк/байт уже обработано, ещё до завершения запроса). Тот же бинарник работает и в неинтерактивном режиме — стандартный способ гонять запросы и миграции из скриптов и CI.The official CLI is an interactive console over the native protocol (port 9000 by default), with autocompletion, syntax highlighting, and a progress bar on long queries (useful on terabyte scans — you see how many rows/bytes have been processed before the query finishes). The same binary also runs non-interactively — the standard way to run queries and migrations from scripts and CI.
# интерактивно# interactive
clickhouse-client --host ch1 --user app
# неинтерактивно, из скрипта/CI# non-interactive, from a script/CI
clickhouse-client --host ch1 --query "SELECT count() FROM trades"
cat migration.sql | clickhouse-client --host ch1 --multiquery
Порт `8123` принимает обычные HTTP-запросы — запрос передаётся как тело POST или GET-параметр, ответ приходит в выбранном формате (`FORMAT JSON`, `CSV`, `TSV` и десятки других). Это самый универсальный способ достучаться до ClickHouse — работает из любого языка без специального драйвера, легко проксируется через nginx/балансировщик, укладывается в стандартный HTTP-мониторинг (коды ответа, задержки). Плата — накладные расходы на парсинг HTTP и обычно более медленная (де)сериализация по сравнению с нативным протоколом на высокочастотных мелких запросах.Port 8123 accepts plain HTTP requests — the query goes as a POST body or a GET parameter, the response comes back in the chosen format (FORMAT JSON, CSV, TSV, and dozens of others). It's the most universal way to reach ClickHouse — works from any language without a special driver, proxies easily through nginx/a load balancer, fits standard HTTP monitoring (response codes, latency). The cost is HTTP parsing overhead and usually slower (de)serialization compared to the native protocol on high-frequency small requests.
curl 'http://ch1:8123/?query=SELECT+symbol,+avg(price)+FROM+trades+GROUP+BY+symbol+FORMAT+JSON'
# вставка через HTTP — тело запроса это данные, не SQL# insert via HTTP — the request body is the data, not SQL
echo 'BTC,50000,0.1' | curl 'http://ch1:8123/?query=INSERT+INTO+trades+FORMAT+CSV' --data-binary @-
Нативный бинарный протокол (порт `9000`) — то, чем пользуется `clickhouse-client` и большинство официальных/community драйверов (`clickhouse-go`, `clickhouse-driver` для Python, JDBC-драйвер). Передаёт данные в колоночном формате, тем же, в каком они лежат на диске, — минимум преобразований на пути от диска к клиенту, поэтому нативный протокол ощутимо быстрее HTTP на больших объёмах данных или высокой частоте запросов. Выбор между HTTP и нативным протоколом на практике определяется одним вопросом: важна ли максимальная пропускная способность (нативный) или простота интеграции/проксирования (HTTP).The native binary protocol (port 9000) is what clickhouse-client and most official/community drivers use (clickhouse-go, Python's clickhouse-driver, the JDBC driver). It transmits data in the same columnar format it's stored in on disk — minimal transformation on the path from disk to client, so the native protocol is noticeably faster than HTTP at large data volumes or high query frequency. In practice the choice between HTTP and native comes down to one question: is maximum throughput the priority (native), or ease of integration/proxying (HTTP)?
Запрос на выборку миллионов строк через HTTP-интерфейс без потоковой обработки на клиенте формирует весь ответ в памяти сервера перед отправкой — на действительно больших выборках это может исчерпать память сервера. Потоковая передача (`send_progress_in_http_headers`, чтение ответа по частям на клиенте) или, лучше, переход на нативный протокол с курсорным чтением — правильное решение для экспорта больших объёмов данных.A query fetching millions of rows over the HTTP interface without client-side streaming builds the entire response in server memory before sending — on genuinely large result sets, this can exhaust server memory. Streaming (send_progress_in_http_headers, reading the response in chunks client-side) or, better, switching to the native protocol with cursor-based reads is the right approach for exporting large volumes of data.
Нативный протокол по умолчанию не шифрован (порт `9000` — plaintext, `9440` — TLS-вариант) — держать его открытым за пределами доверенной сети (VPC/приватная подсеть) означает передавать запросы и данные в открытом виде. Тот же принцип, что и для любой БД: нативный порт должен быть доступен только из приватной сети или через TLS, никогда напрямую из интернета.The native protocol is unencrypted by default (port 9000 is plaintext, 9440 is the TLS variant) — leaving it open outside a trusted network (a VPC/private subnet) means sending queries and data in the clear. Same principle as any DB: the native port should only be reachable from a private network or over TLS, never directly from the internet.