一、简介
为了修复游标查询Bug2024年6月17日晚上20点对如下截图的ES集群进行了版本升级,从7.6.2版本升级到7.10.0,其余未做改动。Kp selection KSA ES集群节点信息:

压测目的
- 对比es集群版本7.10.0和7.6.2同等机器上的性能差异,找出性能差异的原因。
- 排除查询语句或者数据干扰等因素导致。
- 搜集压测时的ES集群日志,为后面分析改善做数据支撑。
压测 范围
Selection ES集群6台主机,配置16C/32G内存/50G磁盘,IP地址如下:
172.25.162.41
172.25.162.46
172.25.162.36
172.25.162.44
172.25.162.39
172.25.162.38
二、压测环境配置
使用Selection ES集群6台主机,硬件配置: 16C/32G/50G
第一次压测(14:10左右)
只压测了elasticsearch7.6.2集群:
使用elasticsearch.yml配置
yaml
cluster.name: kp_selection_ksa2
node.name: xnode-4
node.master : false
node.data : true
node.ingest: true
network.host: 0.0.0.0
http.port: 9201
transport.tcp.port: 9301
discovery.seed_hosts: ["172.25.162.36","172.25.162.38","172.25.162.39","172.25.162.41","172.25.162.44","172.25.162.46"]
cluster.initial_master_nodes: ["172.25.162.36","172.25.162.38","172.25.162.39"]
Java启动配置
ruby
/opt/jdk8/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dio.netty.allocator.numDirectArenas=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.locale.providers=COMPAT -Xms16g -Xmx16g -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -Djava.io.tmpdir=/tmp/elasticsearch-8691838914460001174 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/data/eslog/elasticsearch/hs_err_pid%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Xloggc:/data/eslog/elasticsearch/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=32 -XX:GCLogFileSize=64m -XX:MaxDirectMemorySize=8589934592 -Des.path.home=/data/elasticsearch-7.6.2 -Des.path.conf=/data/elasticsearch-7.6.2/config -Des.distribution.flavor=default -Des.distribution.type=tar -Des.bundled_jdk=true -cp /data/elasticsearch-7.6.2/lib/* org.elasticsearch.bootstrap.Elasticsearch -d
cluster.setting配置:
json
{
"persistent" : { },
"transient" : {
"logger" : {
"org" : {
"elasticsearch" : {
"threadpool" : "trace",
"discovery" : "trace",
"transport" : "info"
}
}
}
}
}
-
第二次压测(14:50左右)
只压测了elasticsearch7.10.0集群:
使用elasticsearch.yml配置
yaml
cluster.name: kp_selection_ksa
node.name: node-4
node.master : false
node.data : true
node.ingest: true
path.repo: ["/mnt/elasticsearch_snapshots"]
path.logs: /data/elasticsearch/log
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["172.25.162.36","172.25.162.38","172.25.162.39","172.25.162.41","172.25.162.44","172.25.162.46"]
cluster.initial_master_nodes: ["172.25.162.36","172.25.162.38","172.25.162.39"]
indices.memory.index_buffer_size: 15%
indices.queries.cache.size: 15%
Java启动配置:
ruby
/usr/share/elasticsearch/jdk/bin/java -Xshare:auto -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -XX:+ShowCodeDetailsInExceptionMessages -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dio.netty.allocator.numDirectArenas=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.locale.providers=SPI,COMPAT -Xms16g -Xmx16g -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -Djava.io.tmpdir=/tmp/elasticsearch-4290326795320379362 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/var/log/elasticsearch/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=/var/log/elasticsearch/gc.log:utctime,pid,tags:filecount=32,filesize=64m -XX:MaxDirectMemorySize=8589934592 -Des.path.home=/usr/share/elasticsearch -Des.path.conf=/etc/elasticsearch -Des.distribution.flavor=default -Des.distribution.type=rpm -Des.bundled_jdk=true -cp /usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch -p /var/run/elasticsearch/elasticsearch.pid --quiet
cluster.setting配置:
json
{
"persistent" : {
"xpack" : {
"monitoring" : {
"collection" : {
"enabled" : "true"
}
}
}
},
"transient" : {
"logger" : {
"org" : {
"elasticsearch" : {
"threadpool" : "trace",
"discovery" : "trace",
"transport" : "info"
}
}
}
}
}
-
第三次压测(16:20左右开始)
保持配置和第一次压测配置基本一致只压测了elasticsearch7.10.0集群:
使用elasticsearch.yml配置:
lua
cluster.name: kp_selection_ksa
node.name: node-4
node.master : false
node.data : true
node.ingest: true
path.repo: ["/mnt/elasticsearch_snapshots"]
path.logs: /data/elasticsearch/log
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["172.25.162.36","172.25.162.38","172.25.162.39","172.25.162.41","172.25.162.44","172.25.162.46"]
cluster.initial_master_nodes: ["172.25.162.36","172.25.162.38","172.25.162.39"]
Java启动配置:
ruby
/opt/jdk8/bin/java -Xshare:auto -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dio.netty.allocator.numDirectArenas=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.locale.providers=SPI,JRE -Xms16g -Xmx16g -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -Djava.io.tmpdir=/tmp/elasticsearch-7360855312557538579 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/var/log/elasticsearch/hs_err_pid%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Xloggc:/var/log/elasticsearch/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=32 -XX:GCLogFileSize=64m -XX:MaxDirectMemorySize=8589934592 -Des.path.home=/usr/share/elasticsearch -Des.path.conf=/etc/elasticsearch -Des.distribution.flavor=default -Des.distribution.type=rpm -Des.bundled_jdk=true -cp /usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch -p /var/run/elasticsearch/elasticsearch.pid --quiet
cluster.setting配置:
json
{
"persistent" : { },
"transient" : {
"logger" : {
"org" : {
"elasticsearch" : {
"threadpool" : "trace",
"discovery" : "trace",
"transport" : "info"
}
}
}
}
}
-
第四次压测(16:41左右开始)
保持和第三次压测相同的配置参数,只是增加了QPS压力。
附加配置参数
四次都已开启慢查日志
bash
PUT /_all/_settings
{
"index.search.slowlog.threshold.query.warn": "1s",
"index.search.slowlog.threshold.query.info": "7ms",
"index.search.slowlog.threshold.fetch.warn": "1s",
"index.search.slowlog.threshold.fetch.info": "7ms",
"index.indexing.slowlog.threshold.index.warn": 1s
}
-
配置差异说明
- 第二次 压测 和第一次压测的配置差异:
elasticsearch.yml中增加了优化参数,注册仓库,数据路径和log路径存在差异,侦听端口号存在差异。
makefile
注册仓库
path.repo: ["/mnt/elasticsearch snapshots"]
#索引查询优化参数
indices.memory.index_buffer_size: 15%
indices.queries.cache.size: 15%
JVM配置差异:使用的是openjdk14,主要差异已标注颜色

cluster.setting配置,比第一次增加如下配置:
json
{
"persistent" : {
"xpack" : {
"monitoring" : {
"collection" : {
"enabled" : "true"
}
}
}
}
- 第三次 压测 和第一次压测的配置差异:
elasticsearch.yml配置差异:配置上使用颜色标准差异,查看只有注册仓库,数据路径和log路径存在差异,侦听端口号存在差异。

JVM配置差异:配置上使用颜色标准差异,查看如下只有log路径差异

cluster.setting配置无差异
- 第四次和第三次无配置差异
三、压测使用场景
压测的查询语句
暂时无法在飞书文档外展示此内容
TPS配置
(本次测试前端压测参数TPS:6600)

数据量
数据量使用566MB,索引数调用4个索引

perl
[root@KSSHMW149699 ~]# curl http://172.25.162.41:9201/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open sph_city_district_takeout_yumc_ks_20240628_0405 hNg1q2SXTle1rPNF4AICIQ 1 5 3274 0 4.8mb 884.7kb
green open sph_store_takeout_yumc_ks_20240628_0510 EdAGOmgzRRaRl4TW6Xf8YQ 1 5 33577 822 328mb 54.6mb
green open sph_merchant_yumc_ks_20240628_0405 CnGITBzJSoOHTf-cRqblvw 1 5 524 0 418.5kb 69.7kb
green open coupon_activity_yumc_ks_20240628_0212 Mp9iVNPLTbOin9Z662bh2Q 1 5 7275 0 233.1mb 38.8mb
green open sph_market_takeout_yumc_ks_20240628_0405 BDLnlSxGSjiYJjQ3qrQV6g 1 5 23 0 35.6kb 5.9kb
[root@KSSHMW149699 ~]#
-
时间段
28号的4个时间段14:10分,14:50分, 16:20分,16:41分,只有压测场景,没有其他业务在使用宿主机。排除多场景同时发生导致压测数据不准。
四、压测结果对比
第一次压测(14:10左右)
7.6.2版本 ES 的监控
- CPU使用率

- QPS

- 任务队列

- 网络IO

- 集群平均查询耗时(query)

第二次压测(14:50左右)
7.10版本 ES 的监控
- CPU使用率

- QPS

- 任务队列

- 网络IO

- 集群平均查询耗时(query)

第三次压测(16:20左右开始)
7.10版本 ES 的监控
- CPU使用率

- QPS

- 任务队列

- 网络IO

- 集群平均查询耗时(query)

第四次压测(16:41左右开始)
7.10版本 ES 的监控
- CPU使用率

- QPS

- 任务队列

- 网络IO

- 集群平均查询耗时(query)

压测数据对比
峰值CPU使用率 | 峰值QPS | 峰值fetch查询延迟率 | 峰值任务队列 | 峰值网络IO | 备注 | |
---|---|---|---|---|---|---|
第一次压测 | 24.6% | 9.02K | 417μs | 2 | 78MiB | 没有继续往更高QPS进行压测 |
第二次压测 | 42.4% | 8.62K | 7.08ms | 14 | 77MiB | 增加索引缓存配置,和第一次压测JDK环境不一致 |
第三次压测 | 45.8% | 8.63K | 1.43ms | 5 | 76MiB | 删除 X-Pack 监控,配置文件和第一次压测配置几乎一致,JDK环境也和第一次压测一致 |
第四次压测 | 50.9% | 8.95K | 6.25ms | 305 | 79MiB | 和第三次压测一样的配置,只是增加QPS压力 |
五、压测分析
- 4次压测均采用了相同的索引数据,相关的查询语法,表现结果不符合预期,可以排除了数据查询干扰或者语法使用导致的结果异常。索引数据参考如下:
perl
[root@KSSHMW149699 ~]# curl http://172.25.162.41:9201/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open sph_city_district_takeout_yumc_ks_20240628_0405 hNg1q2SXTle1rPNF4AICIQ 1 5 3274 0 4.8mb 884.7kb
green open sph_store_takeout_yumc_ks_20240628_0510 EdAGOmgzRRaRl4TW6Xf8YQ 1 5 33577 822 328mb 54.6mb
green open sph_merchant_yumc_ks_20240628_0405 CnGITBzJSoOHTf-cRqblvw 1 5 524 0 418.5kb 69.7kb
green open coupon_activity_yumc_ks_20240628_0212 Mp9iVNPLTbOin9Z662bh2Q 1 5 7275 0 233.1mb 38.8mb
green open sph_market_takeout_yumc_ks_20240628_0405 BDLnlSxGSjiYJjQ3qrQV6g 1 5 23 0 35.6kb 5.9kb
[root@KSSHMW149699 ~]#
- 第二次增加了索引查询缓存优化配置
indices.queries.cache.size: 15%
,表现结果不符合预期,排除查询缓存优化可以大幅提升QPS查询性能。 3. 第三次的压测使用配置几乎和第一次的配置一样,关闭es的monitoring监控

图下查看monitoring监控慢日志一台机器日志采集1分钟大概几十次,QPS压力较小

JDK环境也从openjdk14版本换成java1.8版本进行压测

启动时还是存在部分参数与第一次压测有差异,主要差异已备注颜色如下图:

上图中 -Xshare:auto
通常在多个 JVM 实例需要加载相同的类时可以提高效率,因为它们可以共享一些基础的类数据,从而减少了每个 JVM 实例的内存占用和提高了启动速度。SPI, JRE
:此选项指示 JVM 使用服务提供接口 (Service Provider Interface
, SPI) 和 Java 运行环境自带的本地化数据。JVM 会首先查找第三方提供的本地化数据,如果没有找到,再回退到自带的 JRE 数据,如上参数对qps的影响还需要后续评估。表现结果不符合预期,排除JDK版本环境和监控采集数据Qps影响。
- 第四次压测保持和第三次压测同样的配置,16:41时加大QPS后进行了压测,结果ES集群的压力骤增。7.10版本瓶颈复现,ES集群中的QPS达到9000左右时,查询任务队列增大,查询延迟时间增加。
六、结论
- 同等资源配置下、elasticsearch.yml配置只开启如下参数:
yaml
#__xxxxx__表示可变
cluster.name: __xxxxx__
node.name: __xxxxx__
node.master : __xxxxx__
node.data : true
node.ingest: true
path.repo: __xxxxx__
path.logs: __xxxxx__
network.host: 0.0.0.0
http.port: __xxxxx__
transport.tcp.port: __xxxxx__
discovery.seed_hosts: __xxxxx__
cluster.initial_master_nodes: __xxxxx__
JVM配置文件只开启如下参数:
ruby
#__xxxxx__表示可变
-Xms16g
-Xmx16g
8-:-XX:+UseG1GC
8-:-XX:G1ReservePercent=25
8-:-XX:InitiatingHeapOccupancyPercent=30
-Djava.io.tmpdir=${ES_TMPDIR}
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=__xxxxx__
-XX:ErrorFile=__xxxxx__
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:__xxxxx__
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m
9-:-Xlog:gc*,gc+age=trace,safepoint:file=__xxxxx__:utctime,pid,tags:filecount=32,filesize=64m
其他配置默认的情况下,同等QPS下(压测工具QPS指标),ES7.6.2版本的性能和稳定性均优于7.10版本,7.6.2版本有着更低的CPU使用率,任务队列中积压得更少,QPS更优。QPS在8500-8900之间时两个版本的cpu性能有20%左右的差距。
- 7.10.0版本比7.6.2版本更新了很多索引搜索和安全等功能,如:新增异步搜索 API ,在x-pack basic中引入时间点api等。 可能底层实现和优化策略的变化导致CPU使用率和QPS测试不一致的情况,需要后续去调整相关参数再次验证。
七、建议
- 目前业务使用7.10.0版本是否满足qps等要求,如不满足建议回退至7.6.2版本的elasticsearch集群。
- 调研版本性能差异的原因,为后续改进和优化elasticsearch集群配置提供参考。
- 7.6.2版本有游标查询Bug,可以使用脚本探测bug是否出现,出现后及时处理bug。
参考资料
略