為什么我們要從ES遷移到ClickHouse?
ElasticSearch 是一種基于 Lucene 的分布式全文搜索引擎,攜程用 ES 處理日志,目前服務器規模 500+,日均日志接入量大約 200TB。
圖片來自 Pexels
隨著日志量不斷增加,一些問題逐漸暴露出來:
- 一方面 ES 服務器越來越多,投入的成本越來越高。
- 另一方面用戶的滿意度不高,日志寫入延遲、查詢慢甚至查不出來的問題一直困擾著用戶。
而從運維人員的角度看,ES 的運維成本較高,運維的壓力越來越大。
為什么選擇 ClickHouse
ClickHouse 是一款高性能列式分布式數據庫管理系統,我們對 ClickHouse 進行了測試,發現有下列優勢:
①ClickHouse 寫入吞吐量大,單服務器日志寫入量在 50MB 到 200MB/s,每秒寫入超過 60w 記錄數,是 ES 的 5 倍以上。
②在 ES 中比較常見的寫 Rejected 導致數據丟失、寫入延遲等問題,在 ClickHouse 中不容易發生。
③查詢速度快,官方宣稱數據在 pagecache 中,單服務器查詢速率大約在 2-30GB/s;沒在 pagecache 的情況下,查詢速度取決于磁盤的讀取速率和數據的壓縮率。經測試 ClickHouse 的查詢速度比 ES 快 5-30 倍以上。
ClickHouse 比 ES 服務器成本更低:
- 一方面 ClickHouse 的數據壓縮比比 ES 高,相同數據占用的磁盤空間只有 ES 的 1/3 到 1/30,節省了磁盤空間的同時,也能有效的減少磁盤 IO,這也是 ClickHouse 查詢效率更高的原因之一。
- 另一方面 ClickHouse 比 ES 占用更少的內存,消耗更少的 CPU 資源。我們預估用 ClickHouse 處理日志可以將服務器成本降低一半。
④相比 ES,ClickHouse 穩定性更高,運維成本更低。
⑤ES 中不同的 Group 負載不均衡,有的 Group 負載高,會導致寫 Rejected 等問題,需要人工遷移索引;在 ClickHouse 中通過集群和 Shard 策略,采用輪詢寫的方法,可以讓數據比較均衡的分布到所有節點。
⑥ES 中一個大查詢可能導致 OOM 的問題;ClickHouse 通過預設的查詢限制,會查詢失敗,不影響整體的穩定性。
⑦ES 需要進行冷熱數據分離,每天 200T 的數據搬遷,稍有不慎就會導致搬遷過程發生問題,一旦搬遷失敗,熱節點可能很快就會被撐爆,導致一大堆人工維護恢復的工作。
⑧ClickHouse 按天分 Partition,一般不需要考慮冷熱分離,特殊場景用戶確實需要冷熱分離的,數據量也會小很多,ClickHouse 自帶的冷熱分離機制就可以很好的解決。
⑨ClickHouse 采用 SQL 語法,比 ES 的 DSL 更加簡單,學習成本更低。
結合攜程的日志分析場景,日志進入 ES 前已經格式化成 JSON,同一類日志有統一的 Schema,符合 ClickHouse Table 的模式。
日志查詢的時候,一般按照某一維度統計數量、總量、均值等,符合 ClickHouse 面向列式存儲的使用場景。
偶爾有少量的場景需要對字符串進行模糊查詢,也是先經過一些條件過濾掉大量數據后,再對少量數據進行模糊匹配,ClickHouse 也能很好的勝任。
另外我們發現 90% 以上的日志沒有使用 ES 的全文索引特性,因此我們決定嘗試用 ClickHouse 來處理日志。
用 ClickHouse 處理日志
ClickHouse 高可用部署方案
①容災部署與集群規劃
我們采用多 Shards、2 Replicas 的方式,通過 Zookeeper 進行服務器間互相備份,允許一個 Shard 一臺服務器 Down 機數據不丟失。
為了接入不同規模的日志,我們將集群分成 6 臺、20 臺兩種規模的多個集群。
②跨 IDC 部署
借助于 ClickHouse 分布式表的特性,我們實現了跨集群搜索。攜程有多個 IDC,日志分布在不同的 IDC。
為了避免跨 IDC 搬遷日志,我們在每個 IDC 都部署一套 ClickHouse,然后配置 ClickHouse 的跨 IDC 的 Cluster,創建分布式表,實現跨多個 IDC 數據搜索。
如下圖所示:
③幾個重要的參數說明
如下所示:
- max_threads:32 #用于控制一個用戶的查詢線程數。
- max_memory_usage:10000000000 #單個查詢最多能夠使用內存大小 9.31G。
- max_execution_time:30 #單個查詢最大執行時間。
- skip_unavailable_shards:1 #在通過分布式表查詢的時候,當某一個 Shard 無法訪問時,其他 Shard 的數據仍然可以查詢。
④踩過的坑
我們之前將 Cluster 的配置放在 config.d 的目錄下,當 ClickHouse 意外重啟后,發現查詢分布式表時部分 Shard 訪問不到的問題,因此我們現在不再使用 config.d 配置方式,Cluster 配置放在 metrika.xml 中。
消費數據到 ClickHouse
我們使用 gohangout 消費數據到 ClickHouse,關于數據寫入的幾點建議:
- 采用輪詢的方式寫 ClickHouse 集群的所有服務器,保證數據基本均勻分布。
- 大批次低頻率的寫入,減少 parts 數量,減少服務器 merge,避免 Too many parts 異常。通過兩個閾值控制數據的寫入量和頻次,超過 10w 記錄寫一次或者 30s 寫一次。
- 寫本地表,不要寫分布式表,因為分布式表接收到數據后會將數據拆分成多個 parts,并轉發數據到其它服務器,會引起服務器間網絡流量增加、服務器 merge 的工作量增加,導致寫入速度變慢,并且增加了 Too many parts 的可能性。
- 建表時考慮 partition 的設置,之前遇到過有人將 partition 設置為 timestamp,導致插入數據一直報 Too many parts 的異常。我們一般按天分 partition。
- 主鍵和索引的設置、數據的亂序等也會導致寫入變慢。
數據展示
我們調研了像 Supperset、Metabase、Grafana 等幾個工具,最終還是決定采用在 Kibana3 上開發支持 ClickHouse 實現圖表展示。
主要原因是 Kibana3 這種強大的數據過濾功能,很多系統都不具備,另外也考慮到遷移到其他系統成本較高,用戶短期內難以適應。
目前 K3 上幾種常用的圖表(terms、histogram、percentiles、ranges、table),我們都開發了對應的 ClickHouse 版本,用戶體驗與原版基本保持一直,查詢效率經過優化大幅提升。
查詢優化
Kibana 中的 Table Panel 用于顯示日志的明細數據,一般查詢最近 1 小時所有字段的數據,最終只展示前 500 條記錄。這種場景對于 ClickHouse 來說非常不友好。
針對這個問題,我們將 table Panel 的查詢分兩次進行:
- 第一次查詢單位時間間隔的數據量,根據最終顯示的數據量計算出合理查詢的時間范圍。
- 第二次根據修正后的時間范圍,結合 Table Panel 中配置的默認顯示的 Column 查詢明細數據。
經過這些優化,查詢的時間可以縮短到原來的 1/60,查詢的列可以減少 50%,最終查詢數據量減少到原來的 1/120。
ClickHouse 提供了多種近似計算的方法,用于提供相對較高準確性的同時減少計算量。
使用 MATERIALIZED VIEW 或者 MATERIALIZED COLUMN 將計算量放在平常完成,也能有效降低查詢的數據量和計算量。
Dashboard 遷移
因為 Kibana3 上的 Dashboard 很多,我們開發了一個 Dashboard 遷移工具,通過修改 kibana-init-* 索引中 Dashboard 的配置來進行 Dashboard 遷移。
接入 ClickHouse 的效果
目前我們一個集群的日志量 100T 左右(壓縮前 600T 左右),ClickHouse 服務器主要監控指標如下:
ClickHouse 相對 ES 占用更少的內存。ES 為了提高查詢效率會將很多數據放在內存中,如:segment 的索引數據、filter cache、field data cache、indexing buffer 等。
ES 內存的使用量與索引量、數據量、寫入量、查詢量等成正比。刪除(下線)索引、遷移索引或者擴容是應對 ES 內存問題的常用手段。
但是刪除(下線)索引導致用戶希望保存更長時間數據的需求無法滿足,而服務器擴容導致又了成本上升。
ClickHouse 的內存消耗主要包括內存型的 engine,數據索引,加載到內存中待計算的數據,搜索的結果等。在 ClickHouse 中日志的數據量和保存時間主要和磁盤有關。
相比 ES,ClickHouse 后至少可以節省 60% 的磁盤空間。
如上圖所示,Netflow 的日志占用的磁盤空間 ClickHouse 是 ES 的 32%,CDN 日志占用磁盤空間 ClickHouse 是 ES 的 18%,Dblog 的日志 ClickHouse 是 ES 的 22.5%。
比較查詢速度提升,ClickHouse 比 ES 提升了 4.4 倍到 38 倍不等,原來 ES 上查詢不出來的問題基本得到了解決,查詢慢的問題有了很大的提升。
Netflow 由于數據量非常大,導致 ES 無法查詢,ClickHouse 中經過優化,查詢耗時 29.5s,CDN 的查詢 CK 和 ES 快 38 倍,dbLog 的查詢 CK 比 ES 快 4.4 倍。
關于查詢速度的對比,因為在生產環境,無法保證 ES 和 ClickHouse 的環境一樣,ES 使用的是 40 核 256G 的服務器,一臺服務器部署一個 ES 實例,單服務器數據量 3T 左右。
ClickHouse 采用的是 32 核 128G 的服務器,單服務器數據量大約 18T 左右,一臺服務器部署一個 ClickHouse 實例。
用 ClickHouse 處理日志查詢速度得到了很大的提升,基本解決了數據保存時間短的問題,用戶使用體驗也得到了提升。
我們預估使用現在 ES 日志集群 50% 的服務器資源就能就能夠完成現有 ES 日志的處理,并能提供比現在更好的用戶體驗。
ClickHouse 基本運維
總體來說 ClickHouse 的運維比 ES 簡單,主要包括以下幾個方面的工作:
①新日志的接入、性能優化。
②過期日志的清理,我們通過一個定時任務每天刪除過期日志的 partition。
③ClickHouse 的監控,使用 ClickHouse-exporter+VictoriaMetrics+Grafana 的實現。
④數據遷移,通過 ClickHouse 分布式表的特性我們一般不搬遷歷史數據,只要將新的數據接入新集群,然后通過分布式表跨集群查詢。
隨著時間的推移,歷史數據會被清理下線,當老集群數據全部下線后,新老集群的遷移就完成了。
確實需要遷移數據時,采用 ClickHouse_copier 或者復制數據的方式實現。
⑤常見問題處理:
慢查詢:通過 kill query 終止慢查詢的執行,并通過前面提到的優化方案進行優化。
Too many parts 異常:Too many parts 異常是由于寫入的 part 過多 part 的 merge 速度跟不上產生的速度。
導致 part 過多的原因主要包括幾個方面:
- 設置不合。
- 小批量、高頻次寫 ClickHouse。
- 寫的是 ClickHouse 的分布式表。
- ClickHouse 設置的 merge 線程數太少了。
無法啟動:之前遇到過 ClickHouse 無法啟動的問題。
主要包括兩個方面:
- 文件系統損壞,通過修復文件系統可以解決。
- 某一個表的數據異常導致 ClickHouse 加載失敗,可以刪除異常數據后啟動,也可以把異常的文件搬到 detached 目錄,等 ClickHouse 起來后再 attach 文件恢復數據。
總結
將日志從 ES 遷移到 ClickHouse 可以節省更多的服務器資源,總體運維成本更低,而且提升了查詢速度,特別是當用戶在緊急排障的時候,這種查詢速度的成倍提升,對用戶的使用體驗有明顯的改善。
我們將繼續致力于將 ES 的日志遷移到 ClickHouse,并優化日志查詢性能,讓 ClickHouse 在日志分析領域為用戶提供更大的價值。
但是 ClickHouse 畢竟不是 ES,在很多業務場景中 ES 仍然不可替代,ClickHouse 也不僅只能處理日志,進一步深入研究 ClickHouse,讓 ClickHouse 在更多領域發揮更大的價值,是我們一直努力的方向。
作者:Gavin Zhu
簡介:攜程軟件技術專家,負責監控系統運維開發、ES 系統運維及 Clickhouse 技術應用推廣及運維工作。
編輯:陶家龍
出處:轉載自公眾號攜程技術(ID:ctriptech)