Elasticsearch 壓測方案之 esrally 簡介

因爲 Elasticsearch(後文簡稱es) 的簡單易用及其在大數據處理方面的良好性能,愈來愈多的公司選用 es 做爲本身的業務解決方案。然而在引入新的解決方案前,難免要作一番調研和測試,本文即是介紹官方的一個 es 壓測工具 esrally,但願能爲你們帶來幫助。html

爲何要壓測?

關於壓測,咱們先來看下百度百科上的一個定義。node

壓測,即壓力測試,是確立系統穩定性的一種測試方法,一般在系統正常運做範圍以外進行,以考察其功能極限和隱患。python

從定義不難看出壓測的目的,是要測出一個系統的極限,提前發現隱患,早做打算。那麼對於 es 來說,我認爲壓測通常有如下幾個目的:git

  1. 驗證 es 的性能,儘管網上把 es 的性能誇上天了,仍是本身跑一下才放心。
  2. 針對 es 的某些配置作試驗性測試,好比關閉索引的 _all 特性,是否能提升寫性能,具體能提升多少。
  3. 對比 es 新版本和舊版本的性能差別。衆所周知,es 的版本升級很是快,用着 2.x 的同窗們還沒來得及升級 5.x ,眼看 6.x 都要發佈了。此時,你到底要不要升級呢?答案雖然是確定的,可是你怎麼說服你的 leader 呢?很簡單:壓測新版本,和舊版本作對比,用表格、圖表指明新版本在寫性能、讀性能方面的改善等等,搞定。
  4. 對 es 集羣作容量規劃。俗話說「人無遠慮,必有近憂」,容量規劃就是「遠慮」。簡單講就是你線上的 es 集羣一共須要多少節點?每一個節點的配置如何?這個集羣的寫性能極限是多少?讀性能呢?若是你回答不了這些問題,那就說明你沒有作過容量規劃,只是兩眼一抹黑,說幹就幹,上了再說,好在有驚無險,沒有碰到性能問題。至於何時會遇到問題,你也說不許,感受是個機率和人品問題……對面的老闆已經黑臉了…… 對於這個問題咱們在最後再來詳細討論。

如何進行壓測?

如今咱們知道壓測的目的了,接下來該如何進行壓測呢?通常有如下幾個方案:github

  1. 本身寫代碼。無需多言,想怎麼寫怎麼寫,難點在於若是確保測試代碼的專業性。這裏有一些開源項目,留給你們本身探索:esperfelasticsearch-stress-test
  2. http壓測工具。es 對外暴露了 Restful API,所以全部的針對 http 協議的壓測工具均可以用來測試 es,好比 JMeter、httpload等等。
  3. elastic 官方工具 esrally。

各個壓測方案各有優劣,你們能夠根據本身的需求和工具熟悉度來選擇本身的壓測工具。接下來咱們就來具體瞭解下 esrally。算法

入門

簡介

esrally 是 elastic 官方開源的一款基於 python3 實現的針對 es 的壓測工具,源碼地址爲https://github.com/elastic/rally,相關博客介紹在這裏。esrally主要功能以下:json

  • 自動建立、壓測和銷燬 es 集羣
  • 可分 es 版本管理壓測數據和方案
  • 完善的壓測數據展現,支持不一樣壓測之間的數據對比分析,也能夠將數據存儲到指定的es中進行二次分析
  • 支持收集 JVM 詳細信息,好比內存、GC等數據來定位性能問題

elastic 官方也是基於 esrally 進行 es 的性能測試,並將結果實時發佈到 https://elasticsearch-benchmarks.elastic.co/ ,你們能夠從該網站上直接查看 es 的性能。官方使用兩臺服務器進行壓測,一臺運行 esrally ,一臺運行 es,服務器的配置以下:服務器

CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
RAM: 32 GB
SSD: Crucial MX200
OS: Linux Kernel version 4.8.0-53
JVM: Oracle JDK 1.8.0_131-b11併發

網站頂部的 Geonames、Geopoint、Percolator等都是針對不一樣的數據集作的壓測,好比下面這些圖展現了 logging 日誌類數據的壓測結果。app

