Elasticsearch性能优化指南

java达人
关注

使用Profile API调整查询

您还可以使用Profile API分析查询和聚合每个部分的成本。这可能使您可以调整查询花费更少成本,从而获得正面的性能结果并减少负载。另请注意,可以在Search Profiler中轻松查看Profile API负载以提高可读性,Search Profiler是所有X-Pack许可证(包括免费的X-Pack Basic许可证)中均可使用的Kibana开发工具UI。

对Profile API的一些警告是:

Profile API作为调试工具增加了搜索执行的大量开销,并且还可能产生非常冗长的输出

给定增加的开销,得出的花费时间指标可能不是实际花费时间,但是可以在子句之间进行比较以获取相对时间差异

Profile API最适合用于研究查询中花费最多开销的子句后面的可能原因,但并非旨在准确衡量每个子句的时间

使用index_phrases进行更快的短语查询

文本字段具有index_phrases选项,该选项索引2个,并且查询解析器会自动利用该选项来运行不带斜率的词组查询。如果您的用例涉及运行大 量短语查询,则可以大大加快查询速度。

使用index_prefixes进行更快的前缀查询

文本字段具有index_prefixes选项,该选项为所有term的前缀编制索引,并由查询解析器自动利用以运行前缀查询。如果您的用例涉及运行大量前缀查询,则可以大大加快查询速度。

使用constant_keyword加快过滤

调整磁盘使用率

禁用不需要的功能

默认情况下,Elasticsearch为大多数字段编入索引并将doc值添加到大多数字段,以便可以立即搜索和聚合汇总它们。例如,如果您有一个名为foo的数字字段,需要在其上运行直方图,但您永远不需要对其进行过滤,则可以安全地在 mappings中禁用对此字段的索引:

text字段在索引中存储归一化因子,以便能够对文档进行评分。如果您只需要 text字段上的匹配功能但不关心产生的分数,则可以将Elasticsearch配置为不将 norms 写入索引:

curl -X PUT "localhost:9200/index?pretty" -H 'Content-Type: application/json' -d'{"mappings": {"properties": {"foo": {"type": "text","norms": false      }    }  }}'

默认情况下,文本字段还将频率和位置存储在索引中。频率用于计算分数,位置用于运行 phrase 查询。如果您不需要运行 phrase 查询,可以告诉Elasticsearch不要索引位置信息:

curl -X PUT "localhost:9200/index?pretty" -H 'Content-Type: application/json' -d'{"mappings": {"properties": {"foo": {"type": "text","index_options": "freqs"      }    }  }}'

此外,如果您既不计分,也可以将Elasticsearch配置为仅对每个 term的匹配文档编制索引。您仍然可以在此字段上进行搜索,但是词组查询将引发错误,并且评分将假定 term在每个文档中仅出现一次。

curl -X PUT "localhost:9200/index?pretty" -H 'Content-Type: application/json' -d'{"mappings": {"properties": {"foo": {"type": "text","norms": false,"index_options": "freqs"      }    }  }}'

不要使用默认的动态字符串映射

默认的动态字符串mappings会将字符串字段索引为文本和关键字。如果您只需要其中之一,则很浪费。通常,id字段仅需要索引为 keyword,而body字段仅需要索引为 text 字段。

可以通过在字符串字段上配置显式映射或设置将字符串字段映射为text 或keyword的动态模板来禁用此功能。

观测分片大小

较大的分片将在存储数据方面更加有效。要增加分片的大小,可以通过创建具有较少主分片的索引,创建较少的索引(例如通过利用Rollover API)或使用Shrink API修改现有索引来减少索引中的主分片数量。

请记住,较大的分片大小会带来缺点,例如较长的完整恢复时间。

禁用_source

_source字段存储文档的原始JSON body 。如果您不需要访问它,可以将其禁用。但是,需要访问_source的API(例如 update 和 reindex )将无法使用。

使用best_compression

_source和storage字段很容易占用不可忽略的磁盘空间。通过使用best_compression编解码器,可以更大程度地压缩。

强制合并

Elasticsearch中的索引存储在一个或多个分片中。每个分片都是一个Lucene索引,由一个或多个 segment(磁盘上的实际文件)组成。较大的 segment更有效地存储数据。

_forcemerge API可用于减少每个分片的段数。在许多情况下,通过设置max_num_segments = 1,可以将每个分片的 segment数减少到一个。

收缩索引

使用Shrink API,您可以减少索引中的分片数量。与上面的Force Merge API一起使用,可以大大减少索引的分片和分段的数量。

使用足够的最小数字类型

您为数字数据选择的类型可能会对磁盘使用产生重大影响。特别是,整数应使用整数类型( byte, short, integer o或 long)存储,并且浮点数应在适当的情况下存储在scaled_float中,或存储在适合以下用例的最小类型中:相对于double优先使用float或相对于float优先使用half_float将有助于节省存储空间。

