You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ClickHouse服务无法启动,目标表目录文件过多问题咨询

ClickHouse启动卡顿与海量数据目录问题排查

问题背景

我在独立部署的ClickHouse-Server实例上遇到异常问题。服务器此前运行正常,配置基本默认,仅将data和tmp目录修改至独立磁盘:

cat /etc/clickhouse-server/config.d/my_config.xml
<?xml version="1.0"?>
<yandex>
    <path>/data/clickhouse/</path>
    <tmp_path>/data/clickhouse/tmp/</tmp_path>
</yandex>

今日服务器出现连接拒绝错误,重启后服务无法完全启动,日志显示加载数据部分时卡在57%:

2018.05.28 13:15:44.248373 [ 2 ] <Information> DatabaseOrdinary (default): 42.86%
2018.05.28 13:15:44.259860 [ 2 ] <Debug> default.event_4648 (Data): Loading data parts
2018.05.28 13:16:02.531851 [ 2 ] <Debug> default.event_4648 (Data): Loaded data parts (2168 items)
2018.05.28 13:16:02.532130 [ 2 ] <Information> DatabaseOrdinary (default): 57.14%
2018.05.28 13:16:02.534622 [ 2 ] <Debug> default.event_5156 (Data): Loading data parts
2018.05.28 13:34:01.731053 [ 3 ] <Information> Application: Received termination signal (Terminated)

因启动耗时过长我终止了进程。默认日志级别为trace,但未显示异常原因。经排查,/data/clickhouse/data/default/event_5156目录下存在626023个子目录,ls命令无法正常执行,需用find统计:

# time find . -maxdepth 1 | wc -l
626023
real    5m0.302s
user    0m3.114s
sys     0m24.848s

咨询问题

  1. 默认配置下ClickHouse-Server为何生成如此多的文件和目录?
  2. 如何在无数据损失的前提下,在合理时间内启动服务?

问题解答

1. 为何生成大量数据目录?

在默认配置下,ClickHouse绝大多数表用的是MergeTree引擎,数据会被拆分成多个"数据部分"(data parts)存储,每个部分对应一个独立目录。出现几十万级别的目录,核心原因是小批量写入+合并不及时:

  • 高频小写入堆积:如果你的event_5156表是持续接收小批量插入(比如每秒多次仅几条数据的insert),每次写入都会生成一个极小的数据部分目录,时间一久就会堆积成海量数量。
  • 合并策略未适配:默认的MergeTree合并规则有触发阈值(比如最小合并行数、数据大小),如果小数据部分始终达不到阈值,合并线程就不会主动合并这些零散部分。
  • 合并资源受限:默认background_pool_size(合并线程池大小)是16,如果服务器负载高,合并任务会被延迟,进一步加剧小数据部分的堆积。

简单说就是:每次小插入都生成一个目录,而ClickHouse没来得及把这些小目录合并成大的,时间长了就堆出几十万级别的数量。

2. 无数据损失前提下快速启动服务的方案

核心思路是先让服务启动,再批量合并小数据部分,最后优化长期配置避免复发。

步骤1:临时调整配置,快速启动服务

在/etc/clickhouse-server/config.d/下新增临时配置文件(比如temp_fix.xml),跳过部分严格检查并增强合并能力:

<?xml version="1.0"?>
<yandex>
    <!-- 启动时跳过不正确数据部分的检查(后续手动校验) -->
    <skip_check_for_incorrect_parts>1</skip_check_for_incorrect_parts>
    <!-- 临时增大合并线程池,加快启动后的合并速度 -->
    <background_pool_size>64</background_pool_size>
    <!-- 降低数据加载优先级,避免阻塞启动流程 -->
    <load_balancing>random</load_balancing>
</yandex>

修改后重启ClickHouse,此时启动速度会大幅提升——因为跳过了部分耗时检查,且合并线程更多,启动后会自动开始合并小数据部分。

步骤2:启动后手动合并小数据部分

服务正常启动后,在业务低峰期对event_5156表执行强制合并:

-- 强制合并所有小数据部分,设置足够大的合并字节阈值(比如100G)
OPTIMIZE TABLE default.event_5156 FINAL SETTINGS max_bytes_to_merge = 107374182400;

这个命令会运行一段时间(具体时长取决于数据量和磁盘IO),期间服务器CPU和IO负载会升高,别中途终止,否则可能导致数据损坏。执行完成后,数据部分数量会骤降,后续启动速度就会恢复正常。

步骤3:优化长期配置,避免再次堆积

为了防止以后再出现这种情况,需要调整写入和合并策略:

  • 改用批量写入:把高频小插入改成批量写入(比如每次插入1000条以上),减少小数据部分的生成频率。
  • 调整表的合并参数:修改MergeTree表的合并阈值,让零散数据更容易被合并:
    ALTER TABLE default.event_5156 MODIFY SETTINGS 
        merge_min_rows_to_merge = 100000, -- 降低合并触发的最小行数
        merge_max_block_size = 1048576, -- 增大合并后的块大小
        merge_max_rows_to_merge = 10000000; -- 增大单次合并的最大行数
    
  • 配置定时合并任务:在业务低峰期(比如凌晨)定时执行OPTIMIZE TABLE命令,提前合并小数据部分。
  • 开启TTL自动清理:如果数据有有效期,设置TTL自动清理过期数据,减少整体数据量。

内容的提问来源于stack exchange,提问作者user9859810

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:44:40