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

