壓測平臺 - 記錄一次百億級資料查詢最佳化
引言
為了支撐數十萬 tps 的穩定性壓測,,我們的壓測平臺對壓測資料查詢進行了最佳化,以提高整體測試效率和響應能力。這些最佳化措施確保平臺能夠在大流量場景下高效穩定地執行,從而為產品的效能和穩定性提供更有力的保障。
16w 左右 tps 的 7*24 小時壓測
問題分析
1.壓測資料無法載入
在壓測平臺中,InfluxDB 被用於儲存和查詢壓測資料。然而,由於當時的 InfluxDB 資料庫採用的是單體架構,未進行任何分片或分散式部署。隨著系統中的資料量逐步增大,資料庫逐漸暴露出效能瓶頸,尤其是在處理大規模的壓測資料和歷史資料載入時。
壓測資料無法載入的情況
2.歷史資料載入緩慢
在訪問歷史資料時,由於資料量龐大,InfluxDB 的查詢效率下降明顯。載入歷史資料所需的時間變得過長,使用者體驗極差,查詢往往需要等待數秒甚至數分鐘才能完成,嚴重影響了系統的可用性和使用者滿意度。
3.資源利用率過高
單體架構的 InfluxDB 承擔了所有的讀寫操作,導致日常查詢和寫入的負載極高,難以有效分擔壓力。資料庫伺服器的 CPU 使用率常年保持在 75% 以上,系統壓力大時甚至接近滿負荷,導致 CPU 無法為查詢提供充足的資源支援。此外,資料庫的記憶體經常性地被佔滿,進一步影響了資料查詢的效能。
切換社群版 InfluxDB 的叢集版後遇到的新問題
為了緩解單體架構的效能瓶頸,我們嘗試切換到 InfluxDB 的叢集版本,以便在分散式架構下處理更大的資料量。初期切換後,系統的負載確實有所緩解,一些效能問題得到了改善。然而,在執行約半個月後,新的問題開始顯現:
高 IO 讀操作
在沒有任何查詢操作的情況下,系統的 IO 讀負載持續偏高。經過詳細排查,發現這種高 IO 讀並非由使用者查詢引起,而是在資料寫入時觸發的。這樣的現象導致了系統儲存裝置的高頻讀操作,增加了硬體的負載,並降低了整體系統的穩定性。
資料壓縮導致的 IO 讀壓力
經過分析和閱讀 InfluxDB 的程式碼,發現問題的根源在於 InfluxDB 在進行資料寫入時,觸發了自動的資料壓縮機制。這個壓縮機制在檢測到記憶體索引達到壓縮閾值時,會執行一次資料壓縮操作。資料壓縮的過程需要遍歷索引,這種操作會頻繁地進行大量磁碟 IO 讀取,加重了系統的讀負載。
pprof 分析
influxdb 出問題的程式碼塊
社群支援有限
由於 InfluxDB 的社群版叢集是由社群維護,在發現高 IO 讀負載問題後,我們嘗試向社群尋求支援。然而,由於社群支援有限,未能找到有效的解決方案,問題持續影響系統效能,並可能導致資料載入變慢或讀寫操作卡頓。
決策與解決方案
在社群支援無果的情況下,為了保證系統的穩定性和高效性,我們最終決定 切換底層儲存資料庫,選擇一個能夠更好處理海量資料寫入和壓縮任務的資料庫方案。這個決策的目的是找到一種能夠提供穩定、高效的儲存和查詢功能的底層資料庫,從而支援系統長期的高併發寫入和查詢需求,避免因單點儲存效能限制帶來的瓶頸問題。
新部署架構設計
最佳化前架構梳理
最佳化前的系統架構如下:壓測代理(agent)將壓測資料寫入 Kafka,資料中心從 Kafka 中獲取資料並按每秒進行聚合處理,隨後將結果寫入 InfluxDB。我們利用 InfluxDB 的持續查詢功能,每分鐘將詳細資料轉存至 1 分鐘間隔的聚合資料表,從而將資料壓縮至原始量的 50% 左右。
雖然該架構在設計上無明顯缺陷,但由於 InfluxDB 的開源版本僅支援單機部署,無法進行分散式擴充套件,因此在短時間內出現大批次資料寫入和查詢請求時會遇到效能瓶頸。為確保系統能夠支撐 15-17 萬 TPS 的壓測需求,我們決定更換底層的儲存資料庫,以支援更高的併發處理能力和更穩定的效能表現。
最佳化後核心部署架構
新的部署架構將原儲存於 InfluxDB 的資料遷移至 ClickHouse 資料庫,以充分利用 ClickHouse 多節點計算的優勢。壓測資料通常按列聚合計算,而 ClickHouse 作為列式資料庫非常適合這一需求。
由於 ClickHouse 沒有類似 InfluxDB 的持續查詢功能,我們開發了一個自定義的 watch 服務,用於每 30 秒自動聚合並轉存原始資料至新的 30 秒維度的表中。考慮到資料隨著時間的推移查詢頻率逐漸降低,我們計劃將超過 30 天的資料轉存為冷資料至磁碟,以降低頻繁讀寫對磁碟的壓力。
Grafana 實時讀取 30 秒維度的分散式表,以近實時方式展示壓測資料,此時資料大約有 1 分鐘延遲,但在效能測試中這一延遲可忽略不計。透過這種架構最佳化,ClickHouse 可以高效地執行資料聚合計算,並實現靈活的歷史資料管理,顯著提升了系統的效能和可擴充套件性。
watch 服務架構
watch 服務啟動時,會從 Redis 中讀取一個 startTime
作為初始查詢時間,並將當前時間 now
作為 endTime
,在 ClickHouse 中執行相應的查詢和聚合操作。
在查詢和寫入操作完成後,watch 服務將 now
更新到 Redis 中的 startTime
,實現查詢時間視窗的動態滾動更新。這種設計確保 watch 服務始終在正確的時間視窗內執行資料查詢和聚合操作,從而實現資料的持續更新和處理。
透過這種滾動更新機制,系統能夠高效管理資料的時效性,確保資料處理的連續性與一致性,同時有效提升了整體系統的穩定性和可靠性。
成果
透過資料轉存與聚合,本專案成功地將原有的 178 億條資料壓縮至 181 萬條,顯著改善了系統效能和資源利用情況。具體成果如下:
- 查詢效率顯著提升
資料聚合後,查詢的響應速度提高了數倍。由於資料量的減少,系統可以更快速地定位所需資訊,查詢平均響應時間從原來的數秒縮短至毫秒級別,為使用者提供了更流暢的體驗。這一提升在高頻查詢場景下尤為明顯,減輕了伺服器的查詢負擔,使系統在高峰期也能保持穩定的效能。
儲存成本降低
聚合資料後的儲存需求大幅下降,原本需要高儲存容量的 178 億條記錄被壓縮為 181 萬條,大大減少了對儲存空間的需求。這一變化帶來了顯著的成本節省,不僅降低了儲存硬體的開銷,還減少了備份、傳輸和維護資料的時間和成本。
系統資源最佳化
資料量減少後,CPU 和記憶體的佔用也顯著降低,系統資源得到了更加高效的利用。由於減少了處理冗餘資料的負擔,伺服器的整體效能得到提升,可以處理更多併發任務。此外,這種資源最佳化還延長了系統硬體的使用壽命,進一步節約了成本。
可擴充套件性提升
透過資料聚合,系統的可擴充套件性得到提升。在資料規模更大、資料增長更快的情況下,聚合策略能確保系統效能穩定,幫助應對未來的資料擴充套件需求,為系統長遠發展奠定了基礎。
相關文章
- MySQL 億級資料資料庫最佳化方案測試-銀行交易流水記錄的查詢MySql資料庫
- 百億級資料分表後怎麼分頁查詢?
- 百億級資料 分庫分表 後怎麼分頁查詢?
- cmdb 查詢資料庫操作記錄資料庫
- 海關資料查詢系統「查詢平臺分類」
- 記某百億級mongodb叢集資料過期效能最佳化實踐MongoDB
- SqlServer查詢資料改動歷史記錄SQLServer
- 記錄一次遞迴查詢的運用遞迴
- 資料統計查詢最佳化
- 記錄一次 postgresql 最佳化案例( volatility 自定義函式無法並行查詢 )SQL函式並行
- 記一次 Golang 資料庫查詢元件的優化。Golang資料庫元件優化
- 千萬級資料深分頁查詢SQL效能最佳化實踐SQL
- 記一次資料庫查詢超時優化問題資料庫優化
- 輕量級壓測平臺RunnerGo簡介及使用教程Go
- 30個MySQL千萬級大資料SQL查詢最佳化技巧詳解MySql大資料
- Laravel 框架使用 whereIn 查詢 SQL 時資料出錯記錄Laravel框架SQL
- 上億級別資料庫查詢資料庫
- 百億級資料處理優化優化
- 記錄一次鎖的最佳化
- MySQL 百萬級資料量分頁查詢方法及其最佳化MySql
- mysql千萬級資料量根據索引最佳化查詢速度MySql索引
- Django筆記二十八之資料庫查詢最佳化彙總Django筆記資料庫
- mysql 隨機查詢記錄MySql隨機
- 梧桐資料庫淺談查詢最佳化技巧資料庫
- 一次資料庫壓力測試的故事資料庫
- 常見資料庫最佳化記錄資料庫
- RestCloud測試平臺,支援壓力測試RESTCloud
- 記錄一次測開面試題記錄面試題
- MySQL資料庫查詢多個欄位值全部相同的記錄MySql資料庫
- EntityFramework Core筆記:查詢資料(3)Framework筆記
- leetCode資料查詢筆記(簡單)LeetCode筆記
- 記一次關於Laravel model查詢返回大量資料的效能優化Laravel優化
- 記一次 Boomer 壓測 MQTT 過程OOMMQQT
- 每日百億查詢請求,咋敢玩可觀測性的呢?
- 記錄一次在keil中,查詢ALIGN()括號裡任意字元,ALIGN(.*)字元
- Elasticsearch如何做到億級資料查詢毫秒級返回?Elasticsearch
- 【記錄】SSH分頁查詢功能
- 先進級!阿里雲大資料+AI平臺通過信通院資料平臺整體解決方案最高等級評測阿里大資料AI