寫性能

讀性能

其餘系統指標

快速入門

esrally 的文檔在這裏,這裏簡單說下安裝與運行。
esrally 對於軟件環境的要求以下:

  • Python 3.4+ 和 pip3
  • JDK 8
  • git 1.9+

安裝方法爲:

pip3 install esrally

Tips:
可使用國內的pip源,好比豆瓣或者阿里的,這樣安裝會快不少。

安裝完畢後執行以下的配置命令,確認一些數據存放的路徑便可。

esrally configure

接下來就能夠開跑了,好比下面這條命令是針對 es 5.0.0 版本進行壓力測試。

esrally --distribution-version=5.0.0

運行結束後,會獲得以下的結果。

壓測結果

對於第一次見到壓測結果的同窗來講可能有些暈,這麼多數據,該怎麼看?!別急,一步步來!

Tips:
因爲 esrally 的測試數據存儲在國外 aws 上,致使下載很慢甚至會超時失敗,從而致使整個壓測沒法進行。後面我會把這些測試數據的壓縮包放到國內,你們能夠下載後直接放到 esrally 的數據文件夾下面,保證壓測的正常進行。另外因爲數據量過大,壓測的時間通常會好久,可能在1個小時左右,因此你們要有耐心哦~
若是你只是想體驗下,能夠加上 --test-mode 的參數,此時只會下載1000條文檔進行測試。

相關術語

rally 是汽車拉力賽的意思,也就是說 esrally 是將壓測比做了汽車拉力賽,所以其中的不少術語都是從汽車拉力賽中借鑑來的。

track

track 是賽道的意思,在這裏是指壓測用的數據和測試策略,詳細文檔在這裏。esrally 自帶的track都在 github 上,地址在這裏 https://github.com/elastic/rally-tracks。在該 repository 中,有不少測試數據,好比 geonames geopoint logging nested 等,每一個數據文件夾中的 README.md 中有詳細的數據介紹,而 track.json 即是壓測策略的定義文件。
咱們來看下 loggins/track.json 文件

{% import "rally.helpers" as rally with context %}

{
  "short-description": "Logging benchmark",
  "description": "This benchmark indexes HTTP server log data from the 1998 world cup.",
  "data-url": "http://benchmarks.elasticsearch.org.s3.amazonaws.com/corpora/logging",
  "indices": [
    {
      "name": "logs-181998",
      "types": [
        {
          "name": "type",
          "mapping": "mappings.json",
          "documents": "documents-181998.json.bz2",
          "document-count": 2708746,
          "compressed-bytes": 13815456,
          "uncompressed-bytes": 363512754
        }
      ]
    },
    {
      "name": "logs-191998",
      "types": [
        {
          "name": "type",
          "mapping": "mappings.json",
          "documents": "documents-191998.json.bz2",
          "document-count": 9697882,
          "compressed-bytes": 49439633,
          "uncompressed-bytes": 1301732149
        }
      ]
    }
  ],
  "operations": [
    {{ rally.collect(parts="operations/*.json") }}
  ],
  "challenges": [
    {{ rally.collect(parts="challenges/*.json") }}
  ]
}

該 json 文件主要包含下面幾個部分:

  • description 和 short-description: track 的描述文字
  • data-url: 一個url地址,指明測試數據的下載根路徑,與下方 indices 中的 documents 結合,可獲得數據的下載地址。
  • indices: 指定該track能夠操做的索引,包括建立、更新、刪除等操做。詳細信息能夠參見這裏
  • operations: 指定具體的操做,好比 index 索引數據的操做、force-merge 強制合併segment的操做、search 搜索的操做等等。具體例子能夠看下面的示例。詳細信息能夠參見這裏
  • challenges: 經過組合 operations 定義一系列 task ,再組合成一個壓測的流程,請參照下方的 例子。詳細信息能夠參見這裏

operations/default.json 中的一個定義以下:

{
      "name": "index-append",
      "operation-type": "index",
      "bulk-size": 5000
}

