ElasticSearch Tune for search speed Translation

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本译文原文取自https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html#_search_rounded_dates

1.给文件系统缓存提供更多的内存

es严重依赖文件系统缓存来提高搜索速度。通常,为了使es将搜索保持在物理内存的热区域中,需要确保至少一般的可用内存提供给文件系统缓存

2.使用更快的硬件

如果索引速度受到I/O制约,你需要提供为文件系统缓存提供更多的内存或者升级更快的硬件设备。一般固态比机械硬盘性能更好。始终使用本地文件系统,远程文件系统像NFS以及SMB都应该避免。对例如亚马逊的EBS(elastic block storage)也要留意,es在虚拟存储上表现更好,由于更快以及易于安装使得它变得越来越受欢迎。但是不幸的是相比于本地存储虚拟存储还是有一些差距。如果你要使用EBS请注意要使用提供的IOPS否则会被限流。

如果索引速度受到CPU制约,你需要购买更快的CPU

3.文档建模

文档需要建模这样能够使得索引操作变得更快。

尤其是joins操作应该尽量避免,而嵌套(nested)会降低几倍查询速度,而父子关系(parent-child relations)查询更会使得查询以数百倍的速度下降。所以如果可以使用不规范的文档而不是使用joins也能达到同样的效果,尽量使用这些来提高速度

4.尽量使用更少的字段

query_string和multi_match的字段越多,查询越慢。提高多字段查询速度中普遍使用的一项技术就是将多个字段值拷贝到一个字段,查询的时候只需要查询这个字段即可。这可以使用映射中的copy_to 指令来做到并且该指令不会改变文档源,下面是一个例子


PUT movies
{
  "mappings": {
    "_doc": {
      "properties": {
        "name_and_plot": {
          "type": "text"
        },
        "name": {
          "type": "text",
          "copy_to": "name_and_plot"
        },
        "plot": {
          "type": "text",
          "copy_to": "name_and_plot"
        }
      }
    }
  }
}

5.预索引数据

你应该使用查询模式优化数据索引方式。例如,如果所有文档都有price字段,并且大多数查询都会使用固定的price 范围查询,那么我们可以事先将该范围映射到索引中来加快聚合此字段,看下面例子:

使用前:

PUT index/_doc/1
{
  "designation": "spoon",
  "price": 13
}

GET index/_search
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 10 },
          { "from": 10, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}

使用后:


PUT index
{
  "mappings": {
    "_doc": {
      "properties": {
        "price_range": {
          "type": "keyword"
        }
      }
    }
  }
}

PUT index/_doc/1
{
  "designation": "spoon",
  "price": 13,
  "price_range": "10-100"
}

GET index/_search
{
  "aggs": {
    "price_ranges": {
      "terms": {
        "field": "price_range"
      }
    }
  }
}

6.考虑将标识符映射为关键字

事实上一些数值型字段并不一定会被映射为数值型,es在term的数值型范围查询中使用关键字会更好。典型的,字段存储的例如ISBN或者来自另一个数据库的数值型标识符号会很少被用在范围查询或聚合中,这是因为将它们映射为关键字而不是integer或long更好。


7.避免脚本

通常情况下,脚本尽量避免使用,不得已时最好也要使用painless和expressions引擎


8.搜索边界数据

使用now作为日期范围查询一般不会被缓存这是因为now一直在变化。然而就用户体验而言使用边界数据会更好,而且还有利于查询缓存。

使用前:


PUT index/_doc/1
{
  "my_date": "2016-05-11T16:30:55.328Z"
}

GET index/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "my_date": {
            "gte": "now-1h",
            "lte": "now"
          }
        }
      }
    }
  }
}
使用后:


GET index/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "my_date": {
            "gte": "now-1h/m",
            "lte": "now/m"
          }
        }
      }
    }
  }
}

在这个案例中我们四舍五入到分钟,如果当前时间是16:31:29,这个查询会查询 15:31:00到 16:31:59之间的所有数据。此时如果很多用户进行包含该范围的查询,查询缓存会帮助加快速度。四舍五入的间隔越大,查询缓存越能起到作用。但是太大范围的四舍五入会影响用户体验。
我们也可以使用更大和更小的范围来四舍五入从而提高查询缓存效率


GET index/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should": [
            {
              "range": {
                "my_date": {
                  "gte": "now-1h",
                  "lte": "now-1h/m"
                }
              }
            },
            {
              "range": {
                "my_date": {
                  "gt": "now-1h/m",
                  "lt": "now/m"
                }
              }
            },
            {
              "range": {
                "my_date": {
                  "gte": "now/m",
                  "lte": "now"
                }
              }
            }
          ]
        }
      }
    }
  }
}