使用索引排序来定位相似的文档

当Elasticsearch存储_source时,它会一次压缩多个文档,以提高整体压缩率。例如,文档共享相同的字段名称是很常见的,而文档共享某些字段值是很常见的,尤其是在基数较低或zipfian分布的字段上。

默认情况下,文档按添加到索引的顺序压缩在一起。如果启用了索引排序,则它们将按排序顺序进行压缩。将具有相似结构,字段和值的文档分类在一起可以提高压缩率。

将字段按相同顺序放在文档中

由于多个文档被压缩成块,因此如果字段总是以相同的顺序出现,则更有可能在这些_source文档中找到更长的重复字符串。

避免分片过多

在某些情况下,减少集群中的分片数量,同时保持相同数量的数据,可以更有效地利用系统资源(CPU,RAM,IO)。在这些情况下,我们认为集群分片过多了。

出现此拐点的分片数量取决于多种因素,包括:

可用的硬件

分片负载

数据量

针对集群执行的查询的类型

这些查询的发出率

正在查询的数据量

在生产环境硬件上,针对生产数据进行测试是校准最佳分片大小的唯一方法。通常使用数十GB的分片大小,这可能是进行实验的有用起点。当评估不同分片大小的影响时,Kibana的Elasticsearch监视功能可提供有用的历史集群性能视图。

为什么分片效率低下

每个segment都有需要保留在堆内存中的元数据。这些包括字段列表,文档数和term词典。随着分片的大小增加,其segment的大小通常也会增加,因为较小的segment会合并为较少的较大segment。通常,这可以减少给定数据量的分片的segment元数据所需的堆数量。分片至少应大于1GB,才能最有效地利用内存。

但是,即使一开始分片在1GB左右的内存效率上有所提高,但充满1GB分片的集群的性能仍可能会很差。这是因为拥有许多小分片也会对搜索和索引操作产生负面影响。每个查询或索引操作在要查询或建立索引的索引分片的单个线程中执行。接收到来自客户端的请求的节点将负责将该请求分配给适当的分片,并将这些单独分片的结果归并为单个响应。即使假设集群有足够的 search threadpool threads 可立即针对请求所需的所有分片进行请求的操作,但与向持有这些分片的节点发出网络请求以及必须合并许多小型结果相关的开销会导致分片延迟增加。这继而可能导致线程池耗尽,并因此导致吞吐量降低。

如何减少分片数量并增加分片大小

尝试使用这些方法来减少过度分片。

减少新索引的分片数量

您可以为使用create index API创建的新索引,指定index.number_of_shards设置,也可以为由索引生命周期管理(ILM)自动创建的索引,将它作为索引模板的一部分。

使用 rollover index API. rollover索引时,可以覆盖index.number_of_shards。

通过增加过渡阈值来创建更大的分片

您可以使用  rollover index API或通过在ILM策略中指定  rollover 操作来翻转索引。如果使用ILM策略,请增加rollover条件阈值(max_age,max_docs,max_size),以允许索引在过渡之前增长到更大的大小,这会创建更大的分片。

请特别注意任何空索引。由于满足max_age阈值,这些可以由滚动索引的ILM策略管理。在这种情况下,您可能需要调整策略以利用max_docs或max_size属性来防止创建这些空索引。一个可能发生这种情况的示例是一个或多个Beats停止发送数据。如果将这些Beats的ILM管理的索引配置为每天滚动,则每天将生成新的空索引。可以使用 cat count API.识别空索引。

通过使用跨越较长时间段的索引模式来创建更大的分片

创建涵盖更长时间段的索引可减少索引和分片数,同时增加索引大小。例如,您可以创建每月甚至每年的索引,而不是每日索引。

如果使用Logstash创建索引,则可以将Elasticsearch输出的index属性修改为涵盖较长时间段的日期数学表达式。例如,使用logstash-%{+ YYYY.MM}而非logstash-%{+ YYYY.MM.dd}创建月度索引,而不是每日索引。Beats还允许您更改在Elasticsearch输出的index属性中定义的日期数学表达式,例如Filebeat。

将现有索引缩小到更少的分片

您可以使用缩小索引API将现有索引缩小到更少的分片。

索引生命周期管理还可以在warm阶段对索引执行收缩操作。

重新索引现有索引以减少分片

您可以使用reindex API将现有索引重新分配到具有更少分片的新索引。重新索引数据后,可以删除过多分片的索引。

将索引从较短时期重新索引为较长时期

您可以使用reindex API将涵盖较短时间段的多个小索引重新索引为涵盖较长时间段的较大索引。例如,十月起的每日索引以及诸如foo-2019.10.11之类的命名模式可以合并为月度foo-2019.10索引,如下所示:

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'{"source": {"index": "foo-2019.10.*"  },"dest": {"index": "foo-2019.10"  }}'

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存