其中 operation-type 包含 index、force-merge、index-stats、node-stats、search等,每個operation-type都有本身的可定義參數,好比 index 中能夠經過指定 bulk-size 來決定批量寫入的文檔數。

challenges/default.json 中的一個定義以下:

{
      "name": "append-no-conflicts",
      "description": "",
      "default": true,
      "index-settings": {
        "index.number_of_replicas": 0
      },
      "schedule": [
        {
          "operation": "index-append",
          "warmup-time-period": 240,
          "clients": 8
        },
        {
          "operation": "force-merge",
          "clients": 1
        },
        {
          "operation": "index-stats",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 100,
          "target-throughput": 50
        },
        {
          "operation": "node-stats",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 100,
          "target-throughput": 50
        },
        {
          "operation": "default",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 500,
          "target-throughput": 10
        },
        {
          "operation": "term",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 500,
          "target-throughput": 60
        },
        {
          "operation": "range",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 200,
          "target-throughput": 2
        },
        {
          "operation": "hourly_agg",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 100,
          "target-throughput": 0.2
        },
        {
          "operation": "scroll",
          "clients": 1,
          "warmup-iterations": 100,
          "iterations": 200,
          "target-throughput": 10
        }
      ]
    }

這裏定義了一個名爲 append-no-conflicts 的 challenge。因爲每次壓測只能運行一個challenge,這裏的 default 參數是指當壓測未指定時默認運行的 challenge。schedule 中指定了該 challenge 中按順序執行 index-append、force-merge、index-stats、node-stats、default、term、range、hourly_agg、scroll 等 9 個task,其中每一個 task 都指定了 一個 operation,除此以外還能夠設定 clients (併發客戶端數)、warmup-iterations(預熱的循環次數)、iterations(operation 執行的循環次數)等,詳情請參見此處

經過下面的命令能夠查看當前 esrally 可用使用的track。

esrally list tracks

esrally 的 track 數據位於 rally 目錄(mac默認是 ~/.rally)中 benchmarks/tracks/ 下面。

car

car 是賽車的意思,這裏是指不一樣配置的 es 實例。經過下面的命令能夠查看 esrally 當前可用的 car。

esrally list cars

Name
----------
16gheap
1gheap
2gheap
4gheap
8gheap
defaults
ea
verbose_iw

cars 的配置位於 rally 目錄(mac默認是 ~/.rally)中 benchmarks/teams/default/cars/ 下面。具體配置能夠參見 cars 的文檔,除了 heap 的配置,全部的 es 配置均可以修改。

race

race 是一次比賽的意思,這裏是指某一次壓測。要比賽,就要有賽道和賽車,若是不指定賽車,就用 default 配置,若是不指定賽道,則默認使用 geonames track。經過下面的命令來執行一次 race。

esrally race --track=logging --challenge=append-no-conflicts --car="4gheap"

上面的命令即是執行一次壓測,並指定使用 logging 的track,運行該 track 中的 append-no-conflicts 的 challenge,指定的 car 爲 4gheap 的 es 實例。詳情能夠查看 race 相關文檔

Tournament

tournament 是錦標賽的意思,是由多個 race 組成的。經過下面的命令能夠查看全部的 race。

esrally list races

Recent races:

Race Timestamp    Track    Challenge            Car       User Tag
----------------  -------  -------------------  --------  ------------------------------
20160518T122341Z  pmc      append-no-conflicts  defaults  intention:reduce_alloc_1234
20160518T112057Z  pmc      append-no-conflicts  defaults  intention:baseline_github_1234
20160518T101957Z  pmc      append-no-conflicts  defaults

當有了多個 race 後,能夠經過下面的命令方便地比較不一樣 race 之間的數據。

esrally compare --baseline=20160518T112057Z --contender=20160518T112341Z

兩次 race 的數據比較

詳細信息能夠參見 tournament 的文檔

Pipeline

Pipeline 在這裏是指壓測的一個流程,經過下面的命令能夠查看已有的pipeline。

esrally list pipeline

