如何對 ElasticSearch 叢集進行壓力測試

Bestony發表於2020-08-07

當 ElasticSearch 的業務量足夠大,比如每天都會產生數百 GB 資料的時候,你就會自然而然的需要一個效能更強的 ElasticSearch 叢集。特別是當你使用的場景是一些典型的大量資料進入的場景,比如網站日誌、使用者行為記錄、大型電商網站的站內搜尋時,一個強勁的 ElasticSearch 是必不可少的元件。在這樣的場景下,如何找到一組合適的 ElasticSearch 叢集?如何評估 ElasticSearch 叢集的效能,就成為了一個十分重要的因素。

用什麼 ElasticSearch 進行壓力測試?

對於 ElasticSearch 效能測試和壓力測試方面,其實有很多不同的方案,比如:

  • Rally:Rally 是 Elastic 官方針對於 ElasticSearch 的巨集觀測試工具。
  • ESPerf:一個基於 Golang 編寫的 ElasticSerch 效能測試工具
  • Elasticsearch Stress Test:由著名的 ElasticSearch 服務提供商 Logzio 開發的效能測試工具

除了這些定製化的工具意外以外,ElasticSearch 也可以藉由其 Restful API 來使用Load Runner、JMeter等老牌工具進行測試,這些工具零零散散,各有各的用法和用途,不過,對於廣大開發者而言,還是官方出的 Rally 更令人滿意。

在本篇文章中,將會使用 Rally 來完成 ElasticSearch 叢集的壓力測試

Rally 作為官方出品的工具,來自官方的信任加成讓他成為各家進行壓力測試的首選工具。其次, Rally 官方給出了多種預設的資料集(Tracks)。如果你的使用場景覆蓋在這些資料集(比如HTTP 訪問事件資料、地理名稱資料、地理座標點資料、HTTP 請求日誌、問答場景、叫車記錄等場景)中,可以直接使用已有的資料集,來完成測試,而無需製造測試資料。

即使你的場景比較特殊,無法被官方的資料集所覆蓋,也依然可以根據自己的線上資料,來建立資料集,確保測試效果的準確。

如何使用 Rally 進行測試?

在瞭解了 Rally 後,來具體看一看 Rally 的使用。

測試前的準備

關於 Rally 的基本安裝,這裡就不再介紹,總的來說十分簡單,在配置好了 JDK 和 Python 環境以後,只需要執行pip install rally 就可以完成安裝。如果你的環境複雜,希望以一個更簡單的方式來執行,你也可以選擇使用 Docker 來執行 Rally ,進行測試。關於更多的安裝方式,你可以參考 Rally 的安裝文件.

在安裝完成了 Rally 後,就可以開始進行 ElasticSearch 的測試。

在測試前,你需要先了解一些基本概念

  • race:在 Rally 中,每一次測試都可以稱之為 race
  • car: 在 Rally 中,每一個參與測試的叢集,都可以稱之為 car ,不同的叢集就是不同的 car,如果你是在選配置,則可以通過切換 car 來設定不同配置的測試。
  • track: 在 Rally 中,每一次測試用的資料,都可以稱之為 Track,不同的 Track 意味著不同的測試資料。
  • challange: 在 Rally 中,每一個 challange 意味著一個不同的測試場景,具體的場景則代表著 ElasticSearch 所執行的操作。

在瞭解測試的基本概念後,就可以開始進行壓力測試。

進行壓力測試

測試裝置

