IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Elasticsearch不同版本的压力测试与结果对比

    Derobukal发表于 2023-11-11 04:55:35
    love 0

    公司目前所使用的Elasticsearch(以下简称ES)版本是在2015年的时候选择的,当时选择了ES的最新版本1.5.2。随着ES官方的快速发展,ES也已经推出了很多新的版本,这些新版本往往伴随着一些新特性的发布以及性能的提升,为了使用到这些新特性,我们决定将ES的版本升级到7.5.2。

    ES版本升级会遇到API不兼容的问题,我们的解决办法是在业务和ES之间增加一层_搜索平台_来做接口兼容。此外我们在版本升级之前还需要了解一下ES-7.5.2相对于ES-1.5.2有多少性能提升,所以我们需要针对这两个版本做一下性能测试并对结果进行对比。我们使用如下的四台负载来做性能测试

    序号节点IPCPU型号CPU核数内存硬盘操作系统
    1172.19.66.58Intel(R) Xeon(R) CPU E5645 @2.40GHz23079520kB14GGNU/Linux 3.10.0-957.21.3.el7.x86_64
    2172.19.66.70Intel(R) Xeon(R) CPU E5645 @2.40GHz23079524kB14GGNU/Linux 3.10.0-957.21.3.el7.x86_64
    3172.19.66.77Intel(R) Xeon(R) CPU E5645 @2.40GHz23079524kB14GGNU/Linux 3.10.0-957.21.3.el7.x86_64
    4172.19.66.133Intel(R) Xeon(R) CPU E5645 @2.40GHz23079524kB14GGNU/Linux 3.10.0-957.21.3.el7.x86_64

    使用time和dd命令测试负载的磁盘性能

    # 测试磁盘的写入性能time dd if=/dev/zero of=test.data bs=8k count=10000 oflag=direct# 测试磁盘的读取性能time dd if=test.data of=/dev/null bs=8k count=10000 iflag=direct

    通过测试可知以上四台负载的磁盘读写性能基本一致。

    压测前的环境准备

    创建索引和数据

    1号和2号节点安装ES-1.5.2集群,3号和4号节点安装ES-7.5.2集群。两个集群各自的两个节点均设置为master-eligible和data节点,并且JVM的堆内存都设置为1GB。分别向两个集群写入相同的测试数据112万条,对于text类型两个集群都使用ES默认的分词器。两个集群的两个索引的mapping基本上一致,我把1.5.2和7.5.2这两个索引的mapping都放在了gist上面以供参考。

    创建压测环境

    我们使用 ApacheBench (ab) 来实现压测功能,为了方便操作我们利用ab实现了一个测试脚本 test.sh,在测试脚本中我们使用了query.json文件中的ES查询DSL来实现ES不同类型查询的性能测试,后面我们会修改query.json文件中的DSL来实现不同的查询测试。

    进行压测

    压测使用的客户机为MacBookPro,客户机和ES集群位于同一个局域网,因此可以保证网络带宽不会成为瓶颈。客户机的具体配置如下

    macOs Catalina 10.15.4 (19E287)MacBook Pro (Retina, 13-inch, Early 2015)2.7 GHz Dual-Core Intel Core i58 GB 1867 MHz DDR3

    具体的测试结果如下,我们修改query.json的DSL来实现不同类型操作的测试。

    term-level

    term
    1
    2
    3
    4
    5
    6
    7
    8
    {
    "query": {
    "term": {
    "acctId": "A00000000000"
    }
    },
    "size": 0
    }

    修改query.json的内容如上并且执行命令

    ./test.sh

    随后我们可以得到脚本的执行结果,因为执行结果内容比较多所以我们只挑一些关键性的部分进行了解。完整的执行结果可以在 gist上面 看到。

    Elasticsearch-1.5.2 >>> 172.19.66.70Requests per second:    165.87 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     34366%     39975%     42180%     45490%     54795%     62098%     68799%     784100%    905 (longest request)Elasticsearch-7.5.2 >>> 172.19.66.77Requests per second:    1049.51 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     5366%     6175%     6880%     7390%     8795%     10098%     11899%     129100%    202 (longest request)

    可以看到在并发为60的情况下,执行压测10秒钟,1.5.2的QPS为165.87,7.5.2的QPS为1049.51,此外7.5.2的99%的请求耗时都是在130ms以下的,由此可以证明7.5.2相较于1.5.2在term查询上确实有很大的性能提升。

    range

    query.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "query": {
    "range": {
    "createdTimeStr": {
    "gte": "2020-01-01T00:00:00.000+0800"
    }
    }
    },
    "size": 0
    }

    性能测试结果

    Elasticsearch-1.5.2 >>> 172.19.66.70Requests per second:    1237.86 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     4566%     5275%     5880%     6290%     7595%     8598%     10199%     113100%    189 (longest request)Elasticsearch-7.5.2 >>> 172.19.66.77Requests per second:    1099.03 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     4766%     5475%     5980%     6390%     7595%     8698%     10299%     120100%    166 (longest request)

    可以看出7.5.2在range查询上有一定的性能提升,但是提升并不明显。

    match

    query.json

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "query": {
    "match": {
    "userName.analyzed": "江苏千米"
    }
    },
    "size": 0
    }

    性能测试结果

    Elasticsearch-1.5.2 >>> 172.19.66.70Requests per second:    789.62 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     7466%     9275%     10780%     11590%     13295%     14898%     16999%     187100%    336 (longest request)Elasticsearch-7.5.2 >>> 172.19.66.77Requests per second:    1229.56 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     4466%     5275%     5780%     6290%     7295%     8598%     10799%     135100%    275 (longest request)

    由上面的结果可见7.5.2对match查询也是有一定的性能提升的。

    aggregation操作

    metrics

    query.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "aggs": {
    "balance_stats": {
    "extended_stats": {
    "field": "balance"
    }
    }
    },
    "size": 0
    }

    性能测试结果

    Elasticsearch-1.5.2 >>> 172.19.66.70Requests per second:    32.67 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%    183866%    193875%    197080%    197290%    242795%    255598%    259799%    3486100%   3806 (longest request)Elasticsearch-7.5.2 >>> 172.19.66.77Requests per second:    1393.98 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     4166%     4875%     5380%     5690%     6595%     7498%     8499%     93100%    141 (longest request)

    7.5.2在指标聚合上的速度提升也十分的可观。

    bucket

    query.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
    "aggs": {
    "typeName": {
    "terms": {
    "field": "balanceTypeName",
    "size": 50
    }
    }
    },
    "size": 0
    }

    性能测试结果

    Elasticsearch-1.5.2 >>> 172.19.66.70Requests per second:    79.98 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%    72166%    101575%    117180%    125890%    148895%    157198%    160099%    1618100%   1643 (longest request)Elasticsearch-7.5.2 >>> 172.19.66.77Requests per second:    1629.80 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     3466%     4075%     4580%     4890%     5795%     6598%     7799%     86100%    153 (longest request)

    7.5.2在桶聚合上也有着很好的性能优化效果。

    小结

    从上面的term、range、match、metric、bucket的测试结果中我们可以看到,除了range之外其余的几个DSL在7.5.2都有了较大的性能提升。但是我们也要清醒地认识到,我们在上面的单次性能测试中使用的都是完全一样的DSL,这就可能会使得ES中的缓存生效,因此该性能测试可能无法完全展现出真实环境中的ES性能,因为在真实环境中ES的缓存可能并不能像这里测试的这样完美的生效。

    此外,由于这里的机器资源有限,我们只能做一个简单的性能对比实验,证明7.5.2的性能确实是优于1.5.2的。真正的ES-7.5.2集群的性能极限还要等到_搜索平台_的兼容性测试完成后,这时候我们可以搭建一个真正的生产环境的7.5.2集群,然后对此集群进行极限压测,等后面做了我会再做一份笔记。

    数据写入的性能测试

    上面我们测试了ES的数据检索和聚合的性能,下面我们也对ES的数据写入性能做一个测试。创建data.json并保存如下的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    {
    "id": 86523,
    "name": "普通高等教育“十一五”国家级规划教材配套参考书:电工电子学学习辅导与习题解答(第3版)",
    "publish": "高等教育出版社",
    "author": "张伯尧,叶挺秀",
    "info": "《电工电子学学习辅导与习题解答(第3版)》",
    "price": 86.9,
    "createdTimeStr": "2020-01-01T12:00:00.000+0800",
    "createdTime": 1547873713709,
    "type": "college",
    "sellOut": false,
    "students": [
    {
    "name": "王博文",
    "class": 1
    },
    {
    "name": "徐晓静",
    "class": 2
    },
    {
    "name": "路小楠",
    "class": 1
    }
    ]
    }

    使用ab测试1.5.2的集群写入性能

    ab -n 50000 -c 200 -p data.json -T 'application/json' http://172.19.66.70:9200/books/Book

    性能报告如下

    Time taken for tests:   26.680 secondsRequests per second:    1874.06 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     7266%     8575%     9580%     10190%     12395%     14798%     123699%     1276100%    3652 (longest request)

    使用ab测试7.5.2的集群写入性能

    ab -n 50000 -c 200 -p data.json -T 'application/json' http://172.19.66.77:9200/books/_doc

    性能报告如下

    Time taken for tests:   103.203 secondsRequests per second:    484.48 [#/sec] (mean)Percentage of the requests served within a certain time (ms)50%     34466%     38775%     43880%     47890%     61595%     73998%     97999%     1097100%    2436 (longest request)

    很奇怪的是ES-7.5.2的数据写入性能明显低于ES-1.5.2,为了规避掉机器之间的细微的差异,我把ES-7.5.2安装在节点1和节点2之上,之后停止ES-1.5.2集群同时启动ES-7.5.2集群,然后把数据写到新的7.5.2的集群中去,测试结果和上面还是基本一致。具体原因暂时还不清楚,后面再做进一步的深入了解。

    数据写入慢的原因

    我们删除上面的测试中所创建的books索引,之后给每个索引只创建一条文档

    ab -n 1 -c 1 -p data.json -T 'application/json' http://172.19.66.70:9200/books/Bookab -n 1 -c 1 -p data.json -T 'application/json' http://172.19.66.77:9200/books/_doc

    只写入一条数据我们发现1.5.2也是快于7.5.2的集群的,之后我们使用如下接口观察我们写入的数据的段文件情况,首先是1.5.2集群

    http://172.19.66.70:9200/books/_segments

    得到1.5.2的段文件信息如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    {
    "_shards": {
    "total": 4,
    "successful": 4,
    "failed": 0
    },
    "indices": {
    "books": {
    "shards": {
    "0": [
    {
    "routing": {
    "state": "STARTED",
    "primary": true,
    "node": "Fn-qbetJSyS7Qn6qb8rcaQ"
    },
    "num_committed_segments": 1,
    "num_search_segments": 1,
    "segments": {
    "_0": {
    "generation": 0,
    "num_docs": 1,
    "deleted_docs": 0,
    "size_in_bytes": 9870,
    "memory_in_bytes": 12898,
    "committed": true,
    "search": true,
    "version": "4.10.4",
    "compound": true
    }
    }
    },
    {
    "routing": {
    "state": "STARTED",
    "primary": false,
    "node": "PvI9366jTQKbFXWF2HRg6w"
    },
    "num_committed_segments": 1,
    "num_search_segments": 1,
    "segments": {
    "_0": {
    "generation": 0,
    "num_docs": 1,
    "deleted_docs": 0,
    "size_in_bytes": 9870,
    "memory_in_bytes": 12898,
    "committed": true,
    "search": true,
    "version": "4.10.4",
    "compound": true
    }
    }
    }
    ],
    "1": [
    {
    "routing": {
    "state": "STARTED",
    "primary": false,
    "node": "Fn-qbetJSyS7Qn6qb8rcaQ"
    },
    "num_committed_segments": 0,
    "num_search_segments": 0,
    "segments": {}
    },
    {
    "routing": {
    "state": "STARTED",
    "primary": true,
    "node": "PvI9366jTQKbFXWF2HRg6w"
    },
    "num_committed_segments": 0,
    "num_search_segments": 0,
    "segments": {}
    }
    ]
    }
    }
    }
    }

    从上面的结果中我们可以看到这条文档被保存到了books索引的0号分片中,这个分片包含了primary和replica两份数据,1号分片中的数据则为空。我们可以看到0号分片的主备两个分片的 segments.size_in_bytes 的值均为9870,这代表了segment在磁盘上占用的空间大小。

    了解了以上信息之后,我们继续获得7.5.2的段文件信息

    http://172.19.66.77:9200/books/_segments

    得到的7.5.2的段文件信息如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    {
    "_shards": {
    "total": 4,
    "successful": 4,
    "failed": 0
    },
    "indices": {
    "books": {
    "shards": {
    "0": [
    {
    "routing": {
    "state": "STARTED",
    "primary": true,
    "node": "sLtK-N1eSFiGNV7PeA1ntg"
    },
    "num_committed_segments": 0,
    "num_search_segments": 0,
    "segments": {}
    },
    {
    "routing": {
    "state": "STARTED",
    "primary": false,
    "node": "HNJ8oebqSRGO6C9YJbjCFA"
    },
    "num_committed_segments": 0,
    "num_search_segments": 0,
    "segments": {}
    }
    ],
    "1": [
    {
    "routing": {
    "state": "STARTED",
    "primary": false,
    "node": "sLtK-N1eSFiGNV7PeA1ntg"
    },
    "num_committed_segments": 0,
    "num_search_segments": 1,
    "segments": {
    "_0": {
    "generation": 0,
    "num_docs": 1,
    "deleted_docs": 0,
    "size_in_bytes": 11863,
    "memory_in_bytes": 5007,
    "committed": false,
    "search": true,
    "version": "8.3.0",
    "compound": true,
    "attributes": {
    "Lucene50StoredFieldsFormat.mode": "BEST_SPEED"
    }
    }
    }
    },
    {
    "routing": {
    "state": "STARTED",
    "primary": true,
    "node": "HNJ8oebqSRGO6C9YJbjCFA"
    },
    "num_committed_segments": 0,
    "num_search_segments": 1,
    "segments": {
    "_0": {
    "generation": 0,
    "num_docs": 1,
    "deleted_docs": 0,
    "size_in_bytes": 11863,
    "memory_in_bytes": 5007,
    "committed": false,
    "search": true,
    "version": "8.3.0",
    "compound": true,
    "attributes": {
    "Lucene50StoredFieldsFormat.mode": "BEST_SPEED"
    }
    }
    }
    }
    ]
    }
    }
    }
    }

    7.5.2集群的books索引的文档分配在了分片1上,同样分片1也包含了主副两个分片。我们可以看到7.5.2的段文件占用的磁盘空间为11863,比1.5.2的9870要大一些,这是为什么呢?按道理来说Lucene从版本4.10.4升级到版本8.3.0,占用空间应该有一定程度上的优化才对,至少也不应该是占用空间变大了啊。

    通过查找资料,我们可以知道在新版本的Elasticsearch中,为了优化ES的排序和聚合的速度而引入了Doc values属性,该属性是在文档索引时生成的,目的是为了替代以前在文档查询时才生成的Fielddata属性。

    我们可以对字段的mapping属性添加

    "doc_values": false

    这样可以禁用字段的doc_values属性,在禁用了7.5.2的字段的doc_values之后,段文件占用空间明显减小,索引速度也有明显的提升。

    BUT!!!

    通过以上的配置之后,7.5.2的数据索引速度仍然只是1.5.2的一半😶,具体原因还需进一步的分析😢。

    5月19日补充:

    关闭两个集群的refresh_interval(关闭自动refresh之后,写入到索引的数据不会被查询到,除非手动的执行了refresh操作之后才可以)

    PUT /books/_settings{    "refresh_interval": -1}

    同时关闭7.5.2的doc_values,并且只保存了long类型的数据以避免分词器的影响,之后测试结果发现仍然是7.5.2的时间更长。不过此时我们使用如下的接口查询索引的详细信息

    GET /books/_stats

    可以发现两个索引的 indexing.index_time_in_millis 的值其实是一样呢,这是为啥呢。。。

    参考

    Apache Bench 安装与使用
    性能测试应该怎么做?

    滴滴 ElasticSearch 平台跨版本升级以及平台重构之路
    https://www.elastic.co/guide/en/elasticsearch/reference/7.5/query-dsl.html
    https://www.elastic.co/guide/en/elasticsearch/reference/7.5/search-aggregations.html



沪ICP备19023445号-2号
友情链接