ES写入毛刺问题?从原理到调优

简介: ES是一个非常完善的搜索引擎,可以用于业务搜索、数据分析,其周边生态产品也十分丰富;正是由于ES的完善与通用性,用户使用ES的场景越来越多样化,通用的配置已经无法达到用户的稳定性需求,并且难以给出通用的最佳实践,需要专门的为某些场景进行调优。例如,update频繁的场景下的性能调优。

ES是一个非常完善的搜索引擎,可以用于业务搜索、数据分析,其周边生态产品也十分丰富;
正是由于ES的完善与通用性,用户使用ES的场景越来越多样化,通用的配置已经无法达到用户的稳定性需求,并且难以给出通用的最佳实践,需要专门的为某些场景进行调优。
例如,update频繁的场景下的性能调优。

ES的使用场景

1.在线搜索(垂直搜索+全文检索)
2.数据分析与日志
ES最初设计的就是一个搜索引擎,对全文检索更是“擅长”,准确且简单;后面由于性能的不断提升,集群规则的扩大,使得ES在OLAP(数据分析)场景也有很大的发挥空间;
无论是在线搜索还是数据分析,其使用场景依然是一个“上层”,并不作为一个最底层的数据源,数据链路依然是从DB数据源--->ES,这也是比较推荐的使用方式。
ES不是数据库,没有事务、不保证任何情况下都不会丢失数据(数据先写lucene再写translog),以及近实时的特性,ES并不非常适合极其频繁的update场景。尽管如此,ES依然允许被这样使用,只是需要进行一些调优;
image.png

问题是什么?

有用户提出,update接口偶尔(一天3-4次)会出现请求耗时很高(1s+)的情况;
监控观察下来并没有在异常请求的时间点出现不正常的现象。
请求链路:用户service->gateway->ES集群实例
从日志看下来,时间主要用在从gateway发送请求到gateway得到ES的响应;由于是update请求,不会存在大量的网络IO,所以问题大概率出现在ES处理请求上。

分析

1.由于是频繁的update请求,很容易发现有大量的is_deleted文件,该现象主要影响查询性能,可通过forcemerge处理,实验下来对update毛刺没有任何影响,符合预期。(补充:segment过多也会影响查询性能,由于每个分片单独merge,出现的segment在某些分片上过多的情况也会造成查询的毛刺)

2.用户根据我们提供的“最佳实践”文档,计算出了主副分片的设置,由于数据量不大,最终算出来是primary=1,replica=4,于是update场景下副本数过多,更容易造成长尾效应
image.png
可以看到update的耗时等于node1上主分片update的耗时加上node2,node3,node4,node5中耗时的最大值。这样副本越多也就越容易出现长尾效应。
这里再提一点:wait_for_active_shards参数经常被误认为是控制写入请求同步分片的数量(认为在wait_for_active_shards=2的时候只需要等待1主+任意一个副本返回成功,即可响应给客户端)。实际上该参数表示需要写入成功wait_for_active_shards个分片才算写入成功。可以看到该参数默认是1,也就是说只要写入主分片成功就算此次请求成功,但是依然需要等待所有副本都响应了,才能返回客户端。
该参数是用来保证数据不丢失的,例如wait_for_active_shards=2,需要至少写入1主1副才算此次请求成功,这样一致性会更高,但相应的写入性能会更差。

3.translog同步顺序写,在translog清空、翻滚的时候会有writeLock,也可能造成等待,导致update请求出现毛刺。可以将translog设置成异步,相应的异步丢数据的可能性就会增加。

4.官方推荐使用SSD,且esrally测试结果普通SSD在大多场景下都表现比HDD好(成本问题没有考虑Nvme)。目前该用户集群使用HDD,调整成SSD。

5.之前有看到文章描述当使用BulkShardRequest时,ES的定期refresh的过程中可能出现write线程帮助refresh线程进行refresh的情况,从而导致write线程堵塞。该场景本文没有实际验证过。

问题解决

通过观察毛刺出现的频率,大概是每小时出现一波;
image.png

发现translog是同步的,且软删除保留的是1h得到translog

"soft_deletes":{
  "retention_lease":{
    "period": "1h"
  }
}

修改后问题解决:

# 1.改成异步
"translog": {
  "sync_interval": "60s",
  "durability": "async"
}

# 2.soft_deletes配置删除(即使用默认的,也就是12h)

修改完成后:
image.png

最后

如有描述不准确的地方欢迎指正~
有其他思路欢迎补充~

相关文章
|
程序员 Linux Ruby
Mac安装并使用telnet命令操作
Mac安装并使用telnet命令操作
16417 1
Mac安装并使用telnet命令操作
|
监控 Java 索引
ES 生产中10个常见参数阈值(默认最大值)操作及优化解决方案
ES 生产中10个常见参数阈值(默认最大值)操作及优化解决方案
ES 生产中10个常见参数阈值(默认最大值)操作及优化解决方案
|
4月前
|
域名解析 应用服务中间件 Shell
使用nps配置内网穿透加域名解析
使用nps配置内网穿透加域名解析
585 76
|
9月前
|
存储 缓存 监控
极致 ElasticSearch 调优,让你的ES 狂飙100倍!
尼恩分享了一篇关于提升Elasticsearch集群的整体性能和稳定性措施的文章。他从硬件、系统、JVM、集群、索引和查询等多个层面对ES的性能优化进行分析,帮助读者提升技术水平。
Elasticsearch 查看磁盘占用 查看指定索引磁盘占用
【7月更文挑战第2天】Elasticsearch 查看磁盘占用 查看指定索引磁盘占用
|
缓存 分布式计算 算法
优化Hadoop MapReduce性能的最佳实践
【8月更文第28天】Hadoop MapReduce是一个用于处理大规模数据集的软件框架,适用于分布式计算环境。虽然MapReduce框架本身具有很好的可扩展性和容错性,但在某些情况下,任务执行可能会因为各种原因导致性能瓶颈。本文将探讨如何通过调整配置参数和优化算法逻辑来提高MapReduce任务的效率。
1198 0
|
前端开发 Java iOS开发
elasticsearch8.1源码编译笔记
elasticsearch8.1源码编译笔记
233 0
|
Arthas Java 测试技术
ES7.5升级7.17后在写多读少场景下CPU、IO飙升
ES PAAS管理的集群升级了100+,从7.5升级到7.17 (保证每个大版本最终仅维护一个小版本集群),由于业务使用差异大,也出了不少问题,前面的文章也有提到过Integer类型字段使用terms查询效率低的情况...
473 0
ES7.5升级7.17后在写多读少场景下CPU、IO飙升
|
数据库
探究 | Elasticsearch CPU高排查思路
Elasticsearch CPU高排查思路的探究思路。
6086 1
|
SQL 分布式计算 Hadoop