由於本次測試實際上是一次選型的過程,在測試之前,我曾閱讀了 Elastic 官方的權威指南中的硬體部分.在其文件中提供了對於運轉 ElasticSearch 叢集裝置的推薦配置。

  1. 64 GB 記憶體的機器是非常理想的, 但是32 GB 和16 GB 機器也是很常見的。少於8 GB 會適得其反(你最終需要很多很多的小機器),大於64 GB 的機器也會有問題, 我們將在 堆記憶體:大小和交換 中討論。
  2. 如果你要在更快的 CPUs 和更多的核心之間選擇,選擇更多的核心更好。多個核心提供的額外併發遠勝過稍微快一點點的時脈頻率。
  3. 如果你負擔得起 SSD,它將遠遠超出任何旋轉介質(注:機械硬碟,磁帶等)。 基於 SSD 的節點,查詢和索引效能都有提升。如果你負擔得起,SSD 是一個好的選擇。
  4. 通常,選擇中配或者高配機器更好。避免使用低配機器, 因為你不會希望去管理擁有上千個節點的叢集,而且在這些低配機器上執行 Elasticsearch 的開銷也是顯著的。

因此,我選擇了原本打算購買的三家廠商(阿里雲、騰訊雲、UCloud)的裝置進行測試,在具體的配置層面,則在各家購買四臺 8C64G 100GBSSD磁碟的的雲主機來進行測試。

測試環節

1. 構建叢集

在進行測試前,需要先對已有的三臺裝置搭建叢集,並配置叢集連結,確保叢集正常工作。叢集搭建的部分,你可以參考官方文件中的Add and remove nodes in your cluster部分。

2. 執行測試命令

在完成了叢集的建設後,測試就簡單很多,只需要執行命令,便可以對已經建設好的叢集進行測試,比如:

esrally --track=pmc --target-hosts=10.5.5.10:9200,10.5.5.11:9200,10.5.5.12:9200 --pipeline=benchmark-only

執行完命令後,接下來就是漫長的等待,根據機器的配置和叢集等

3. 獲得測試結果

在執行了測試命令後,測試完成後,你就可以獲得相應的測試結果。不過,為了方便進行對比和檢視,你可以在測試的命令中加入引數,從而實現將測試結果匯出為特定的格式。

比如,執行這樣的測試命令,就可以獲得 CSV 格式的測試資料

esrally --track=pmc --target-hosts=10.5.5.10:9200,10.5.5.11:9200,10.5.5.12:9200 --pipeline=benchmark-only -report-format=csv --report-file=~/benchmarks/result.csv

當你得到了 csv 的結果後,就可以對資料進行分析和對比了。

如何檢視 Rally 的測試結果

當我們對 Rally 執行測試以後,我們會拿到大量的資料,而具體這些資料應該如何來看呢?接下來我們一一來看。

如何理解 Rally 的資料

Rally 匯出的資料共有 4 列,分別是 Metric(維度)Task(任務)Unit(單位)‌Result(結果)

我們可以將資料按照 Task 進行切分,你可以得到若干組結果,如:

  • 沒有 Task 的巨集觀資料
  • index-append 組資料
  • index-stats 組資料
  • node-stats 組資料
  • phrase 組資料
  • ...

不同的組意味著 ElasticSearch 在不同場景下的應用,因此,你在對比時,需要按照分組來看資料。而分組內部的資料,就簡單了許多,除了巨集觀資料以外,其他各組的資料基本上都是一個模式的,具體可以分為以下 14 組資料。

  • Min/Median/Max:本組測試的最小吞吐率、中位吞吐率和最大吞吐率,單位為 ops/s ,越大越好。
  • 50th/90th/99th/100th percentile latency: 提交請求和收到完整回覆之間的時間段,越小越好
  • 50th/90th/99th/99.9th/100th percentile service time:請求處理開始和接收完整響應之間的時間段,越小越好
  • error rate:錯誤率,錯誤響應相對於響應總數的比例。任何被 Elasticsearch Python 客戶端丟擲的異常都被認為是錯誤響應(例如,HTTP 響應碼 4xx、5xx或者網路錯誤,如網路不可達)。

當你能夠理解資料的劃分方式後,對於 Rally 返回的眾多資料就比較好理解了。接下來,我們以實際例子來看 Rally 返回的資料。

如何理解 Rally 返回的巨集觀測試資料

這裡以我測試的資料為例。

