> 想知道自己的服务器到底能扛多少写入?ES 集群换块固态盘能提升多少?本文记录一次从零安装 esrally 到完成多组磁盘对比压测的完整过程,所有命令和数据均为实测。
一、为什么要用 esrally
做日志平台选型时经常要回答几个问题:
- 这台机器跑 ES,写入吞吐到底能到多少 docs/s?
- 机械盘换固态盘,索引性能真的有明显差别吗?
- 升级 ES 版本后性能是涨了还是跌了?
靠业务日志去"感觉"是不靠谱的,需要标准化的基准测试。esrally 是 Elastic 官方的压测工具,内置标准数据集(track)和标准测试场景(challenge),跑出来的结果可以直接横向对比,比自己在 bulk 接口上写脚本压测科学得多。
几个核心概念先过一遍:
| 概念 | 含义 |
|---|---|
| track | 测试赛道,内置了 geonames、http_logs 等标准数据集和操作定义 |
| challenge | 测试场景,如 append-no-conflicts(纯写入)、含查询的混合场景 |
| pipeline | 执行方式,benchmark-only 表示只压测、不负责装 ES |
| race | 一次测试运行,用 race-id 区分 |
| car | 被测节点的配置模板 |
二、环境准备
测试机是 Ubuntu,esrally 是 Python 写的,用 pip 安装即可。前置依赖:JDK 17、git、pip3。
bash
# 安装 JDK 17
sudo apt install openjdk-17-jdk
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 安装 git 和 pip3
sudo apt install git
sudo apt install python3-pip
# 安装 esrally
pip3 install esrally
echo 'export PATH=$PATH:$HOME/.local/bin' >> ~/.bashrc
source ~/.bashrc
# 验证:列出可用赛道
esrally list tracks
如果机器上已经有 ES 在跑,还需要把 ES 的 bin 目录加进 PATH(后面 esrally 管理测试节点时会用到):
bash
echo 'export ES_HOME=~/tools/elasticsearch-7.17.25' >> ~/.bashrc
echo 'export PATH=$ES_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
三、离线准备测试数据(国内网络必看)
esrally 默认会在跑分前自动从 GitHub 拉取赛道和数据集,国内网络经常拉不动。建议提前手动下载:
bash
curl -O https://raw.githubusercontent.com/elastic/rally-tracks/master/download.sh
chmod u+x download.sh
./download.sh geonames
tar -xf rally-track-data-geonames.tar
geonames 数据集解压后约 3.3 GB,后面多组测试复用这一份数据即可。
四、拉起被测 ES 节点
esrally 有两种玩法:一种是让它自己下载并启动一个 ES 节点,一种是 benchmark-only 模式直接压你自己已有的集群。这里先用第一种,在本机拉起一个 7.17.28 的节点:
bash
esrally install --quiet --distribution-version=7.17.28 \
--node-name="rally-node-0" \
--network-host="127.0.0.1" \
--http-port=39200 \
--master-nodes="rally-node-0" \
--seed-hosts="127.0.0.1:39300"
命令会返回一个 installation-id:
json
{
"installation-id": "b92e0e16-218a-4cb5-9b4e-d38d7ad18e94"
}
这个 id 一定要记下来,启动节点时要用:
bash
export INSTALLATION_ID=b92e0e16-218a-4cb5-9b4e-d38d7ad18e94
export RACE_ID=$(uuidgen)
esrally start --installation-id="${INSTALLATION_ID}" --race-id="${RACE_ID}"
看到 SUCCESS 就说明节点已经起来了。
五、开跑
最核心的一条命令:
bash
esrally race \
--pipeline=benchmark-only \
--target-host=127.0.0.1:39200 \
--track=geonames \
--challenge=append-no-conflicts-index-only \
--on-error=abort \
--race-id=${RACE_ID}
参数说明:
--pipeline=benchmark-only:只压测,不管 ES 的安装启停--target-hosts:被测集群地址,也可以指向局域网里别的机器--challenge=append-no-conflicts-index-only:纯写入场景,只测索引不跑查询,适合先摸写入上限--on-error=abort:出错即停,避免脏数据污染结果--race-id:本次运行的唯一标识,便于事后对比- 断网环境下记得加
--offline,否则会刷一堆 Could not update tracks 警告
跑的过程会实时显示每个任务的进度:
Running delete-index [100% done]
Running create-index [100% done]
Running check-cluster-health [100% done]
Running index-append [100% done]
Running force-merge [100% done]
Running wait-until-merges-finish [100% done]
六、结果怎么看
跑完会输出一张大表,几十个指标,重点关注这几行(机械盘一组实测):
| 指标 | 值 |
|---|---|
| Mean Throughput (index-append) | 11303 docs/s |
| Median Throughput | 12233 docs/s |
| 50th percentile latency | 1086 ms |
| 99th percentile latency | 12078 ms |
| error rate | 0 % |
| Segment count | 115 |
| Total Young Gen GC time | 26.1 s / 867 次 |
经验解读:
- 吞吐和延迟一起看:吞吐高但 P99 延迟高得离谱,说明写入在排队,实际业务未必能接受
- GC 次数:Young GC 频繁但 Old GC 为 0,一般说明堆设置还算健康
- error rate 必须为 0,有报错的跑分没有意义
七、实测:磁盘对 ES 写入性能影响有多大
同一份数据、同一个 challenge,换了三种环境跑,结果差异大到出乎意料:
| 环境 | 平均吞吐 (docs/s) | 50% 延迟 | 99% 延迟 | 总耗时 |
|---|---|---|---|---|
| 机械硬盘物理机 | 11,303 | 1086 ms | 12078 ms | 1175 s |
| 机械硬盘(隔天复测) | 44,964 | 536 ms | 3450 ms | 369 s |
| 固态盘单容器 | 70,247 | 342 ms | 1696 ms | 4143 s* |
| 固态盘虚机 | 93,664 | 63 ms | --- | 292 s |
*固态容器那组跑的是完整混合场景(含查询),所以总耗时不可比。
两个直观结论:
- 机械盘和固态盘的差距是数量级的,同一台机械盘机器两次测试都能差 4 倍(后面那次页缓存热了),说明机械盘环境下磁盘 IO 是绝对瓶颈,且结果极不稳定
- 固态环境下写入延迟直接从秒级降到几十毫秒,P50 从 1086ms 降到 63ms------如果是日志类场景,把钱花在固态盘上比加内存划算得多
另外固态容器那组跑了完整混合场景,还能拿到查询类指标,例如 term 查询 99 ops/s、P99 延迟 16ms,聚合 cached/uncached 差距明显(3 ops/s vs 99 ops/s),scroll 每秒 20 页。这些查询指标对评估检索场景很有参考价值。
八、踩坑记录
- installation-id 没记 :
esrally start必须用到 install 返回的 id,丢了只能重装,建议直接 export 到变量里 - Could not update tracks 警告刷屏 :网络不通导致的,加
--offline参数即可,不影响本地已有的赛道 - No throughput metrics available:有一组测试报了 The benchmark ended already during warmup,预热阶段就把数据写完了,吞吐指标没采到。数据量小、机器快的时候容易碰到,可以换更大的 track(如 http_logs)或调整 warmup 时间比例
- cluster is not in a defined clean state 警告:被测集群上一轮的 merge/refresh 还没消停,等集群完全空闲再跑,否则索引耗时指标会有水分
- 两次跑分差异巨大:上面表格里机械盘两次结果差 4 倍,根因是页缓存。对比测试一定要控制变量:重启清缓存,或者至少保证同样的冷热状态
九、总结
esrally 上手门槛不高,一条 pip 就能装好,真正的价值在于:标准数据集 + 标准场景 + 统一指标,让"这台机器能不能扛住日志写入"这种模糊问题变成可以量化的数字。本次实测最大的收获是直观看到了磁盘类型对 ES 写入的碾压级影响------机械盘环境下的跑分波动,大到足以让任何结论失效。
你们在做 ES 容量评估时用的是什么方法?有没有踩过机械盘的大坑?欢迎评论区交流。
本文数据均为实测环境跑分,不同硬件配置结果会有差异,欢迎参考思路复测。