ClickHouse在高并發(fā)寫入場景下的性能優(yōu)化實踐(CPU利用率飆升)
背景
最近團隊遇到了一個棘手的問題:我們的實時數(shù)據(jù)處理系統(tǒng)在峰值流量下出現(xiàn)了寫入瓶頸,CPU 利用率飆升到 90%+,寫入延遲從毫秒級變成了秒級。作為一個不信"玄學調優(yōu)"的技術人,我決定深入剖析 ClickHouse 的寫入機制,找出問題的根源。
問題分析
現(xiàn)象復述
- 峰值寫入 QPS 達到 5 萬時,ClickHouse 集群響應變慢
- 部分寫入操作超時,導致數(shù)據(jù)丟失風險
- 節(jié)點 CPU 使用率持續(xù)高位,內存使用正常
初步診斷
我首先查看了 ClickHouse 的系統(tǒng)表,重點關注 system.metrics 和 system.events:
SELECT * 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;
通過分析,我發(fā)現(xiàn)了幾個關鍵指標異常:
WriteBufferFromFileDescriptorWriteBytes增長速度異常InsertedRows與InsertedBytes的比例不符合預期MergeTreeDataWriter相關指標波動較大
源碼分析
「源碼之下,沒有秘密?!刮覜Q定查看 ClickHouse 的寫入相關源碼,特別是 MergeTreeDataWriter 和 WriteBufferFromFile 部分。
在 MergeTreeDataWriter.cpp 中,我發(fā)現(xiàn)了一個關鍵問題:當并發(fā)寫入量較大時,內存中的寫緩沖區(qū)(WriteBuffer)會頻繁觸發(fā)刷盤操作,而每次刷盤都會持有表級鎖,導致其他寫入操作被阻塞。
// 簡化后的關鍵代碼邏輯
void MergeTreeDataWriter::writeTempPart(...) {
// 獲取表級鎖
auto lock = table->lockForShare();
// 寫入數(shù)據(jù)到臨時分區(qū)
// ...
// 刷盤操作
writer->flush();
// 釋放鎖
}
優(yōu)化方案
基于源碼分析,我制定了以下優(yōu)化方案:
1. 調整寫入緩沖區(qū)大小
<!-- config.xml 配置 -->
<profiles>
<default>
<max_insert_block_size>1048576</max_insert_block_size>
<min_insert_block_size_rows>10000</min_insert_block_size_rows>
<min_insert_block_size_bytes>10485760</min_insert_block_size_bytes>
</default>
</profiles>
2. 啟用并行寫入
<merge_tree>
<max_part_loading_threads>4</max_part_loading_threads>
<number_of_free_threads_in_pool_to_lower_max_size_of_merge>4</number_of_free_threads_in_pool_to_lower_max_size_of_merge>
</merge_tree>
3. 優(yōu)化分區(qū)策略
根據(jù)業(yè)務特點,將原來的按天分區(qū)改為按小時分區(qū),減少單個分區(qū)的數(shù)據(jù)量:
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.」我搭建了一個壓測環(huán)境,使用 clickhouse-client 進行并發(fā)寫入測試:
# 壓測命令
for i in {1..100}; do
clickhouse-client --query "INSERT INTO events VALUES (now(), $i, 'test', 'data')" &
done
測試結果對比
| 指標 | 優(yōu)化前 | 優(yōu)化后 | 提升比例 |
|---|---|---|---|
| 峰值 QPS | 5 萬 | 15 萬 | 200% |
| 平均寫入延遲 | 800ms | 120ms | 85% |
| CPU 使用率 | 90%+ | 60% | 33% |
| 內存使用 | 4GB | 4.2GB | -5% |
生產部署
在測試環(huán)境驗證通過后,我們在生產環(huán)境進行了灰度發(fā)布。部署策略:
- 先在一個節(jié)點上應用配置
- 觀察 24 小時,確認無異常
- 逐步推廣到整個集群
經驗總結
- 寫入緩沖區(qū)調整:根據(jù)數(shù)據(jù)特點和硬件配置,找到最佳的緩沖區(qū)大小
- 并行度優(yōu)化:合理設置并行寫入線程數(shù),充分利用多核 CPU
- 分區(qū)策略:根據(jù)數(shù)據(jù)量和查詢模式,選擇合適的分區(qū)粒度
- 監(jiān)控體系:建立完善的監(jiān)控體系,及時發(fā)現(xiàn)性能瓶頸
到此這篇關于ClickHouse在高并發(fā)寫入場景下的性能優(yōu)化實踐(CPU利用率飆升)的文章就介紹到這了,更多相關ClickHouse高并發(fā)性能優(yōu)化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- ClickHouse數(shù)據(jù)庫的監(jiān)控與運維:監(jiān)控指標、監(jiān)控工具、運維策略、故障處理
- clickhouse遠程連接以及用戶名密碼設置方式
- 在docker中搭建部署clickhouse過程
- clickhouse數(shù)據(jù)庫刪除數(shù)據(jù)的五種方式
- clickhouse中Nullable與非空字段的建表與類型互轉方式
- clickhouse復雜時間格式的轉換方式
- 關于clickhouse幾種create table的情況
- clickhouse分布式表的操作示例詳解
- clickhouse系統(tǒng)表日志清理方式詳解
- 數(shù)據(jù)分析數(shù)據(jù)庫ClickHouse在大數(shù)據(jù)領域應用實踐
- 以示例講解Clickhouse Docker集群部署以及配置
相關文章
Hadoop2.X/YARN環(huán)境搭建--CentOS7.0 JDK配置
在Centos中,進行配置jdk的環(huán)境,這個還是折騰了我聽挺久的。特別是在一次配置中,導致后來我的root用戶無法登錄,并且用其他普通用戶登錄,使用su - root切換到root用戶,都無法使用ls這一些普通的命令。由于沒有權限,各種更改,都沒轍。各種麻煩啊~2014-08-08
Navicat Premium15安裝及破解教程詳解親測有效(附破解失敗解決方案)
這篇文章主要介紹了Navicat Premium15安裝及破解教程詳解親測有效,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
WordPress導入數(shù)據(jù)庫出現(xiàn)”Unknown collation: ‘utf8mb4_unicode_ci”錯誤的解
這篇文章主要介紹了WordPress導入數(shù)據(jù)庫出現(xiàn)”Unknown collation: ‘utf8mb4_unicode_ci”錯誤的解決辦法的相關資料,需要的朋友可以參考下2015-10-10
Navicat運行sql文件導入數(shù)據(jù)不全或導入失敗的解決方案
最近導出數(shù)據(jù)庫到另一個服務器,遇到這個問題,下面這篇文章主要給大家介紹了關于Navicat運行sql文件導入數(shù)據(jù)不全或導入失敗的解決方案,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-03-03

