文章目錄
- 背景
- 問題定位
- 優化方式
- 排序鍵設計
- 寫入順序
- 壓縮算法 DoubleDelta
- LowCardinality
- 避免使用Nullable
- 總結
背景
clickhouse集群容量告警,項目中某些表占據大量的存儲空間,借此機會對ck的存儲優化進行實踐學習,并通過多種方式測試驗證優化效果。
問題定位
通過查詢系統表元數據,定位頭部存儲的表。之前的文章有具體查詢邏輯。如果能通過清理或者是控制表生命周期是最快的方式,不然就要看具體的表各列的存儲壓縮大小。以下圖為例,壓縮率在10以下的就是比較低的。
優化方式
要著手優化,最好標準自然是參考官方的最佳實踐。
排序鍵設計
按基數升序排列關鍵列,能提升存儲壓縮率和查詢效率。 https://clickhouse.com/docs/en/optimize/sparse-primary-indexes#ordering-key-columns-efficiently
- hits_URL_UserID_IsRobot具有復合主鍵的表(URL, UserID, IsRobot),其中我們按基數降序排列關鍵列
- hits_IsRobot_UserID_URL具有復合主鍵的表(IsRobot, UserID, URL),其中我們按基數按升序對鍵列進行排序
壓縮率:
查詢效率:
這里官方有提供效果驗證,就不在重復。
寫入順序
除了低基數列在前,通過對數據進行排序也能提升壓縮效率。 因為ck物理存儲同分區里也是分數據塊的,一個數據塊中的數據更有序也能提升存儲效率。
壓縮算法 DoubleDelta
在定位問題時,我們發現唯一鍵row_key 的壓縮率不到2,一部分原因是該字段寫入ck時是亂序的,另外就是使用合適的壓縮算法。 ck默認的算法是LZ4(原理是按照4字節窗口掃描,查找與之前的值是否匹配)。但如果我們是有序是列,可以使用另外兩個壓縮算法 Delta/DoubleDelta (Delta編碼存儲一個基礎值以及后續相鄰兩個數據的差值, Double Delta是在Delta基礎上再做一次Delta,等差數列壓縮相當優秀)
我們可以看下有序和無序的數據在不同壓縮算法的差異。Double Delta再壓縮有序列效率可謂“遙遙領先”。
LowCardinality
低基數建議使用LowCardinality。 相同數據(Android/IOS 枚舉)壓縮后大小差異近6倍。
避免使用Nullable
相同數據沒有Nullable 壓縮率更高
總結
以上是我們在優化存儲時主要嘗試的方案,具體優化還要結合業務情況來定。