ClickHouse 配置:我是如何搭建生产环境且不踩坑的
一个拼写错误的故事:300 GB 日志与崩溃的服务器
默认情况下,ClickHouse 将日志写入 /var/log/clickhouse-server/ 且从不轮转。上线两周后,我们发现日志文件膨胀到 300 GB,占满了整个根分区。服务器崩溃,分析师无法执行 SELECT,生产环境宕机。
ClickHouse 文档庞大,但在生产环境中你真正需要修改的参数大约只有 20 个。以下是我 5 年运维 1 到 12 节点集群的检查清单。
1. config.xml:生产配置的骨架
主配置文件位于 /etc/clickhouse-server/config.xml。以下是我在每个项目中都会修改的部分:
<clickhouse>
<!-- 日志——添加轮转以避免重蹈覆辙 -->
<logger>
<level>information</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>10</count>
<!-- 这能节省磁盘。10 个文件,每个 1 GB——基于大小的轮转 -->
</logger>
<!-- 端口——标准配置,但我在生产环境中会修改 -->
<tcp_port>9000</tcp_port> <!-- 原生客户端 -->
<http_port>8123</http_port> <!-- HTTP API -->
<interserver_http_port>9009</interserver_http_port> <!-- 复制 -->
<!-- 监听接口——生产环境中,不要在没有防火墙的情况下设置 0.0.0.0 -->
<listen_host>0.0.0.0</listen_host> <!-- 所有接口——小心 -->
<!-- <listen_host>::</listen_host> IPv6 -->
为什么我建议不要盲目使用 0.0.0.0: 在生产环境中使用公网 IP,你的 ClickHouse 会成为端口扫描的目标。最好使用 VPN 或防火墙。
2. 数据路径:ClickHouse 存储一切的地方
<path>/var/lib/clickhouse/</path> <!-- 主数据 -->
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
<user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
<format_schema_path>/var/lib/clickhouse/format_schemas/</format_schema_path>
我踩过的坑: 系统的 /tmp 挂载在内存中(tmpfs),只有 2 GB。ClickHouse 尝试将大型 GROUP BY 查询的临时文件写入那里,然后崩溃并报错。我将 tmp_path 移到了一个 50 GB 的磁盘上:
<tmp_path>/data/clickhouse_tmp/</tmp_path>
3. MergeTree 设置:防止灾难
我在所有生产服务器上设置以下参数:
<merge_tree>
<!-- 一个部分在累积到 10 GB 之前不会合并——减少后台负载 -->
<min_bytes_for_wide_part>10000000000</min_bytes_for_wide_part>
<!-- 合并的最大部分大小(100 GB) -->
<max_bytes_to_merge_at_max_space_in_pool>107374182400</max_bytes_to_merge_at_max_space_in_pool>
<!-- 如果部分超过 300 个,新的 INSERT 将被拒绝 -->
<parts_to_throw_insert>300</parts_to_throw_insert>
<!-- 部分数达到 200 时发出警告 -->
<parts_to_delay_insert>200</parts_to_delay_insert>
<!-- 分区中部分的最大数量 -->
<max_parts_in_total>10000</max_parts_in_total>
</merge_tree>
为什么 parts_to_throw_insert = 300: 如果你有 300 个以上的部分,SELECT 会变慢,INSERT 只会让情况更糟。不如拒绝插入并调查原因。
4. users.xml:用户、配置文件和配额
文件 /etc/clickhouse-server/users.xml 是访问控制。我创建三个用户:
<clickhouse>
<!-- 1. 分析师用户(只读) -->
<analyst>
<password>analyst_secure_password</password>
<networks>
<ip>10.0.0.0/8</ip> <!-- 仅内网 -->
</networks>
<profile>readonly_profile</profile>
<quota>analyst_quota</quota>
</analyst>
<!-- 2. 应用程序(资源受限) -->
<app_user>
<password>${CLICKHOUSE_APP_PASSWORD}</password> <!-- 从环境变量获取 -->
<networks>
<ip>::/0</ip> <!-- 小心,最好使用特定子网 -->
</networks>
<profile>app_profile</profile>
</app_user>
<!-- 3. 管理员(完全访问) -->
<admin>
<password>admin_strong_password</password>
<networks>
<host>localhost</host>
<host>10.0.0.50</host> <!-- 仅堡垒机 -->
</networks>
<profile>admin_profile</profile>
</admin>
</clickhouse>
重要细节: 默认用户的密码默认为空。这是我安装后做的第一件事。
5. 设置配置文件:防止疯狂查询
配置文件是一组约束,可以保护集群免受 SELECT * FROM huge_table CROSS JOIN 的影响。
<profiles>
<!-- 分析师:可以运行重查询但有上限 -->
<readonly_profile>
<readonly>1</readonly> <!-- 仅 SELECT -->
<max_memory_usage>10000000000</max_memory_usage> <!-- 10 GB -->
<max_execution_time>300</max_execution_time> <!-- 5 分钟 -->
<max_rows_to_read>50000000000</max_rows_to_read> <!-- 500 亿行 -->
<max_bytes_to_read>107374182400</max_bytes_to_read> <!-- 100 GB -->
<prefer_global_in_and_join>1</prefer_global_in_and_join>
</readonly_profile>
<!-- 应用程序:快速查询,小限制 -->
<app_profile>
<readonly>0</readonly>
<max_memory_usage>1000000000</max_memory_usage> <!-- 1 GB -->
<max_execution_time>10</max_execution_time> <!-- 10 秒 -->
<max_rows_to_read>100000000</max_rows_to_read> <!-- 1 亿 -->
<timeout_before_checking_execution_speed>0</timeout_before_checking_execution_speed>
</app_profile>
<!-- 管理员:几乎无限制(但小心) -->
<admin_profile>
<readonly>0</readonly>
<max_memory_usage>0</max_memory_usage> <!-- 无限制 -->
<max_execution_time>0</max_execution_time>
</admin_profile>
</profiles>
配额——防止一个分析师拖垮所有人:
<quotas>
<analyst_quota>
<interval>
<duration>3600</duration> <!-- 每小时 -->
<queries>100</queries> <!-- 不超过 100 个查询 -->
<errors>0</errors> <!-- 无错误 -->
<result_rows>100000000</result_rows> <!-- 1 亿结果行 -->
<read_rows>10000000000</read_rows> <!-- 100 亿读取行 -->
</interval>
</analyst_quota>
</quotas>
6. 默认压缩设置
ClickHouse 使用 LZ4(快速)或 ZSTD(更强)压缩数据。我根据数据类型选择:
<compression>
<!-- 新数据使用 LZ4(速度) -->
<case>
<last_level>1</last_level> <!-- 压缩级别 -->
<method>LZ4</method>
</case>
<!-- 超过 30 天的分区使用 ZSTD(节省空间) -->
<case>
<min_part_size>10737418240</min_part_size> <!-- 10 GB -->
<method>ZSTD</method>
<level>3</level>
</case>
</compression>
我在生产环境中的选择: 所有数据使用 LZ4。ZSTD 节省 20-30% 空间,但查询速度降低最多 10%。
7. TLS/SSL——如果你不在隔离网络中
<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>
<openSSL>
<server>
<certificateFile>/etc/clickhouse-server/ssl/server.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-server/ssl/server.key</privateKeyFile>
<verificationMode>none</verificationMode>
<caConfig>/etc/clickhouse-server/ssl/CA.pem</caConfig>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3,tlsv1,tlsv1_1</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
</openSSL>
我踩过的坑: 没有验证的自签名证书只在可信网络内安全。对于外部访问,使用 Let's Encrypt 或付费证书。
8. config.d/——无痛覆盖
永远不要直接编辑 config.xml。将所有更改放在 /etc/clickhouse-server/config.d/ 中。
文件 config.d/memory.xml:
<clickhouse>
<max_server_memory_usage>0.75</max_server_memory_usage> <!-- 总内存的 75% -->
<max_concurrent_queries>100</max_concurrent_queries>
</clickhouse>
文件 config.d/networks.xml:
<clickhouse>
<listen_host>0.0.0.0</listen_host>
<max_connections>4096</max_connections>
</clickhouse>
优点: 更新 ClickHouse 时,你的 config.xml 不会被覆盖,覆盖文件保持不变。我在从 22.x 升级到 23.x 时丢失了配置,才学到这一点。
9. 博彩平台的安全检查清单
在向外部世界开放 ClickHouse 访问之前,我检查以下内容:
✅ 更改默认用户密码
clickhouse-client --password
ALTER USER default IDENTIFIED BY 'new_strong_password';
✅ 删除或限制默认用户
<!-- 在 users.xml 中注释掉默认部分 -->
<!-- <default>
<password></password>
</default> -->
✅ 关闭外部访问端口(UFW)
sudo ufw default deny incoming
sudo ufw allow from 10.0.0.0/8 to any port 9000 proto tcp # 仅内网
sudo ufw allow from 10.0.0.0/8 to any port 8123 proto tcp
sudo ufw allow ssh
✅ 启用主机级防火墙
sudo iptables -A INPUT -p tcp --dport 9000 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 9000 -j DROP
✅ 设置 max_memory_usage 防止单个查询杀死服务器
<max_memory_usage>10000000000</max_memory_usage> <!-- 10 GB -->
✅ 禁用实验性功能(如果不需要)
<allow_experimental_geo_types>0</allow_experimental_geo_types>
<allow_experimental_window_functions>1</allow_experimental_window_functions> <!-- 23.8+ -->
✅ 启用 query_log 和 slow_log 用于监控
<query_log>
<database>system</database>
<table>query_log</table>
<partition_by>toYYYYMM(event_date)</partition_by>
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
</query_log>
<query_thread_log>
<database>system</database>
<table>query_thread_log</table>
</query_thread_log>
✅ 按 IP 限制访问(白名单)
<analyst>
<networks>
<ip>10.0.0.100</ip> <!-- 仅特定分析师 IP -->
<ip>10.0.0.101</ip>
<ip>192.168.1.0/24</ip>
</networks>
</analyst>
下一步
现在你的 ClickHouse 已经配置好,可以投入战斗了。下一篇文章是关于生产环境中的监控和备份。
← 上一篇: ClickHouse聚合函数:我是如何不再害怕uniqHLL12和quantileTDigest的 → 下一篇: ReplacingMergeTree:如何在 ClickHouse 中轻松去重
— Editorial Team
暂无评论。