但是需要注意的是,有些情况下这种方式会适得其反,因为bool查询(在不同的时间分段中搜索)带来的开销可能会超过查询缓存带来的效率。


9.合并只读索引

将只读索引合并到单个分片中会更好,这种情况在时间索引中尤为明显,因为只有当前时间的索引才会需要写入,过时的索引只需要只读状态。

注意:对于需要写入的索引不要将其合并,另外合并可以作为一个后台进程运行


10.备份全球序数

全球序数是一个作为关键字段被用于terms聚合的数据结构。由于es并不知道哪些字段会被用于terms聚合以及哪些字段不会被用于terms聚合,所以它们一般是被懒加载到内存中。那么你可以使用es在刷新时间通过配置映射来指定某个属性是否被es以全球序数的饥渴状态来加载


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

11.备份文件系统缓存

如果机器重启,文件系统缓存会被清空。这会导致操作系统加载索引到热区域之前话费一定的时间。你可以通过index.store.preload配置指定哪些被马上缓存到内存中

注意:如果文件系统缓存不足以装下所有的索引数据,立马加载大量数据到文件系统缓存中会导致查询变慢。


12.使用索引排序加快连接速度

索引排序会牺牲较少的索引速度来加快连接速度


13.使用preference来优化缓存使用率

有很多可以提高查询性能的缓存,例如文件系统缓存,请求缓存或者查询缓存。目前这些缓存都是节点级别的,这意味着连续发送两个相同的请求,在1个或多个副本的情况下,使用round-robin分布式负载均衡策略以及默认的算法,这两个请求会被路由到不同的分片,这会导致节点级别的缓存无法起到作用。

因为对于用户来说一个接一个发送相同请求是很普遍的,所以为了分析索引的较窄子集,使用标识当前用户或会话的偏好值可以帮助优化高速缓存的使用


14.复制可以帮助提高高吞吐但是有条件的

一个节点上分片越少也就意味着为该分片分配的内存越多从而提高吞吐的能力,但是这是以牺牲高可用为前提的,因为缺少了副本分片作为灾备。在这两者之间最好保持平衡,副本分片的最优数量一般是max(max_failures, ceil(num_nodes / num_primaries) - 1) max_failures:每次最多有这么多节点去处理失败。具体见官网


15.打开自适应副本选择

当存在多个副本分片时,es会使用一组称为自适应副本选择的标准,根据包含每个分片副本的节点的响应时间,服务时间和队列大小来选择最佳数据副本。这可以提高查询吞吐量并减少搜索量大的程序的延迟


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
存储 SQL JSON
Elasticsearch Search API之搜索模板(search Template)
Elasticsearch Search API之搜索模板(search Template)
Elasticsearch Search API之搜索模板(search Template)
|
监控 API UED
Elasticsearch 异步搜索 Async search 实战
1、Elasticsearch 异步搜索定义 异步搜索 API 可异步执行搜索请求、监控其进度并检索可用的部分结果。 如下的官方介绍动画,能更加生动的介绍清楚异步检索。 传统检索 VS 异步检索,在数据量比较大时: 传统检索可能导致超时,以至于无数据返回;或者需要等待很久,用户体验差。 异步检索,可以快速响应数据,用户无需等待。
969 0
Elasticsearch 异步搜索 Async search 实战
Elasticsearch Search APIs2
Elasticsearch Search APIs
69 0
   Elasticsearch Search APIs2
|
算法
白话Elasticsearch14-深度探秘搜索技术之基于multi_match 使用most_fields策略进行cross-fields search弊端
白话Elasticsearch14-深度探秘搜索技术之基于multi_match 使用most_fields策略进行cross-fields search弊端
85 0
Elasticsearch Search APIs3
Elasticsearch Search APIs3
56 0
|
关系型数据库 MySQL 测试技术
Elasticsearch Search APIs1
Elasticsearch Search APIs
85 0
Elasticsearch搜索模板search tempalte
Elasticsearch搜索模板search tempalte
|
存储 Java API
Elasticsearch Search API之(Request Body Search 查询主体)-下篇
Elasticsearch Search API之(Request Body Search 查询主体)-下篇
Elasticsearch Search API之(Request Body Search 查询主体)-下篇
|
存储 自然语言处理 算法
Elasticsearch Search API之(Request Body Search 查询主体)-上篇
Elasticsearch Search API之(Request Body Search 查询主体)-上篇
Elasticsearch Search API之(Request Body Search 查询主体)-上篇
|
缓存 算法 关系型数据库
Elasticsearch Search API 概述与URI Search
Elasticsearch Search API 概述与URI Search
Elasticsearch Search API 概述与URI Search