Name                     Description
-----------------------  ---------------------------------------------------------------------------------------------
from-sources-complete    Builds and provisions Elasticsearch, runs a benchmark and reports results.
from-sources-skip-build  Provisions Elasticsearch (skips the build), runs a benchmark and reports results.
from-distribution        Downloads an Elasticsearch distribution, provisions it, runs a benchmark and reports results.
benchmark-only           Assumes an already running Elasticsearch instance, runs a benchmark and reports results
  • from-sources-complete 是從源代碼編譯 es 後再運行,能夠經過 --revision 參數指明要編譯的commit hash ,這樣就能夠針對某一個提交版本就行測試了。
  • from-sources-skip-build 若是已經編譯好了,使用該 pipeline,能夠跳過編譯的流程,節省測試時間
  • from-distribution 經過 --distribution-version 指定 es 版本,esrally 會從官網直接下載該版本的可執行文件,而後進行測試。
  • benchmark-only 此 pipeline 將 es 集羣的管理交由用戶來處理, esrally 只作壓測。若是你想針對已有集羣進行測試,那麼要將pipeline設定爲該模式。

詳細信息請參見 pipeline 的文檔

壓測流程

esrally 的壓測流程主要分爲如下三個步驟:

  1. 根據參數設定自行編譯或者下載 es 可執行實例,而後根據 car 的約定,建立並啓動 es 集羣。若是使用 benchmark-only 的pipeline,則該步驟省略。
  2. 根據指定 track 去下載數據,而後按照指定的 challenge 進行操做。
  3. 記錄並輸出壓測結果數據。

壓測結果分析

壓測結束後,esrally 會將結果輸出到終端和結果文件(位於 esrally 目錄logsbenchmarks/races)中,以下圖所示:

壓測結果

在 Metric 一欄,有很是多的指標數據,詳細的解釋能夠參見該文檔。通常要關注的數據有:

  • throughput 每一個操做的吞吐量,好比 index、search等
  • latency 每一個操做的響應時長數據
  • Heap used for x 記錄堆棧的使用狀況

先搞懂每一個 metric 的含義,而後根據本身的需求去確認本身要關注的指標。

每一次壓測都會以壓測時的時間命名,好比 logs/rally_out_20170822T082858Z.log ,這個日誌即是記錄的 2017年8月22日 8:28:58開始的壓測日誌。而在 benchmarks/races/2017-08-22-08-28-58 中記錄着最終的結果和 es 的運行日誌。

另外對於 benchmark-only 模式的測試,即針對已有集羣的壓力測試,也能夠經過安裝 X-Pack Basic 版本進行監控(Monitoring),在壓測的過程當中就能查看相關指標。

X-Pack Monitoring

esrally 能夠在配置的時候指定將全部的 race 壓測結果數據存入一個指定的 es 實例中,配置以下(在 esrally 目錄中 rally.ini 文件中):

[reporting]
datastore.type = elasticsearch
datastore.host = localhost
datastore.port = 9200
datastore.secure = False
datastore.user =
datastore.password =

esrally 會將數據存儲在以下 3 個index中,下面 * 代指月份,即按月存儲結果數據。

  • rally-metrics-* 該索引分指標記錄每次 race 的結果,以下圖所示爲某一次race的全部 metric 數據。

Metric 數據

第一列時間是指某一次壓測的時間,第二列時間是指標採集的時間,第三列 operation 指具體執行的操做,operation 爲空的指標都是總計類的,好比indexing total time 記錄的是總索引數據的時間、segments_count 是總段數等等。其餘的 operation 都記錄了每個操做的數據。須要注意的是,這裏記錄的是 operation 的全部採樣數據,不是一個最終的彙總數據。上面截圖中也能夠看出同一個 hour_agg 的operation 有多項名爲 service_time 的指標數據,但他們的採集時間是不一樣的。基於這些數據,咱們能夠作出某一次 race 中某個指標的可視化圖表,好比你想觀察本次 race 中 index-log 這個 task 的 throughput 指標數據,即可以經過以下圖的方式實現。

