跳到主要内容
跳到主要内容

ClickHouse 运维:社区调试洞见

本指南是基于社区活动中总结出的经验与结论的一部分。想获取更多真实场景下的解决方案与洞见,可以按具体问题浏览 是否正为高昂的运维成本发愁?请查看成本优化社区洞见指南。

关键系统表

以下系统表是生产环境调试/排障的基础:

system.errors

显示 ClickHouse 实例中当前所有存在的错误。

SELECT name, value, changed 
FROM system.errors 
WHERE value > 0 
ORDER BY value DESC;

system.replicas

包含用于监控集群健康状况的复制延迟和状态信息。

SELECT database, table, replica_name, absolute_delay, queue_size, inserts_in_queue
FROM system.replicas 
WHERE absolute_delay > 60
ORDER BY absolute_delay DESC;

system.replication_queue

提供用于诊断复制相关问题的详细信息。

SELECT database, table, replica_name, position, type, create_time, last_exception
FROM system.replication_queue 
WHERE last_exception != ''
ORDER BY create_time DESC;

system.merges

显示当前的合并操作,并可用于识别已卡住的进程。

SELECT database, table, elapsed, progress, is_mutation, total_size_bytes_compressed
FROM system.merges 
ORDER BY elapsed DESC;

system.parts

对监控数据片数量和识别碎片化问题至关重要。

SELECT database, table, count() as part_count
FROM system.parts 
WHERE active = 1
GROUP BY database, table
ORDER BY count() DESC;

常见生产环境问题

磁盘空间问题

在复制架构中,磁盘空间耗尽会引发级联问题。当某个节点磁盘用尽时,其他节点会持续尝试与其同步,导致网络流量激增并出现难以理解的异常现象。有一位社区用户花了 4 小时排查,结果只是磁盘空间不足。请参考这个用于监控特定集群磁盘存储情况的查询

AWS 用户需要注意,默认通用型 EBS 卷的上限为 16TB。

too many parts 错误

小而频繁的插入会造成性能问题。社区实践表明,当插入速率超过每秒 10 次时,经常会触发 “too many parts” 错误,因为 ClickHouse 无法以足够快的速度合并这些 part。

解决方案:

  • 使用 30 秒或 200MB 阈值对数据进行批处理
  • 启用 async_insert 实现自动批处理
  • 使用 Buffer 表在服务端进行批处理
  • 配置 Kafka 以控制批大小

官方建议:每次插入至少 1,000 行,理想范围为 10,000 到 100,000 行。

无效时间戳问题

应用程序如果发送带有任意时间戳的数据,会导致分区问题。这可能生成包含不现实日期(如 1998 或 2050 年)的分区,从而引发意外的存储行为。

ALTER 操作风险

在多 TB 级表上执行大型 ALTER 操作会消耗大量资源,并有可能锁住数据库。某个社区案例中,将 14TB 数据中的 Integer 修改为 Float,结果锁住了整个数据库,只能通过备份重建。

监控开销巨大的变更操作(mutation):

SELECT database, table, mutation_id, command, parts_to_do, is_done
FROM system.mutations 
WHERE is_done = 0;

先在较小的数据集上验证模式变更。

内存与性能

外部聚合

为内存密集型操作启用外部聚合。虽然速度会更慢,但通过将数据写入磁盘来防止因内存不足而导致的崩溃。可以通过使用 max_bytes_before_external_group_by 来实现,这有助于在大型 GROUP BY 操作中避免内存不足崩溃。有关此设置的更多信息,请参见此处

SELECT 
    column1,
    column2,
    COUNT(*) as count,
    SUM(value) as total
FROM large_table
GROUP BY column1, column2
SETTINGS max_bytes_before_external_group_by = 1000000000; -- 1GB 阈值

异步插入详情

异步插入会在服务端自动对小批量插入进行批量聚合,以提升性能。可以配置在返回确认之前是否等待数据写入磁盘——立即返回速度更快,但持久性较差。较新版本支持去重,以处理批次中的重复数据。

相关文档

Distributed 表配置

默认情况下,Distributed 表使用单线程插入。启用 insert_distributed_sync 可进行并行处理,并将数据立即发送到各分片。

在使用 Distributed 表时,应监控临时数据的累积情况。

性能监控阈值

社区推荐的监控阈值:

  • 每个分区的 parts 数量:最好少于 100
  • 延迟插入:应保持为 0
  • 插入速率:建议限制在每秒约 1 次,以获得最佳性能

相关文档

快速参考

问题检测方式解决方案
磁盘空间检查 system.parts 总字节数监控使用情况,规划扩容
parts 过多统计每张表的 parts 数量批量写入,启用 async_insert
副本延迟检查 system.replicas 延迟监控网络,重启副本
异常数据校验分区日期实施时间戳校验
卡住的 mutations检查 system.mutations 状态先在小规模数据上测试

视频资料