根據每組資料對應的不同操作,我們可以將其資料分為若干組,這裡我將資料按照顏色進行了一個基礎的劃分,從上到下依次為:

  • 索引時間
  • 索引節流時間
  • 合併時間
  • 合併節流時間
  • 重新整理時間
  • 重刷時間

首先,先看第一組的索引時間,索引時間共有四個指標:

  • Cumulative indexing time of primary shards: 主分片累計索引時間
  • Cumulative indexing time across primary shards:跨分片累計索引時間
  • Cumulative indexing throttle time of primary shards:主分片累計節流索引時間
  • Cumulative indexing throttle time across primary shards:跨分片累計節流索引時間

這四個指標說明了 ElasticSearch 在進行資料處理所需要的索引時間,因此,時間越短越好。

Metric騰訊雲UCloud阿里雲
Cumulative indexing time of primary shards25.26283333333330019.266221.40011666666670
Min cumulative indexing time across primary shards5.02973.81776666666667004.2537666666666700
Median cumulative indexing time across primary shards5.0520666666666703.82523333333333004.272083333333330
Max cumulative indexing time across primary shards5.0763166666666703.91906666666667004.3139

在本組測試結果中,騰訊雲的計算時間耗費最長,阿里雲可以在騰訊的基礎之上,有約 16 % 的效能提升,UCloud 則在騰訊雲的基礎之上提升了 24%

在測試過程中,會因為機器的效能等因素,而造成實際測試時間的不同。在這三組中,阿里雲是最神奇的一個,因為它測試時間達到了6個小時。而 UCloud 和騰訊雲則分別在 3 小時和 4 小時左右,實際的測試體驗還是有很大的差距。如果你要復現相應的實驗,建議你在早上進行,這樣出測試結果的時候剛好還在白天。

接下來看合併時間的資料

  • Cumulative merge throttle time of primary shards:主分片累計節流合併時間
  • Min cumulative merge throttle time across primary shards:主分片累計節流合併時間
  • Median cumulative merge throttle time across primary shards:主分片累計節流中位合併時間
  • Max cumulative merge throttle time across primary shards:主分片累計節流最大合併時間

合併時間組結果類似於索引時間組,不同的是測量的資料 Merge 時間。和 index 類似,時間越短越好,合併數量越大越好。

Metric騰訊雲UCloud阿里雲Unit
Cumulative merge time of primary shards12.63797.71736666666667011.083600000000000min
Cumulative merge count of primary shards9011699
Min cumulative merge time across primary shards2.20371.436051.8695333333333300min
Median cumulative merge time across primary shards2.53911666666667001.57131666666667002.2406333333333300min
Max cumulative merge time across primary shards2.7339666666666701.65381666666667002.5342min

在本組測試結果中,騰訊雲的計算時間耗費最長,阿里雲可以在騰訊的基礎之上,有約 9 % 的效能提升,UCloud 則在騰訊雲的基礎之上提升了 30%~40%

其他幾組類似的資料,這裡就不再一一介紹,大家可以自行下載文章最後的資料進行分析,評估,得出結論。

如何理解 Rally 返回的專案測試資料

除了巨集觀資料以外,Rally 返回資料中極大比例的是各種不同場景下的資料,這裡,我們也選兩組資料進行對比分析,看一看這些資料應該如何理解。

首先,我們看一下 node-stats 組的結果。

node-stats 組的結果是針對 node-stats 命令的資料分析結果。這裡的吞吐量越大越好,時延則越小越好。