metric 數據展現

  • rally-result-* 該索引分指標記錄了每次 race 的最終彙總結果,好比下面這條數據。

    {
       "user-tag": "shardSizeTest:size6",
       "distribution-major-version": 5,
       "environment": "local",
       "car": "external",
       "plugins": [
         "x-pack"
       ],
       "track": "logging",
       "active": true,
       "distribution-version": "5.5.2",
       "node-count": 1,
       "value": {
         "50_0": 19.147876358032228,
         "90_0": 21.03116340637207,
         "99_0": 41.644479789733886,
         "100_0": 47.20634460449219
       },
       "operation": "term",
       "challenge": "default-index",
       "trial-timestamp": "20170831T063724Z",
       "name": "latency"
     }

這個記錄了 term operation 的 latency 指標數據,彙總值以 percentile(百分位數) 的形式展現。基於該數據,咱們能夠繪製針對某個指標的多race對比,好比下圖即是對比多 race 之間 hourly_agg(按小時作聚合)、default(match_all 查詢)、term(term查詢)、range(range查詢)的latency(延遲時間)對比。

屢次 race 的 latency 對比

  • rally-races-* 該索引記錄了全部 race 的最終結果,即命令行執行的輸出結果。

除了es相關指標數據外,esrally 還會同時記錄測試的一些環境信息,好比操做系統、JVM等等,你能夠方便的查看本次測試的軟硬件環境。

實戰

終於到了開賽的時候,下面咱們採用問答的形式來進行,但願你們看到問題後先本身思考下再看答案。

問題一

提問:如何對比 5.5.0 相比 2.4.6 的性能改進?

回答:

分別針對 5.5.0 和 2.4.6 作一次壓測,而後比較二者二者的相關指標便可,這裏咱們的 track 和 challenge 以下:

  • track: nyc_taxis
  • challenge: append-no-conflicts

測試步驟以下:

  1. 測試 2.4.6 的性能

esrally race --distribution-version=2.4.6 --track=nyc_taxis --challenge=append-no-conflicts --user-tag="version:2.4.6"

  1. 測試 5.5.0 的性能

esrally race --distribution-version=5.5.0 --track=nyc_taxis --challenge=append-no-conflicts --user-tag="version:5.5.0"

  1. 對比兩次 race 的結果

esrally list races

esrally compare --baseline=[2.4.6 race] --contender=[5.5.0 race]

Tips:
--user-tag 用於爲 race 打標籤,方便後續查找
若是隻是試一下,能夠加上 --test-mode ,用測試數據來跑,很快。

問題二

提問:如何測試 _all 關閉後對於寫性能的影響?

回答:

針對 5.5.0 版本的 es 作兩次測試,第一次開啓 _all,第二次關閉 _all,對比兩次的結果,因爲只測試寫性能,因此咱們只須要 index 類型的 operation執行。這裏咱們的 track 和 challenge 以下:

  • track: nyc_taxis
  • challenge: append-no-conflicts

測試步驟以下:

  1. 默認 nyc_taxis 的 mapping 設置是將 _all 關閉的,直接測試 _all 關閉時的性能。

esrally race --distribution-version=5.5.0 --track=nyc_taxis --challenge=append-no-conflicts --user-tag="enableAll:false" --include-tasks="type:index"

  1. 修改 nyc_taxis 的 mapping 設置,打開 _all。mapping 文件位於 rally 主目錄 benchmarks/tracks/default/nyc_taxis/mappings.json,修改 _all.enabled 爲 true。

esrally race --distribution-version=5.5.0 --track=nyc_taxis --challenge=append-no-conflicts --user-tag="enableAll:true" --include-tasks="type:index"

  1. 對比兩次 race 的結果

esrally list races

esrally compare --baseline=[enableAll race] --contender=[disableAll race]

下圖是我在 --test-mode 模式下運行的對比結果,也能夠看出關閉 _all 能夠提高寫性能。

測試結果

Tips:
--include-tasks 用於只運行 challenge 中的部分 task

問題三

提問:如何測試已有集羣的性能?

