写入性能
服务器资源
资源 | 数值 |
---|---|
服务器 | 华为 |
系统 | centos7.9 |
cpu | Intel® Core™ i5-10500 CPU @ 3.10GHz、6核12线程 |
mem | 62G |
disk | 机械硬盘、3.6T |
单机写入性能
将es堆内存增大到20G,其余配置不做任何修改,数据单条写入。测试结果如下
线程 | 线程延迟时间(ms) | 数据量(W) | 平均响应时间(ms) | QPS |
---|---|---|---|---|
300 | 0 | 5.9 | 338 | 222 |
300 | 0 | 81 | 369 | 217 |
附件一:
附件二:
从上面测试结果来看,在不做优化前提下,es并发写入单条耗时约在360ms。这个性能相比大多数场景都已满足,不过如果项目对数据存储和周转的实时性要求高,那么还是要对写入性能做优化。
写入性能优化
方案一:业务优化
在业务上,最常见的优化手段就是变单条写入为批量写入。而es本身支持批量插入,就是bulk操作。我在第三章“Elasticsearch专栏-3.es基本用法-基础api”中也提到了bulk的使用方法。
本次测试,我的优化方式是:数据接入时,先不写库,而是直接推送到消息队列中(这里我使用的是rabbitmq)。然后监听该队列,批量拿消息。测试时,是一次拿去1000条。最后将这1000条数据批量写入es。实测结果是,1000条批量写入耗时和单条写入耗时相差不大。附图略。
除了按数量批量写入外,还可以按照时间。比如每秒写入一次,有多少数量就写入多少。其实这种方法应该更合理,像mysql底层数据和日志落盘的策略,其中就有每秒落盘一次的策略。上篇文章中,也做了图说明,有兴趣可以参考下。
方案二:底层优化
除了业务优化外,还有就是从底层优化。而底层优化,最常见的就是刷盘策略。因为我们都知道,正在的耗时就是磁盘IO。
这里我直接贴出优化的参数,如下:
参数 | 优化后值 | 含义 |
---|---|---|
index.refresh_interval | 10s | 缓存刷新时间,即10s后数据才能被搜索 |
index.translog.durability | async | 异步 |
index.translog.flush_threshold_size | 1024mb | translog大小达到多大时落盘 |
index.translog.sync_interval | 30s | translog每隔多久落盘 |
其中,效果最明显的就是index.translog.durability。它表示的是日志持久化策略,默认情况下是同步策略,即写一条数据要等日志落盘后才返回。这种效率慢,但能保证数据安全性。
将index.translog.durability改为async后,就是异步策略。数据写入缓存后,里面返回,不会等待日志是否落盘成功。这种效率很快,但数据安全性差。
测试结果如下:(后台无报错,es入库数据量和jemter发送量一致)
线程 | 线程延迟时间(ms) | 数据量(W) | 平均响应时间(ms) | QPS |
---|---|---|---|---|
500 | 100 | 1000 | 13 | 4100 |
附件:
从上面测试结果来看,改同步为异步后,写入性能有了量级的提升。这个平均耗时(13ms)和吞吐量(4100)已经相当于消息队列了。
查询性能
因为业务需要,有考虑从mysql切换到es。所以查询性能,我采用es和mysql做对比。数据量选用680w,1050w,2000w。查询内容包括:总和统计、多条件列表查询、分页查询、详情查询等多个维度。下面列出对比的数据。(数据结构和查询逻辑后续专门章节说明,本次只展示比对结果。)
1.总和统计耗时:ms
数据量 | 680w | 1050w | 2000w |
---|---|---|---|
es | 18 | 29 | 45 |
mysql | 36 | 52 | 144 |
2.近5天数量趋势统计耗时:ms
数据量 | 680w | 1050w | 2000w |
---|---|---|---|
es | 71 | 62 | 450 |
mysql | 2.7s | 4.2s | 8s |
3.分组统计耗时:ms
数据量 | 680w | 1050w | 2000w |
---|---|---|---|
es | 20 | 74 | 54 |
mysql | 2.8s | 4.3s | 8.4s |
4.es列表查询及分页耗时:ms
数据量 | 第一页 | 第10页 | 第100页 | 第1000页 |
---|---|---|---|---|
1050w | 79 | 35 | 30 | 34 |
5.详情查询耗时:ms
数据量 | 680w | 1050w | 2000w |
---|---|---|---|
es | 61 | 55 | 62 |
mysql | 37 | 35 | 60 |
从对比结果来看,es整体性能要优于mysql。总结如下:
1.数据量从百万级到千万级,对es的查询耗时影响不大,基本每次查询都在几十毫秒。但对mysql影响很大,数据量越多,查询越慢,这也符合实际情况。
2.es分页没有想象的那样,越靠后翻页越慢。整个分页查询都很稳定。
3.查询单条数据时,mysql如果走索引情况下,速度是非常快的,有可能比es都要快。
4.总的来说,es的性能和稳定性要比mysql好。无论查询条件变化如何,数据量多少,es的查询耗时都不会相差很大。
资源占用情况
cpu
线程 | 300t | 500t |
---|---|---|
es | 9% | 9% |
mysql | 64% | 112% |
随着线程的增加,mysql占用CPU明显比es高
mem
数据量 | 680w | 1050w | 2000w |
---|---|---|---|
es | 23G | 23G | 23G |
mysql | 24G | - | 48G |
随着压测数据量的增加,es内存并没有增大,而mysql增加了很多。因为mysql innodb_buff我设置的是40G,所以增加这么多内存也不难理解,都被mysql底层缓存占用了。
disk
数据量 | 680w | 1050w | 2000w |
---|---|---|---|
es | 2.1G | 2.9G | 5G |
mysql | 1.9G | 2.7G | 5.3G |
从结果来看,mysql存储数据占用磁盘还是比es多。
总结:es对cpu、mem、disk等资源占用,相比mysql来说要少。