MetricTask騰訊雲UCloud阿里雲Unit
Min Throughputnode-stats90.0790.0790.07ops/s
Median Throughputnode-stats90.1190.1190.12ops/s
Max Throughputnode-stats90.3990.4490.42ops/s
50th percentile latencynode-stats2.17983788934362001.4914058338035801.8348334997426700ms
90th percentile latencynode-stats2.5212786893462201.86984359979760001.9605179221798600ms
99th percentile latencynode-stats3.7958803976653103.1735501120056102.901402467268780ms
99.9th percentile latencynode-stats12.8849285100555009.62514549798658017.55732728102550ms
100th percentile latencynode-stats18.13429577850910010.2951944445522020.23470633321270ms
50th percentile service timenode-stats2.1118245003890501.42319650012723001.7749374997038100ms
90th percentile service timenode-stats2.4530315993615701.79797490045530001.8996412000888100ms
99th percentile service timenode-stats3.6861332198350302.95360312949015002.8262974901645100ms
99.9th percentile service timenode-stats12.8180928703135009.551407762206578.42020982098726ms
100th percentile service timenode-stats16.34543399995890010.2264939996530020.173265999801500ms

在本組測試結果中,阿里雲、騰訊雲、UCloud 在效能方面沒有較大的差距。

類似的,我們可以對比 country_agg_uncached 組的結果

MetricTask騰訊雲UCloud阿里雲Unit
Min Throughputcountry_agg_uncached3.603.613.60ops/s
Median Throughputcountry_agg_uncached3.603.613.60ops/s
Max Throughputcountry_agg_uncached3.603.613.61ops/s
50th percentile latencycountry_agg_uncached259.7333187786720116.19688144446600197.52657255594400ms
90th percentile latencycountry_agg_uncached264.3554400450740125.7470980999640201.85445903407500ms
99th percentile latencycountry_agg_uncached270.25939978284400132.88548155585000205.84624599263400ms
100th percentile latencycountry_agg_uncached278.76161922358700133.7250455553660206.57134322209500ms
50th percentile service timecountry_agg_uncached259.5503135007680115.99637649987900197.4296050002520ms
90th percentile service timecountry_agg_uncached264.2378849999660125.53214089985000201.7642059001450ms
99th percentile service timecountry_agg_uncached270.08045803115200132.6980350402570205.7533532799970ms
100th percentile service timecountry_agg_uncached278.6570290008970133.52231299995800206.47192300020800ms
error ratecountry_agg_uncached0.000.000.00%

在本組測試結果中,阿里雲、騰訊雲、UCloud 在吞吐量方面沒有較大的差距,時延方面 UCloud 會更好一點。

關於更多的資料,我們不在這裡一一介紹,我將測試資料已經附在了文章的最後,你可以通過下載資料,自行分析,來練習 Rally 的使用和資料分析。

一些使用 Rally 時的小技巧

如何解決 Rally 網路不好的問題?

Rally 在執行時,需要下載相應的資料進行真實場景下的模擬,在這種情況下,Rally 需要從 AWS S3 上下載一些資料包,用於本地的測試。但國內的裝置對於 S3 的訪問不算太友好,經常會在下載的時候出現問題,因此,你可以選擇前置下載資料,這樣在測試的時候可以直接使用本地的資料來完成測試,減少失敗的可能。

想要前置下載資料也很簡單隻需要執行如下命令:

curl -O https://raw.githubusercontent.com/elastic/rally-tracks/master/download.sh
chmod u+x download.sh
./download.sh geonames
cd ~
tar -xf rally-track-data-geonames.tar

在執行 download.sh 時加入 track 名,就可以下載對應 track 資料的壓縮包到本地,你可以根據自己的實際使用情況,來決定使用什麼樣的 track 模擬真實場景。

總結

在業務真正使用 ElasticSearch 之前,你可以像我一樣,藉助於 Rally 對備選的 ElasticSearch 叢集進行壓力測試,並通過對壓測結果進行分析,從而獲得明確的選型建議。比如,在我這次測試中,顯然 UCloud 優於其他兩家,是一個價效比 更高的選擇。當然,這是一個實驗環境下的壓測,還是需要根據具體的業務場景做測試來進行選型,更為科學,不過希望壓測方法能給予大家參考,也歡迎大家在後續實際的測試過程中給予我反饋。

附錄

本文涉及到的測試資料均可以在下載地址找到。

相關文章