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

最后

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

相关文章
|
6月前
|
Kubernetes 调度 容器
K8S 性能优化 -K8S Node 参数调优
K8S 性能优化 -K8S Node 参数调优
|
6月前
|
分布式计算 算法 Spark
Spark中的性能优化有哪些方法?请举例说明
Spark中的性能优化有哪些方法?请举例说明
96 1
|
前端开发 API
ES 高级实战(四)查询 ES 数据
ES 高级实战(四)查询 ES 数据
1386 0
ES 高级实战(四)查询 ES 数据
|
3月前
|
存储 Kubernetes 监控
在K8S中,ELK是如何实现及如何优化的ES?
在K8S中,ELK是如何实现及如何优化的ES?
|
4月前
|
API 索引
面试题ES问题之使用分词器提高写入效率如何解决
面试题ES问题之使用分词器提高写入效率如何解决
38 1
|
11月前
|
网络架构
ES6学习(六)—函数的扩展
ES6学习(六)—函数的扩展
ES文档写入原理
ES文档写入原理
97 0
ES文档写入原理
|
Java 数据库
ES深度分页问题解决方案
ES深度分页问题
314 0
|
存储 缓存 自然语言处理
ES 优化概述|学习笔记
快速学习 ES 优化概述。
234 0
|
数据采集 搜索推荐 数据可视化
ES 工作原理|学习笔记
快速学习 ES 工作原理。
147 0
ES 工作原理|学习笔记