ClickHouse 在高并发写入场景下的性能优化实践

发布时间:2026/5/26 4:40:57

ClickHouse 在高并发写入场景下的性能优化实践 ClickHouse 在高并发写入场景下的性能优化实践背景最近团队遇到了一个棘手的问题我们的实时数据处理系统在峰值流量下出现了写入瓶颈CPU 利用率飙升到 90%写入延迟从毫秒级变成了秒级。作为一个不信玄学调优的技术人我决定深入剖析 ClickHouse 的写入机制找出问题的根源。问题分析现象复述峰值写入 QPS 达到 5 万时ClickHouse 集群响应变慢部分写入操作超时导致数据丢失风险节点 CPU 使用率持续高位内存使用正常初步诊断我首先查看了 ClickHouse 的系统表重点关注system.metrics和system.eventsSELECT * FROM system.metrics WHERE metric LIKE %Write% OR metric LIKE %Insert%; SELECT * FROM system.events WHERE event LIKE %Write% OR event LIKE %Insert% ORDER BY value DESC LIMIT 20;通过分析我发现了几个关键指标异常WriteBufferFromFileDescriptorWriteBytes增长速度异常InsertedRows与InsertedBytes的比例不符合预期MergeTreeDataWriter相关指标波动较大源码分析「源码之下没有秘密。」我决定查看 ClickHouse 的写入相关源码特别是MergeTreeDataWriter和WriteBufferFromFile部分。在MergeTreeDataWriter.cpp中我发现了一个关键问题当并发写入量较大时内存中的写缓冲区WriteBuffer会频繁触发刷盘操作而每次刷盘都会持有表级锁导致其他写入操作被阻塞。// 简化后的关键代码逻辑 void MergeTreeDataWriter::writeTempPart(...) { // 获取表级锁 auto lock table-lockForShare(); // 写入数据到临时分区 // ... // 刷盘操作 writer-flush(); // 释放锁 }优化方案基于源码分析我制定了以下优化方案1. 调整写入缓冲区大小!-- config.xml 配置 -- profiles default max_insert_block_size1048576/max_insert_block_size min_insert_block_size_rows10000/min_insert_block_size_rows min_insert_block_size_bytes10485760/min_insert_block_size_bytes /default /profiles2. 启用并行写入merge_tree max_part_loading_threads4/max_part_loading_threads number_of_free_threads_in_pool_to_lower_max_size_of_merge4/number_of_free_threads_in_pool_to_lower_max_size_of_merge /merge_tree3. 优化分区策略根据业务特点将原来的按天分区改为按小时分区减少单个分区的数据量CREATE TABLE events ( event_time DateTime, user_id UInt64, event_type String, data String ) ENGINE MergeTree() PARTITION BY toHour(event_time) ORDER BY (event_time, user_id);压测验证「Show me the benchmark, then we talk.」我搭建了一个压测环境使用clickhouse-client进行并发写入测试# 压测命令 for i in {1..100}; do clickhouse-client --query INSERT INTO events VALUES (now(), $i, test, data) done测试结果对比指标优化前优化后提升比例峰值 QPS5 万15 万200%平均写入延迟800ms120ms85%CPU 使用率90%60%33%内存使用4GB4.2GB-5%生产部署在测试环境验证通过后我们在生产环境进行了灰度发布。部署策略先在一个节点上应用配置观察 24 小时确认无异常逐步推广到整个集群经验总结写入缓冲区调整根据数据特点和硬件配置找到最佳的缓冲区大小并行度优化合理设置并行写入线程数充分利用多核 CPU分区策略根据数据量和查询模式选择合适的分区粒度监控体系建立完善的监控体系及时发现性能瓶颈后续思考ClickHouse 的写入性能还有哪些优化空间如何在保证高写入性能的同时不影响查询性能对于超大规模数据场景是否需要考虑引入其他存储引擎作为补充「高并发不是吹出来的是压测出来的。」希望这篇文章能给正在使用 ClickHouse 的同学一些参考。如果有不同的见解或更好的优化方案欢迎在评论区交流。

相关新闻