一起学Elasticsearch系列-写入和检索调优

这篇具有很好参考价值的文章主要介绍了一起学Elasticsearch系列-写入和检索调优。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文已收录至Github,推荐阅读 👉 Java随想录
微信公众号:Java随想录


当涉及到大规模数据存储和检索时,Elasticsearch以其快速、高效和强大的搜索能力而闻名,并被广泛应用于各种场景,例如日志分析、全文搜索和实时数据分析。

然而,并不是只要将数据存入ES就可以立即获得最佳性能和查询效率。正如任何强大的工具一样,ES也需要进行调优,以充分发挥其潜力并满足特定业务需求。

在这篇文章中,我们将探讨ES写入调优和查询调优的关键方面,并提供一些实用的技巧和建议,帮助您优化ES集群的性能和响应速度。

写入调优

基本原则

写入性能调优是建立在 Elasticsearch 的写入原理之上的。

ES 数据写入具有一定的延时性,这是为了减少频繁的索引文件产生。默认情况下 ES 每秒生成一个 Segment 文件,当达到一定阈值的时候会执行merge,merge 过程发生在 JVM中,频繁的生成 Segmen 文件可能会导致频繁的触发 FGC,导致 OOM。

为了避免这种情况,通常采取的手段是降低 Segment 文件的生成频率,办法有两个:一个是增加时间阈值,另一个是增大Buffer的空间阈值,因为缓冲区写满也会生成 Segment 文件。

生产经常面临的写入可以分为两种情况:

高频低量:高频的创建或更新索引或文档,一般发生在 C 端业务场景下。

低频高量:一般情况为定期重建索引或批量更新文档数据。

在搜索引擎的业务场景下,用户一般并不需要那么高的写入实时性。比如你在网站发布一条征婚信息,或者二手交易平台发布一个商品信息。其他人并不是马上能搜索到的,这其实也是正常的处理逻辑。

这个延时的过程需要处理很多事情,比如:你的信息需要后台审核。

你发布的内容在搜索服务中需要建立索引,而且你的数据可能并不会马上被写入索引,而是等待要写入的数据达到一定数量之后,批量写入。

这种操作优点类似于我们快递物流的场景,只有当快递数量达到一定量级的时候,比如能装满整个车的时候,快递车才会发车。因为反正是要跑一趟,装的越多,平均成本越低。

这和我们数据写入到磁盘的过程是非常相似的,我们可以把一条文档数据看做是一个快递,而快递车每次发车就是向磁盘写入数据的一个过程,这个过程不宜太多,太多只会降低性能,就是体现在运输成本上面,而对于我们数据写入而言就是体现在我们硬件性能损耗上面。

优化手段

以下为常见数据写入的调优手段,写入调优均以提升写入吞吐量和并发能力为目标,而非提升写入实时性。

增加 flush 时间间隔

flush的过程是非常消耗资源的。增加flush的时间间隔目的是减小数据写入磁盘的频率,降低磁盘IO频率。

增加 refresh_interval 参数的值

增加 refresh_interval 参数的值,目的是减少segment文件的创建,降低merge次数,因为merge是发生在jvm中的,有可能导致full GC。

ES的 refresh 行为非常昂贵,并且在正在进行的索引活动时经常调用,会降低索引速度。

默认情况下,Elasticsearch 每秒定期刷新索引,如果没有搜索流量或搜索流量很少(例如每 5 分钟不到一个搜索请求),可以适当调大此参数的值。

增加Buffer大小

本质也是减小refresh的时间间隔,因为导致segment文件创建的原因不仅有时间阈值,还有buffer空间大小,写满了也会创建。 默认值为JVM 空间的10%。

关闭副本

当需要单次写入大量数据的时候,建议关闭副本,暂停搜索服务,或选择在检索请求量谷值区间时间段来完成。

关闭副本可以带来如下好处:

  • 减小读写之间的资源抢占,读写分离。
  • 当检索请求数量很少的时候,可以减少甚至完全删除副本分片,关闭segment的自动创建以达到高效利用内存的目的,因为副本的存在会导致主从之间频繁的进行数据同步,大大增加服务器的资源占用。

具体可通过设置index.number_of_replicas 为0以加快索引速度。没有副本意味着丢失单个节点可能会导致数据丢失,因此数据保存在其他地方很重要,以便在出现问题时可以重试初始加载。初始加载完成后,可以设置index.number_of_replicas改回其原始值。

禁用swap

大多数操作系统尝试将尽可能多的内存用于文件系统缓存,并急切地换掉未使用的应用程序内存。这可能导致部分 JVM 堆甚至其可执行页面被换出到磁盘。

交换对性能和节点稳定性非常不利,应该不惜一切代价避免。它可能导致垃圾收集持续几分钟而不是几毫秒,并且可能导致节点响应缓慢甚至与集群断开连接。在Elastic分布式系统中,让操作系统杀死节点更有效。

使用多个工作线程