回答:

使用 benchmark-only 的 pipeline 便可,這裏咱們的 track 和 challenge 以下:

  • track: nyc_taxis
  • challenge: append-no-conflicts

測試步驟以下:

  1. 執行下方命令便可測試已有集羣

esrally race --pipeline=benchmark-only --target-hosts=127.0.0.1:9200 --cluster-health=yellow --track=nyc_taxis --challenge=append-no-conflicts

Tips:
--cluster-health=yellow 默認 esrally 會檢查集羣狀態,非 green 狀態會直接退出。添加該參數能夠避免該狀況

但願這三個問答能夠幫助到你們快速掌握 esrally 的用法。

進階

自定義 car

前面講解 car 的時候,咱們提到 esrally 已經自帶了一些可用的 es 配置,可是若是這些還不能知足你的時候,能夠經過下面兩個方案解決。

  1. 定製本身的car
    car 的配置文件位於 esrally 目錄 benchmarks/teams/default/cars,在這裏新增一個本身的 car 配置文件就能夠了。這裏就不贅述了,感興趣的能夠查閱 car 的文檔
  2. 本身搭建集羣
    最簡單的方式是脫離 esrally 的管理,自行搭建集羣,這樣想怎麼配置就怎麼配置了。

自定義 track

雖然 esrally 自帶了不少 track,並且這些數據自己也不小,簡單列在下面:

Track 壓縮數據大小 解壓數據大小 文檔數
geonames 252 MB 3.3 GB 11396505
geopoint 482 MB 2.3 GB 60844404
logging 1.2 GB 31 GB 247249096
nested 663 MB 3.3 GB 11203029
noaa 947 MB 9 GB 33659481
nyc_taxis 4.5 GB 74 GB 165346692
percolator 103KB 105 MB 2000000
pmc 5.5 GB 22 GB 574199

這些數據文件位於 esrally 目錄 benchmarks/data 下面。不一樣的 Track 有不一樣的測試目的,詳情能夠去該 github repo 下面去查看。

當咱們作定向測試的時候,仍是但願針對本身的數據進行壓測,此時能夠自定義 track。操做也很簡單,詳情能夠參考官方文檔。這裏簡單列一下操做步驟。

  1. 在 上文提到的 data 目錄中建立本身的數據目錄。
  2. 準備壓測數據文件。 esrally 使用的是一個json文件,實際上是一個一個 json object。
  3. 將準備好的數據文件壓縮成 bz2 格式,而後複製到步驟 1 建立的目錄中去。
  4. 新增自定義的track。能夠直接複製 geoname 目錄,而後修改相關的配置文件,將測試數據與 track 綁定。
  5. 添加完後,經過 esrally list rack 就能夠看到自定義的 track。

分佈式壓測

esrally 還支持分佈式壓測,即若是一個節點的 esrally 沒法達到要求的併發數、請求數,那麼能夠將 esrally 分佈到多臺機器上去同時執行。分佈式壓測文檔在這裏,此處用到了 esrally dameon,對應命令是 esrallyd 。簡單講就是 esrally 經過 esrallyd 將多臺機器組合成一個集羣,而後 esrally 在執行測試任務的時候經過制定 --load-driver-hosts 即可以將測試任務分發到對應的機器上執行。這裏便不贅述了,感興趣的去看前面提到的文檔。

最後一個問題

讓咱們回到開頭提到的容量規劃的問題吧!

提問:一個 index 的 shard 數該如何確認?

回答:

其實針對這個提問,還能夠再問下面兩個問題。

  1. shard 設置過少是否有問題?好比一直都採用默認的 5個分片
  2. shard 設置過可能是否有問題?好比直接設置爲100個分片

