1.背景
最近需要测试ES在一个中心化存储(lightbits)上的一个性能表现,比较ES存储在HDD,普通SSD,中心存储的性能差异;于是准备使用官方的esrally工具来测试,并且通过开源工具(elasticsearch-stress-test)辅助测试,并且验证esrally测试结果的准确性;
翻阅了ESrally的官方文档,以及大量的博客,并没有找到可以测试通过的方法,官方文档描述简单,博客大同小异,于是和ES社区小伙伴交流、并且翻阅部分脚本代码,解决了离线环境测试ES集群的问题,在这里总结一下,希望可以节省大家时间,帮助到需要的小伙伴;
2.离线安装
2.1 不使用root用户(如果只是测试远程集群,不在本地跑ES,可以忽略,为了统一,建议不用root)
2.2 版本信息
# 操作系统版本
CentOS7.6
# 选择较新版本
esrally 2.3.0
# git 1.9以上即可(理论上离线不需要git也可,没有测试过不存在git或者版本过低会有什么异常,可自行测试)
git version 1.9.4
# python版本限制,3.8<=version<3.10
Python 3.8.7
2.3 不要使用pip3 install安装
这样只能装到1.4.1版本的esrally,直接到git上下载esrally,用以离线安装;esrally下载
2.4 离线安装流程
1.提前准备好python环境、git环境,并且下载好esrally2.3的包
2.解压并安装:
tar -zxf esrally-dist-linux-2.3.0.tar.gz
cd esrally-dist-2.3.0/
bash install.sh
注:这里可能会遇到一些python3缺少包的异常,这里不一一列举,根据bash install.sh指令出现的异常一个个补充对应版本的包即可;(主要是python3.8.7离线安装缺少包导致的)
这里有一篇关于踩坑记录文章可以得到一些参考:
https://cloud.tencent.com/developer/article/1891569
https://cloud.tencent.com/developer/article/1892065
3.esrally --version查看版本信息,返回esrally 2.3.0即安装成功
3.术语介绍
rally:汽车拉力赛
track:赛道,压测方案,指压测用到的样本数据和压测策略
team/car: es instance
race: 一场比赛,一次压测
tournament: 锦标赛
测试规则由track.json定义,定义一个压测方案;
track.json包含以下几部分:
- indices:索引定义
- templates:定义indices template
- corpora:定义数据集文件
- operations:具体操作,可以没有,直接在schedule或者challenge内定义
- schedule:执行操作时的负载
- challenge:定义一次race需要经历的operation的集合,可以区分不同测试场景,比如append和update,便于分开统计
4.官方数据集、track介绍
esrally 自带的测试数据track:https://github.com/elastic/rally-tracks
主要包括:
1、Geonames: for evaluating the performance of structured data.
2、Geopoint: for evaluating the performance of geo queries.
3、Percolator: for evaluating the performance of percolation queries.
4、PMC: for evaluating the performance of full text search.
5、NYC taxis: for evaluating the performance for highly structured data.
6、Nested: for evaluating the performance for nested documents.
7、Logging: for evaluating the performance of (Web) server logs.
8、noaa: for evaluating the performance of range fields.
我在测试的时候主要用到了以下几个:
- Geonames:评估结构化数据的性能
- PMC:评估全文搜索的性能
- Nested:评估嵌套文档的性能
- Logging:评估(Web)服务器日志的性能
- noaa:评估range的性能
这里有一个大坑:在下载官方track的时候,一定要注意版本信息,特别是ES6/ES7.
测试过程中直接下载了GitHub上master分支的track,测试过程中esrally不会有报错信息,只是在某个operation开始,一直卡在0%,本质其实是用的ES7的mapping和语法在操作测试的集群,我测试的是ES6版本的集群,可以在ES集群日志找到异常信息,但是在esrally不会有任何信息;
5.官方数据集下载
到官方的tracks下面可以看到download脚本 https://github.com/elastic/rally-tracks
rally-tracks/download.sh
所有的数据集在线下载的时候都是在 “http://benchmarks.elasticsearch.org.s3.amazonaws.com/corpora”
所以可以直接在浏览器拼接出http://benchmarks.elasticsearch.org.s3.amazonaws.com/corpora/nested/documents.json.bz2 来完成下载;其中 “nested” 为数据集名称,“documents.json.bz2”为数据文件;
或者直接命令下载:
curl -o documents.json.bz2 http://benchmarks.elasticsearch.org.s3.amazonaws.com/corpora/nested/documents.json.bz2
6.测试指令
这里先给出测试最终的指令:
esrally race --pipeline=benchmark-only --target-hosts=test-xxx.com:80 --track-path=/home/deploy/.rally/benchmarks/tracks/default/pmc --client-options="basic_auth_user:'elastic',basic_auth_password:'xxx'" --challenge=indexing-querying --user-tag="zmc:chostpath-pmc-1k-indexing-querying" --offline
参数:
--target-hosts:指定远程elasticsearch,以ip:port或者domain:port的形式指定;
--pipeline: 指一个压测流程,可以通过 esrally list pipeline
查看,其中有一个 benchmark-only
的流程,就是将 es 的管理交给用户来操作,rally 只用来做压测,如果你想针对已有的 es 进行压测,则使用该模式;
--track-params:对默认的压测参数进行覆盖;
--user-tag:本次压测的 tag 标记;
--client-options:指定一些客户端连接选项,比如用户名和密码。
--offline 离线模式
--report-format {markdown,csv}
--track-path 手动指定压测方案(本地目录),这个参数是关键,可以绕开git
--challenge 指定要压测的方案里面的操作集合,challenges目录里面文件的内容之一(默认:append-no-conflicts)
7.最头疼的问题
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/esrally/rally.py", line 704, in dispatch_sub_command
dispatch_list(cfg)
File "/usr/local/lib/python3.6/site-packages/esrally/rally.py", line 592, in dispatch_list
track.list_tracks(cfg)
File "/usr/local/lib/python3.6/site-packages/esrally/track/loader.py", line 62, in list_tracks
available_tracks = tracks(cfg)
File "/usr/local/lib/python3.6/site-packages/esrally/track/loader.py", line 53, in tracks
repo = track_repo(cfg)
File "/usr/local/lib/python3.6/site-packages/esrally/track/loader.py", line 224, in track_repo
return GitTrackRepository(cfg, fetch, update)
File "/usr/local/lib/python3.6/site-packages/esrally/track/loader.py", line 265, in __init__
self.repo.update(distribution_version)
File "/usr/local/lib/python3.6/site-packages/esrally/utils/repo.py", line 102, in update
raise exceptions.DataError("Cannot update %s in [%s] (%s)." % (self.resource_name, self.repo_dir, e.message)).with_traceback(tb)
File "/usr/local/lib/python3.6/site-packages/esrally/utils/repo.py", line 66, in update
git.checkout(self.repo_dir, branch=branch)
File "/usr/local/lib/python3.6/site-packages/esrally/utils/git.py", line 36, in probe
return f(src, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/esrally/utils/git.py", line 65, in checkout
raise exceptions.SupplyError("Could not checkout [%s]. Do you have uncommitted changes?" % branch)
esrally.exceptions.DataError: ('Cannot update tracks in [/home/deploy/.rally/benchmarks/tracks/default] (Could not checkout [master]. Do you have uncommitted changes?).', None)
异常大致如上,无法连接git;这也是大多博客内容操作无法绕过去的,这里单独提一下;
使用--offline只是不会下载一些内容,但是连接git的操作依然会执行,通过 --track-path=/home/deploy/.rally/benchmarks/tracks/default/nested 重新指定本地的track则可以绕过git的连接,如果使用 --track=geonames 这个参数,将会一直去连接git找到这个最新的track信息;
8.对比两次race(测试)的结果
8.1 每次测试结果会保存在races目录中,可以通过指令展示所有结果:
esrally list races --offline --limit 100
8.2 将两次结果对比,并生成一个文件
esrally compare --baseline b566f866-df6f-4ad5-b4f9-596fd0452a88 --contender 38f255f5-43aa-4440-ba0b-ce7f40286d00 --report-file noaa-chostpath-lightbits.csv --report-format csv
9.测试时间太长怎么办?
测试时间长是因为数据集较大,可以将数据集减小,使用官方数据集(大json)里面的一部分数据:https://esrally.readthedocs.io/en/0.5.1/adding_tracks.html
0.解压.bz2文件 bzip2 -dk documents.json.bz2
- Pick 1.000 documents from your data set. We choose the first 1.000 here but it does not matter usually which part you choose:
head -n 1000 documents.json > documents-1k.json
. - Compress it:
bzip2 -9 -c documents-1k.json > documents-1k.json.bz2
10.报告分析
官方文档:https://esrally.readthedocs.io/en/stable/summary_report.html
11.拓展
11.1 esrally绕开git的方式?
方法1:上文提到的--tracks-path指定本地的tracks
方法2:修改.rally文件夹中的rally.ini配置文件,将源改成公司的gitlab项目的地址
11.2 elasticsearch-stress-test使用,如上文提到的github地址readme,只需要有python2.7+环境,以及安装ES python client的包(pip install elasticsearch)即可使用该测试脚本
在 ES 集群上运行测试,有 10 个索引,100 个随机文档,每个文档最多 10 个字段,每个文档的每个字段的大小最多为 50 个字符,每个索引将有 1 个分片,没有副本,测试将从 5 个客户端(线程)运行 300 秒,每 15 秒打印一次统计信息,将批量索引 5000 个文档,并在测试后将所有内容保留在 Elasticsearch 中
注:300s大概可以写100w文档,150s可以写50w左右的文档
python elasticsearch-stress-test.py --es_address test-xxx.com:80 --indices 10 --documents 100 --clients 5 --seconds 300 --number-of-shards 1 --number-of-replicas 0 --bulk-size 5000 --max-fields-per-document 10 --max-size-per-field 50 --no-cleanup --stats-frequency 15 --username 'elastic' --password 'xxxxx'