发送批量请求的单个线程不太可能最大化 Elasticsearch 集群的索引容量。为了使用集群的所有资源,应该从多个线程或进程发送数据。除了更好地利用集群的资源外,还有助于降低每个 fsync 的成本。

确保注意 TOO_MANY_REQUESTS 响应代码:429。(EsRejectedExecutionException使用 Java 客户端),这是 Elasticsearch 告诉我们它无法跟上当前索引速度的方式。发生这种情况时,应该在重试之前暂停索引,最好使用随机指数退避。

与调整批量请求的大小类似,只有测试才能确定最佳工作线程数量是多少。这可以通过逐渐增加线程数量来测试,直到集群上的 I/O 或 CPU 饱和。

max_result_window参数

max_result_window是分页返回的最大数值,默认值为10000。max_result_window本身是对JVM的一种保护机制,通过设定一个合理的阈值,避免初学者分页查询时由于单页数据过大而导致OOM。

设置一个合理的大小是需要通过你的各项指标参数来衡量确定的,比如你用户量、数据量、物理内存的大小、分片的数量等等。通过监控数据和分析各项指标从而确定一个最佳值,并非越大越好。

查询调优

读写性能不可兼得

首先要明确一点:鱼和熊掌不可兼得。读写性能调优在很多场景下是只能二选一的。牺牲 A 换 B 的行为非常常见。索引本质上也是通过空间换取时间。牺牲写入实时性就是为了提高检索的性能。

当你在二手平台或者某垂直信息网站发布信息之后,是允许有信息写入的延时性的。但是检索不行,甚至 1 秒的等待时间对用户来说都是无法接受的。满足用户的要求甚至必须做到10 ms以内。

优化手段

避免单次召回大量数据

搜索引擎最擅长的事情是从海量数据中查询少量相关文档,而非单次检索大量文档。非常不建议动辄查询上万数据。如果有这样的需求,建议使用滚动查询

避免单个文档过大

鉴于默认http.max_content_length设置为 100MB,Elasticsearch 将拒绝索引任何大于该值的文档。您可能决定增加该特定设置,但 Lucene 仍然有大约 2GB 的限制。

即使不考虑硬性限制,大型文档通常也不实用。大型文档对网络、内存使用和磁盘造成了更大的压力,即使对于不请求的搜索请求也是如此。

有时重新考虑信息单元应该是什么是有用的。例如,您想让书籍可搜索的事实并不一定意味着文档应该包含整本书。使用章节甚至段落作为文档可能是一个更好的主意,然后在这些文档中拥有一个属性来标识它们属于哪本书。这不仅避免了大文档的问题,还使搜索体验更好。例如,如果用户搜索两个单词 fooand bar,则不同章节之间的匹配可能很差,而同一段落中的匹配可能很好。

单次查询10条文档 好于 10次查询每次一条

批量请求将产生比单文档索引请求更好的性能。但是每次查询多少文档最佳,不同的集群最佳值可能不同,为了获得批量请求的最佳阈值,建议在具有单个分片的单个节点上运行基准测试。

首先尝试一次索引 100 个文档,然后是 200 个,然后是 400 个等。在每次基准测试运行中,批量请求中的文档数量翻倍。当索引速度开始趋于平稳时,就可以获得已达到数据批量请求的最佳大小。在相同性能的情况下,当大量请求同时发送时,太大的批量请求可能会使集群承受内存压力,因此建议避免每个请求超过几十兆字节。

数据建模

很多人会忽略对 Elasticsearch 数据建模的重要性。

nested属于object类型的一种,是Elasticsearch中用于复杂类型对象数组的索引操作。Elasticsearch没有内部对象的概念,因此,ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表。

特别是,应避免Join连接。Nested 可以使查询慢几倍,Join 会使查询慢数百倍。两种类型的使用场景应该是:Nested针对字段值为非基本数据类型的时候,而Join则用于当子文档数量级非常大的时候。

给系统留足够的内存

Lucene的数据的fsync是发生在OS cache的,要给OS cache预留足够的内存大小。

预索引

利用查询中的模式来优化数据的索引方式。例如,如果所有文档都有一个price字段,并且大多数查询 range 在固定的范围列表上运行聚合,可以通过将范围预先索引到索引中并使用聚合来加快聚合速度。

使用 filter 代替 query

query和filter的主要区别在: filter是结果导向的而query是过程导向。query倾向于“当前文档和查询的语句的相关度”,而filter倾向于“当前文档和查询的条件是不是相符”。即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会。另外filter有相应的缓存机制,可以提高查询效率。

避免深度分页

避免单页数据过大,可以参考百度或者淘宝的做法。es提供两种解决方案 scroll search 和 search after。

使用 Keyword 类型

并非所有数值数据都应映射为数值字段数据类型。Elasticsearch为查询优化数字字段,例如integeror long。如果不需要范围查找,对于 term查询而言,keyword 比 integer 性能更好。

避免使用脚本