要回到這兩個問題,咱們得先知道 shard 的做用。shard 是 es 實現分佈式特性的基石,文檔在索引進 es 時,es 會根據一個路由算法,將每個文檔分配到對應的 shard 上。每一個 shard 實際對應一個 lucene index。那麼每一個 shard 能存儲的文檔數是否有上限呢?答案是有!每一個shard最多存儲 2^31 個文檔,即 20億。這是 lucene 設計決定的。那是否是隻要個人文檔數沒有超過20億,就能夠只用一個或者不多的shard 呢?不盡然。由於隨着 shard 體積的增大,其查詢效率會降低,並且數據遷移和恢復的成本也會增高。官方建議單個 shard 大小不要超過 50GB,能夠參見討論一討論二

如今回答上面的兩個問題。
shard數太小不必定好,若是數據量很大,致使每一個 shard 體積過大,會影響查詢性能。
shard數過大也不必定好,由於 es 的每次查詢是要分發給全部的 shard 來查詢,而後再對結果作聚合處理,若是 shard 數過多也會影響查詢性能。所以 shard 的數量須要根據本身的狀況測出來。

官方文檔有一節關於容量規劃的章節,建議你們去看一下,連接在這裏,其給出的步驟以下:

  1. 使用生產環境的硬件配置建立單節點集羣
  2. 建立一個只有一個主分片無副本的索引,設置相關的mapping信息
  3. 將真實的文檔導入到步驟 2 的索引中
  4. 測試實際會用到的查詢語句

測試的過程當中,關注相關指標數據,好比索引性能、查詢性能,若是在某一個點相關性能數據超出了你的預期值,那麼此時的 shard size大小即是符合你預期的單個 shard size的大小。接下來經過下面這個簡單的計算公式便大體能肯定一個 index 須要設定的 shard 數了。

shard數 = index 的數據總大小/單個shard size的極限值

好比你測出單個 shard size 最大爲 20 GB,而你預測該索引數據最大量在1年或者2年內不會超過 200GB,那麼你的 shard 數就能夠設置爲10。

接下來要作的事情也很明確,咱們要用 esrally 完成上面的壓測步驟:

  1. 自行維護 es 節點的建立和運行,esrally 運行的時候採用 benchmark-only 模式.
  2. 自定義 track,這裏有如下兩個重點:

    • 生成真實數據。若是你的數據沒法生成不少,那麼能夠在 track 的 schedule 中設置 iterations 參數,即循環進行同一個操做,這樣也能夠測試大數據量的寫性能。
    • 定義本身的查詢任務。在 track 的 operations 中是能夠定義本身的查詢語句的,好比下面這個
    {
      "name": "hourly_agg",
      "operation-type": "search",
      "index": "logs-*",
      "type": "type",
      "body": {
        "size": 0,
        "aggs": {
          "by_hour": {
            "date_histogram": {
              "field": "@timestamp",
              "interval": "hour"
            }
          }
        }
      }
    }

    其中的 body 即是自定義的查詢語句,因此你能夠經過本身的需求來設定查詢語句,以貼近實際使用的狀況。

  3. 還要記得設置索引的 mapping 與線上一致,好比是否啓用 _all 等設置。
  4. 基於自定義的track來進行壓測便可。要注意的是運行 esrally 的機器要和 es 機器分開,防止對 es 性能產生干擾。

Tips:
esrally 默認在每次壓測是會刪除已有的索引後再從新建立索引,若是你不想這樣,能夠在每一個 index 的配置中設置 auto-managed 爲 false,具體文檔在這裏
經過這個參數,你就能夠單獨壓測查詢性能了,而不用每次都要先通過漫長的導入數據的過程。

總結

esrally 針對 es 的壓測設計了一套完備的基於配置文件的測試流程,極大地簡化了操做難度,而且提供了可重複驗證的方式。對國內用戶來說,我認爲最大的難處仍是在於 esrally 自帶的 track 文件太大,從 國外 aws 下載很慢。好在能夠自定義 track,沒必要徹底依賴自帶的 track。

其餘沒啥好說的,esrally 棒棒噠,你們趕忙去試試吧,若是有問題歡迎來討論!

參考資料

  1. esrally 官方文檔
  2. Using Rally to benchmark Elasticsearch queries
  3. esrally 做者的演講視頻
  4. Benchmarking Elasticsearch for your use case with Rally
相關文章
相關標籤/搜索