ClickHouse C – 使用原生二进制协议与 ClickHouse 通信
摘要
ClickHouse 发布了 clickhouse-c:一个仅头文件的 C 语言客户端库,用于通过原生二进制协议(基于 TCP 的原生协议 / 原生格式数据块)与 ClickHouse 通信,可嵌入 PostgreSQL 扩展中使用。
暂无内容
查看缓存全文
缓存时间: 2026/10/12 00:44
ClickHouse/clickhouse-c 来源:https://github.com/ClickHouse/clickhouse-c # clickhouse-c 用于 ClickHouse (https://clickhouse.com/) Native 线格式的纯头文件 C 客户端——通过 TCP 使用 Native Protocol (https://clickhouse.com/docs/reference/interfaces/specs/NativeProtocol) 传输 Native Format (https://clickhouse.com/docs/reference/interfaces/specs/NativeFormat) 数据块。一个核心头文件,加上用于 TCP、压缩、编解码器和 I/O 后端的可选扩展头文件。设计用于嵌入 PostgreSQL 扩展(palloc 内存分配区、longjmp),但不包含任何 PG 专用代码。仅包含 clickhouse.h 即可获得基于调用方提供的 chc_io 的纯数据块解码器,可通过管道读取 clickhouse-local 的 FORMAT Native 输出,无需 TCP、压缩,也无需 libc 以外的链接时依赖。 ## 快速入门 在不使用 TCP 或压缩的情况下解码 clickhouse local 查询。 c /* demo.c — cc -std=c11 -O2 -I. demo.c -o demo */ #define CHC_PROVIDE_STDLIB_ALLOC #define CHC_IMPLEMENTATION #include "clickhouse.h" #include "clickhouse-posix-io.h" #include #include int main(void) { /* 启动 `clickhouse local --format Native -q "..."`,并通过管道读取其标准输出;完整的连接代码见 examples/minimal_decode.c。 */ int fd = /* 来自子进程的管道读取端 */; chc_alloc al = chc_alloc_stdlib(); chc_posix_io state; chc_io io; chc_posix_io_init(&state, &io, fd, NULL, NULL); chc_block_opts opts = {}; /* clickhouse-local:无 BlockInfo,无自定义序列化 */ /* 整个流使用一个持久的读取器:chc_block_read 会将读取到的数据块边界之后的字节保留在缓冲区中,供下一个数据块使用。 */ chc_err ierr = {}; chc_in in; if (chc_in_init(&in, &io, &al, opts.read_buffer_bytes, &ierr) != CHC_OK) { fprintf(stderr, "初始化:%s\n", ierr.msg); return 1; } for (;;) { chc_block *block = NULL; chc_err err = {}; if (chc_block_read(&in, &al, &opts, &block, &err) != CHC_OK) { fprintf(stderr, "解码:%s\n", err.msg); return 1; } if (!block) break; for (size_t r = 0; r < chc_block_n_rows(block); r++) for (size_t c = 0; c < chc_block_n_columns(block); c++) /* 根据 chc_column_layout(chc_block_column(block, c)) 分派处理 */; chc_block_destroy(block, &al); } chc_in_free(&in); } 可运行的端到端版本:examples/minimal_decode.c。 必需的服务器设置(TCP 使用 Query 数据包,clickhouse local 使用 -- 参数): output_format_native_encode_types_in_binary_format = 0 未设置此项时,服务器会输出二进制类型标记,chc_block_read 会返回 CHC_ERR_TYPE。 ## 集成 clickhouse-c 以一组平铺的头文件分发:每个头文件同时包含声明和实现,并由哨兵宏保护。每个使用方必须且只能在一个翻译单元中定义实现宏并包含头文件;其余翻译单元只包含声明。 c /* consumer/src/clickhouse.c — 将库链接进来的唯一翻译单元 */ #define CHC_IMPLEMENTATION #include "clickhouse.h" #include "clickhouse-posix-io.h" /* ...在此包含 clickhouse-client.h、clickhouse-compression.h,以使用所需功能。 */ 其他翻译单元仅包含公共声明: c #include "clickhouse.h" #include "clickhouse-posix-io.h" /* 此处不定义 CHC_IMPLEMENTATION */ 在包含 clickhouse.h 之前添加 #define CHC_PROVIDE_STDLIB_ALLOC,即可使用基于标准库 malloc/realloc/free 的辅助实现。关于在实际 PostgreSQL 扩展中接入 palloc/repalloc/pfree,请参阅 pg_clickhouse (https://github.com/ClickHouse/pg_clickhouse) 或 pg_stat_ch (https://github.com/ClickHouse/pg_stat_ch)。 ## 头文件 | 头文件 | 用途 | 链接选项 | |—|—|—| | clickhouse.h | 核心:类型、错误、chc_alloc、chc_io、类型名称解析器、数据块读取器和写入器 | — | | clickhouse-client.h | TCP 数据包循环:Hello / Query / Data / EOS / Exception / Progress / Pong | — | | clickhouse-async.h | 无 I/O 客户端:由调用方提交字节驱动的相同数据包循环,不使用套接字 | — | | clickhouse-compression.h | 压缩帧布局、CityHash128、chc_codec 分派、LZ4 和 ZSTD 适配器(使用 CHC_NO_LZ4 / CHC_NO_ZSTD 禁用) | -llz4 -lzstd | | clickhouse-posix-io.h | 基于阻塞式 read(2)/write(2) 的 chc_io,包含 EINTR 重试循环和取消钩子 | — | | clickhouse-openssl.h | 基于 SSL_read/SSL_write 的 chc_io | -lssl -lcrypto | 各扩展头文件相互独立;按构建需求选择即可。clickhouse-client.h 支持 ClickHouse 23.3 及更新版本。各头文件的参考文档位于 doc/;内联声明和注释位于头文件本身。完整示例位于 examples/。 ## 测试 使用 test.sh 运行测试: sh ./test.sh 如果错误提示缺少头文件或出现链接器错误,请使用 CFLAGS 和 LDFLAGS 指向相应目录,例如使用 [Homebrew] 时: sh CFLAGS=-I/opt/homebrew/include LDFLAGS=-L/opt/homebrew/lib ./test.sh 该脚本运行 test 中的各项测试。要运行指定测试,请将其基本名称(不含末尾的 .c)作为参数传入: sh ./test.sh test_cancel test_block_decode test_client_tcp 会从 PATH 启动 clickhouse server。设置 CHC_TEST_PORT 可改为针对正在运行的服务器进行测试,例如 Docker 中的旧版本: sh docker run -d -p 127.0.0.1:19233:9000 clickhouse/clickhouse-server:23.3.22.3 CHC_TEST_PORT=19233 ./test.sh client_tcp tools/capture.py 可作为此类服务器的代理,录制用于回放的测试数据,如 test/ch23_3_sparse.bin。 ## 非目标 * HTTP 协议——直接封装 libcurl。 * DNS、端点轮询、连接池、重试/退避。 * SSL/TLS 上下文生命周期。使用 chc_io 回调;由调用方驱动 OpenSSL。 * 多线程。每个 chc_client 在设计上均为单线程。 * 库内部的异步 I/O。阻塞式客户端同步调用 chc_io.read(回调内部可以使用任意机制——epoll、io_uring、WaitLatchOrSocket)。关于完全不执行 I/O、由调用方在事件循环中提交字节来驱动的无 I/O 客户端,请参阅 clickhouse-async.h。 * v1 中的 Variant / Dynamic / JSON / AggregateFunction 解码。上游线格式在 25.x / 26.x 中仍在变化。 [Homebrew]: https://brew.sh “macOS(或 Linux)缺失的包管理器”
相似文章
@clickhouse/rowbinary: 当你的库同时也是一个解析器编译器
ClickHouse 发布了 @clickhouse/rowbinary,一个用于读写 RowBinary 格式的 Node.js 库,它还包括一个技能文件,使编码代理能够生成针对查询的高性能解析器,速度比通用解析器快1.5到3.4倍。
Helicone 允许用户直接向共享 ClickHouse 编写 SQL
Helicone 实现了一项名为 HQL 的功能,允许客户针对共享的 ClickHouse 数据库编写原始 SQL 查询。他们利用 ClickHouse 的行策略和自定义设置来实施多租户隔离,确保每个组织只能看到自己的数据。
完整的 ClickHouse OLAP 引擎,编译为 WebAssembly
chDB 是一个完整的 ClickHouse OLAP 引擎,编译为 WebAssembly,可通过 wasm.chdb.io 的 SQL 终端直接在浏览器中执行 SQL 查询。
ClickHouse 正在赢得可观测性之战
本文认为,ClickHouse 凭借其处理高吞吐量、时序日志的性能优势,解决了长期以来日志管理的痛点,从而成为可观测性领域的主流数据库。
@XAMTO_AI: MySQL、PostgreSQL、Oracle、SQL Server、ClickHouse、MongoDB、Redis,三十多种数据库一个客户端全连上了。 还能用自然语言生成SQL、解释SQL、帮你优化SQL,模型用自己的就行。 Chat…
Chat2DB 是一款支持三十多种数据库的客户端,能用自然语言生成、解释和优化SQL,支持全平台并附带开源CLI。