Scripting是Elasticsearch支持的一种专门用于复杂场景下支持自定义编程的强大的脚本功能。相对于 DSL 而言,脚本的性能更差,DSL能解决 80% 以上的查询需求,如非必须,尽量避免使用 Script。文章来源地址https://www.toymoban.com/news/detail-778539.html

到了这里,关于一起学Elasticsearch系列-写入和检索调优的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一起学Elasticsearch系列-并发控制

    本文已收录至Github,推荐阅读 👉 Java随想录 微信公众号:Java随想录 ES的并发控制是一种机制,用于处理多个同时对同一份数据进行读写操作的情况,以确保数据的一致性和正确性。 实现并发控制的方法主要有两种:悲观锁和乐观锁。 悲观锁是一种并发控制机制,它基于一

    2024年04月27日
    浏览(42)
  • 一起学Elasticsearch系列-模糊搜索

    本文已收录至Github,推荐阅读 👉 Java随想录 微信公众号:Java随想录 在 Elasticsearch 中,模糊搜索是一种近似匹配的搜索方式。它允许找到与搜索词项相似但不完全相等的文档。 前缀匹配通过指定一个前缀值,搜索并匹配索引中指定字段的文档,找出那些以该前缀开头的结果

    2024年02月01日
    浏览(44)
  • 一起学Elasticsearch系列-核心概念

    本文已收录至Github,推荐阅读 👉 Java随想录 微信公众号:Java随想录 开个新的坑,创作关于Elasticsearch的系列文章 首先,让我们简单的了解一下Elasticsearch: Elasticsearch是一个开源的搜索和分析引擎,支持近实时的大数据存储、搜索和分析。它基于Apache Lucene项目,提供全文搜索

    2024年02月01日
    浏览(48)
  • 一起学Elasticsearch系列-索引的CRUD

    本文已收录至Github,推荐阅读 👉 Java随想录 微信公众号:Java随想录 本篇主要是介绍Elasticsearch中索引的基本操作API,即增删改查(CRUD)。 ?pretty 是一个可选参数,如果加上,Elasticsearch 将返回格式化(即缩进、换行等使结果更易读)过的 JSON。 输出示例: 这个输出表示索引

    2024年02月02日
    浏览(48)
  • 一起学Elasticsearch系列-Query DSL

    本文已收录至Github,推荐阅读 👉 Java随想录 微信公众号:Java随想录 DSL是Domain Specific Language的缩写,指的是为特定问题领域设计的计算机语言。这种语言专注于某特定领域的问题解决,因而比通用编程语言更有效率。 在Elasticsearch中,DSL指的是Elasticsearch Query DSL,是一种以J

    2024年02月01日
    浏览(62)
  • ElasticSearch 7.X系列之: 检索性能优化实战指南

    检索响应慢! 并发检索用户多时,响应时间不达标 卡死了! 怎么还没有出结果? 怎么这么慢? 为啥竞品产品的很快就返回结果了? 宕机了 等等...... 这些都与可能检索有关,确切的说和检索性能有关。 检索性能的优化涉及知识点比较零散,我以官方文档的检索性能优化部

    2023年04月08日
    浏览(47)
  • Elasticsearch 全文检索 分词检索-Elasticsearch文章四

    https://www.elastic.co/guide/en/enterprise-search/current/start.html https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl-match-query.html Full text Query中,我们只需要把如下的那么多点分为3大类,你的体系能力会大大提升 很多api都可以查得到,我们只要大概知道有支持哪些功能 Elasticsearch 执行

    2024年02月14日
    浏览(52)
  • ElasticSearch 实战:ElasticSearch文档全文检索

    Elasticsearch 实战:Elasticsearch 文档全文检索 全文检索是 Elasticsearch 的核心功能之一,它允许用户对文本内容进行高效的模糊搜索、词组匹配、同义词处理、停用词过滤等操作。以下是如何进行文档全文检索的详细步骤: **1. **全文匹配查询(Match Query) 最基础的全文检索查询是

    2024年04月11日
    浏览(51)
  • 全文检索-Elasticsearch-进阶检索

    本文记录谷粒商城高级篇的 Elasticsearch 进阶检索部分,续上之前记录的 Elasticsearch入门篇。 ES 支持两种基本方式检索 : 一个是通过使用 REST request URI 发送搜索参数(uri + 检索参数) 另一个是通过使用 REST request body 来发送它们(uri + 请求体) 请求体中写查询条件,语法: 示例

    2024年02月03日
    浏览(88)
  • 九.全文检索ElasticSearch经典入门-ElasticSearch映射修改

    这篇文章的内容是ElasticSearch映射修改,写这篇文章是有水友公司里面遇到了映射修改问题,我这里做了一个整理,希望对你有所帮助。 在ElasticSearch中一旦创建了映射想要进行修改是不被允许的。比如我这里有一个案例 上面创建了索引employee ,同时为其创建映射,指定了id和

    2024年02月05日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包