Elasticsearch-08-性能优化

4. 性能优化

4.1 写入速度优化

4.1.1 增大translog flush间隔

配置项index.translog.durability

默认值是request,也就是每次写入完成后马上进行刷盘。这实际上是影响ES写入性能最大的因素。但只有这样,才能保证每个写操作都是安全的

如果系统可以忍受一定概率的数据丢失,那么可以调整为 async,同时增大刷盘间隔和translog最大大小来提高写入性能

index.translog.durability: async
index.translog.sync_interval: 5s
index.translog.flush_threshold_size: 512mb

4.1.2 增大index refresh间隔

配置项: index.refresh_interval

默认是1秒,这意味着数据在写入后1秒就可以被搜索到了。如果间隔过短,则会产生大量Lucene的段,这将导致频繁的段合并。如果不需要这么高的实时搜索性能,可以适当考虑降低索引refresh周期

4.1.3 段合并优化

段合并是ES在运行中不可避免的操作,通过段合并可以提高搜索的速度,并节约系统资源。但由于段合并时需要消耗大量的CPU和I\O资源,所以,过于频繁的段合并反而会拖慢ES的运行速度

配置项:index.merge.scheduler.max_thread_count

默认值是Math.max(1, Math.min(4, <<node.processors, node.processors>> / 2))。默认值的设置对于ssd来说很友好,但如果只有一块机械硬盘的话,还是设置成1比较好

4.1.4 indexing buffer

index buffer是在ES为doc创建索引时使用。当缓冲区写满之后,会生成一个新的段。每个分片都有自己的buffer,在实际计算每个分片有多少buffer的时候要除以分片数

配置项

indices.memory.index_buffer_size: 10%
indices.memory.min_index_buffer_size: 48MB
indices.memory.max_index_buffer_size: 100MB # 默认是无限制

4.1.5 使用bulk请求

批量写入比多次单个写入要高效的多,但要注意控制批量请求的大小和数量。

如果太大的话内存扛不住

如果过多的话,则可能造成过长的等待队列,这可能会引起频繁gc

4.1.6 调整索引过程

1)使用自动生成的文档id

如果手动给出了文档id,那么ES在写入时会先去检查是否要执行更新操作,这属于不必要的操作

2)调整字段mapping

对于不需要建立索引的字段,index属性设置为no或者not_analyzed,这么做可以降低CPU的占用

3)调整 _source 字段

source 字段用于存储 doc 原始数据,对于部分不需要存储的字段,可以通过 includes excludes过滤,或者将source禁用,一般用于索引和数据分离。

4.2 搜索速度优化

4.2.1 预留足够的内存空间

在一般情况下,应用程序的读写都会被操作系统cache(除了direct方式),cache保存在系统物理内存中(线上应该禁用swap),命中cache可以降低对磁盘的直接访问频率。搜索很依赖对系统cache 的命中,如果某个请求需要从磁盘读取数据,则一定会产生相对较高的延迟。应该至少为系统cache预留一半的可用物理内存,更大的内存有更高的cache命中率。

4.2.2 使用冗余字段

ES虽然允许join操作,但嵌套查询的效率比普通查询低好几倍,而父子文档可能会更慢。

所以,使用冗余字段往往比嵌套查询和父子文档来高效的多

同时,冗余字段还在某些特定方面表现优秀

如果所有的文档都有某些相同字段,并且大多数查询都会对其在一个固定的范围上进行聚合。那我们可以在创建索引的时候把这个固定的范围带上,并使用term聚合来加快聚合速度

例如:搜索商品时按照价格区间进行搜索,那么我们可以在创建索引的时候加入价格区间这个字段来加快索引

4.2.3 强制进行段合并

对于几乎不怎么更新或者不再更新的索引执行强制段合并。因为较少了段的数量,结果的合并速度会提高,同时还能提高恢复的速度

4.2.4 使用全局序号(global ordinals)

全局序号是一种数据结构,用于在keyword字段上进行term聚合。它用一个数值来代表字段中的字符串值,然后为每一数值分配一个 bucket。默认情况下,他们会延迟构建。但由于ES不知道哪些字段会被用于term聚合,所以我们要提前告诉他

PUT index
{
    "mappings":{
        "type":{
            "properties": {
                "foo":{
                    "type": "keyword",
                    "eager_global_ordinals": true
                }
            }
        }
    }
}

4.2.5 限制搜索请求涉及到的分片数

一个搜索请求涉及的分片数量越多,协调节点的CPU和内存压力就越大。默认情况下,ES会拒绝超过1000个分片的搜索请求。我们应该更好地组织数据,让搜索请求的分片数更少。如果想调节这个值,则可以通过action.search.shard_count配置项进行修改。虽然限制搜索的分片数并不能直接提升单个搜索请求的速度,但协调节点的压力会间接影响搜索速度,例如,占用更多内存会产生更多的GC压力,可能导致更多的stop-the-world时间等,因此间接影响了协调节点的性能

4.2.6 使用ARS来提高响应速度

自适应分片选择(Adaptive Replica Selection)可以避免搜索请求路由到负载较高的节点上。该选项在集群负载均衡是能略微提高吞吐量和响应速度;在出现繁忙节点时,能有效提高吞吐量和响应速度

配置项: cluster.routing.use_adaptive_replica_selection

该配置从ES6.1开始启用,但默认是关闭状态。不过再ES7中,它将默认开启

官方对其有详细说明:https://www.elastic.co/cn/blog/improving-response-latency-in-elasticsearch-with-adaptive-replica-selection

4.3 故障诊断常用手段

  1. profile API 来定位慢查询
  2. explain API 来分析为什么分片分配失败
  3. cat API 来检查内存使用情况

4.4 内存里都有些啥

  1. bulk队列
  2. Netty内存池
  3. index buffer,写入缓冲区
  4. 数据集的聚合
  5. segment
  6. 各种cache,fielddata cache,node query cache,shard request cache

推荐阅读

  1. 使用索引生命周期管理实现热温冷架构:https://www.elastic.co/cn/blog/implementing-hot-warm-cold-in-elasticsearch-with-index-lifecycle-management
  2. 高级调优:查找并修复 Elasticsearch 慢查询:https://www.elastic.co/cn/blog/advanced-tuning-finding-and-fixing-slow-elasticsearch-queries
  3. Elasticsearch 集群协调迎来新时代:https://www.elastic.co/cn/blog/a-new-era-for-cluster-coordination-in-elasticsearch
  4. Elasticsearch 缓存深度剖析:一次提高一种缓存的查询速度,https://www.elastic.co/cn/blog/elasticsearch-caching-deep-dive-boosting-query-speed-one-cache-at-a-time
  5. 使用ARS来提高搜索响应速度:https://www.elastic.co/cn/blog/improving-response-latency-in-elasticsearch-with-adaptive-replica-selection
  6. https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html#_migrating_multi_type_indices_to_single_type
posted @ 2021-09-26 10:36  PrimaBruceXu  阅读(392)  评论(0编辑  收藏  举报