精华内容
下载资源
问答
  • 前言2 合理的集群规划3 数据模型优化3.1 精心设计Mapping3.2 选择合理的分词器4 查询限制5 段合并(segment merge)6 过滤查询(filter)7 路由(routing)8 配置Client角色9 游标查询(scroll)10 避免使用wildcard...


    在这里插入图片描述

    1.概述

    转载:ES Elasticsearch查询优化

    在这里插入图片描述

    1.前言

    Elasticsearch的查询分为两阶段,查询(Query)阶段和提取(Fetch)阶段。Elasticsearch的数据分布在多个Shard以及多台机器上,当进行查询时,潜在的结果数据会在当前查询index的所有Shard中,所以Elasticsearch查询的时候需要查询所有Shard(同一个Shard的Primary和Replica选择一个即可),查询会分发给所有的Shard,每个Shard中都是一个独立的查询引擎,最后合并所有Shard查询的结果并返回。

    2 合理的集群规划

    前期Elasticsearch集群的数据合理规划是必须的,一个集群可以容纳的index的数量(准确的说是shard数据量)和shard的大小以及数据结点的数量和硬件配置有关,因此不可能有一个统一的标准。 最好通过监控数据来做容量管理,如果一个数据结点的heap压力很大,load过高导致查询或者写入慢,就应该考虑扩容加节点了。

    因此建议尽量控制index和shard的数量,以一个Elasticsearch实例内存最大31G为例:

    1. 一个数据实例的shard数保持在600个以内

    2. 每个shard大小不要超过30GB,推荐20-30GB,100 GB以下的index设置成3-5个shard。大的index单shard不超过30GB。

    合理的数据和集群规划是提高查询速度的前提条件。在集群状况良好的前提下进行参数调优。

    当index/shard数量过多时,可以考虑从以下几个方面改进:

    1. 降低数据量较小的index的shard数量;

    2. 把一些关联的index合并成一个index;

    3. 关闭不使用的历史索引。

    3 数据模型优化

    3.1 精心设计Mapping

    Elasticsearch默认的Mapping是动态Mapping,系统自动识别字段类型。因根据实际的业务数据去设置优化Mapping,根据具体的字段和需求去选择对应的类型和设置。

    1. string类型默认分成:text和keyword两种类型。需要分词:text,否则keyword。

    2. 枚举类型,基于性能keyword,即便是整形。

    3. 数值类型,尽量选择贴近大小的类型。

    4. 其他类型,布尔、日期、地理位置。如果需要基于时间轴做分析,必须date类型,如果仅需秒级返回,建议使用keyword。

    5. 如果某个字段不需要被检索,将index设置为false。

    6. 如果字段完全不需要检索,排序,聚合分析,将enable设置为false。

    3.2 选择合理的分词器

      如果使用IK分词器,建议使用ik_max_word,粗粒度的分词结果基本包含细粒度ik_smart的结果。
    

    4 查询限制

    限制的内容包括:查询范围,单次查询数量等。

    1. 根据实际业务需求去规划查询范围,查询越少的字段越快,过大的查询范围不仅会导致查询效率低,而且会使Elasticsearch集群资源耗费急剧增加,甚至可能造成集群崩溃。通过_source参数可以控制返回字段信息,尽量避免读取大字段。

    2. 单次查询数量限制是为了保证内存不会被查询内存大量占用,Elasticsearch默认的查询请求通常返回排序后的前10条记录,最多一次读取10000条记录。通过from和size参数控制读取记录范围,避免一次读取过多的记录。一次性查询大量的数据,使用scroll。

    查询请求示例:

    curl -XGET "http://127.0.0.1:24100/myindex-001/_search?pretty"  -H 'Content-Type: application/json' -d'
    {
      "from": 0,
      "size": 10,
      "_source": "age",
      "query": {
          "match": {
            "age": "56"
          }
      },
      "sort": [
        {
          "age": {
            "order": "asc"
          }
        }
      ]
    }'
    

    5 段合并(segment merge)

    每个Shard是基于多个segment组成创建的,segment的个数的减少可以大幅的提高查询的速度,定时的进行手动索引段合并,可以提高查询速度。

    curl -XPOST 'http://127.0.0.1:24100/myindex-001/_forcemerge?only_expunge_deletes=false&max_num_segments=1&flush=true&pretty'
    
    

    注意:segment merge操作是需要耗费大量的磁盘I/O,所以建议在业务比较空闲的时间进行后台段合并。

    关于索引合并这里有异议:【Elasticsearch】索引 强制合并 缓存 refresh flush 等操作

    6 过滤查询(filter)

    Elasticsearch的查询操作分为2种:查询(query)和过滤(filter),查询(query)默认会计算每个返回文档的得分,然后根据得分排序;而过滤(filter)只会筛选出符合的文档,并不计算得分,且可以缓存文档。

    对于非全文检索的使用场景,用户并不关心查询结果和查询条件的相关度,只是想查找目标数据。此时可以使用filter来提高查询效率。

    query查询:

    curl -XGET "http://127.0.0.1:24100/myindex-001/_search?pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "age": "56"
        }
      }
    }'
    

    filter查询:

    curl -XGET "http://127.0.0.1:24100/myindex-001/_search?pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "bool": {
          "filter": {
             "match": {
              "age": "56"
            }
          }
        }
      }
    }'
    

    7 路由(routing)

    Elasticsearch写入文档时,文档会通过一个公式路由到一个索引中的一个分片上。默认公式如下:

    shard_num = hash(_routing) % num_primary_shards
    

    _routing字段的取值,默认是_id字段,可以根据业务场景设置经常查询的字段作为路由字段。例如可以考虑将用户id、地区作为路由字段,查询时可以过滤不必要的分片,加快查询速度。

    写入时指定路由:

    curl -PUT "http://127.0.0.1:24100/my_index/my_type/1?routing=user1&refresh=true" -H 'Content-Type: application/json' -d'
    {
      "title": "This is a document"
    }'
    

    查询时不指定路由,需要查询所有的分片:

    curl -XGET "http://127.0.0.1:24100/my_index/_search?pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "title": "document"
        }
      }
    }'
    

    查询是指定路由,只需要查询1个分片:

    curl -XGET "http://127.0.0.1:24100/my_index/_search?routing=user1&pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "title": "document"
        }
      }
    }'
    

    8 配置Client角色

    Client角色可以用于发送查询请求到其他节点,收集和合并结果,以及响应发出查询的客户端。通过给Client节点配置更高规格的CPU和内存,可以加快查询运算速度,提升缓存命中数,增加Client节点可以增加查询并发数。

    9 游标查询(scroll)

    Elasticsearch为了避免深分页,不允许使用分页(from&size)查询10000条以后的数据,需要使用scroll(游标)查询。

    curl -XGET  "http://127.0.0.1:24102/myindex-001/_search?scroll=1m&pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "age": "36"
        }
      },
      "size":10000
    }'
    

    优化scroll,在一般场景下,scroll通常用来取得需要排序过来的大量数据,但很多时候只需要把数据取出来就好,这时候可以对scroll进行优化。使用_doc去sort返回的结果不会有排序,此时执行效率最快。

    curl -XGET  "http://127.0.0.1:24102/myindex-001/_search?scroll=1m&pretty" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "match": {
          "age": "36"
        }
      },
      "size":10000,
      "sort": "_doc"
    }'
    

    注意:在设置开启scroll时,设置了一个scroll的存活时间,但是如果能够在使用完顺手关闭,可以提早释放资源,降低ES的负担。

    curl -XDELETE  "http://127.0.0.1:24102/_search/scroll=1m&pretty" -H 'Content-Type: application/json' -d'
    {
      "scroll_id":"id"
    }'
    

    10 避免使用wildcard模糊匹配查询

    Elasticsearch默认支持通过*?正则表达式来做模糊匹配,数据量级别达到TB+甚至更高之后,模糊匹配查询通常会耗时比较长,甚至可能导致内存溢出,卡死乃至崩溃宕机的情况。所以数据量大的情况下,不要使用模糊匹配查询。

    11 聚合优化

    大多时候对单个字段的聚合查询还是比较快的,但是当需要聚合多个字段时,就会产生大量的分组,最终结果就是占用Elasticsearch大量的内存,从而导致内存溢出的情况发生。尽量根据业务优化,减少聚合次数。

    11.1 默认深度优化聚合改为广度优先聚合

    添加设置:"collect_mode": "breadth_first"

    depth_first :直接进行子聚合的计算

    breadth_first :先计算出当前聚合的结果,针对这个结果在对子聚合进行计算

    11.2 在每一层terms aggregation内部加一个增加:“execution_hint”: “map”

    添加设置:"execution_hint": "map"

    注意:

    1、查询结果直接放入到内存中构建map,在查询结果集小的场景下,速度极快;

    2、 但如果查询结果集合很大(百万-亿级别)的时候,传统聚合方式会比map方式快。

    展开全文
  • from elasticsearch import Elasticsearch es = Elasticsearch(['59.110.53.38:9200']) query={ ··· } res = es.search(index='app_store', body=query, doc_type='hotsearch_related') for i in xrange(0, ...
  • linux命令行elasticsearch查询工具es2unix

    千次阅读 2016-01-19 11:23:41
    当想在linux的命令行中查看elasticsearch的状态时,可以用es2unix...它是elasticsearch官方推出的,可以通过命令来查看es的各种状态,安装方法   curl -s download.elasticsearch.org/es2unix/es > /bin/e...
    当想在linux的命令行中查看elasticsearch的状态时,可以用es2unix这个工具,插件地址: https://github.com/elasticsearch/es2unix。它是elasticsearch官方推出的,可以通过命令来查看es的各种状态,安装方法
     
    curl -s download.elasticsearch.org/es2unix/es > /bin/es
    chmod +x /bin/es
     
    这个是作者编译的,如果你运行时报Unrecognized VM option 'TieredStopAtLevel=1',则是因为你使用的jdk是比较旧的1.6版本的,不支持TieredStopAtLevel=1这个jvm参数,解决办法有两个,一个是换最新的jdk,一个是下我编译好的工具(下载地址:http://download.csdn.net/detail/laigood12345/6315121),我重新编译时把这个参数去掉了。
     
    用法
    这个工具默认是使用http://localhost:9200这个elasticsearch的地址,你可以在命令中通过u参数指定其它地址,例如 %es version -u http://192.168.0.1:9200
     
    查看es版本
        % es version
        es            1.0.0
        elasticsearch 0.21.0.Beta1

     

     
    查看健康状态
        % es health -v
        cluster status nodes data pri shards relo init unassign
        kluster green      2    2   3      6    0    0        0
     
    统计索引
         % es count
        2,319,799
        % es count elasticsearch
        3 "q=elasticsearch"
        % es count "john deacon"
        225,839 "q=john deacon"
        % es count "\"saved by the bell\""
        220 "q="saved by the bell""
     
    搜索
         % es search -v "george costanza" title
        score   index  type id      title
        5.78647 wiki   page 660183  George Costansa
        5.78647 wiki   page 273868  George Constanza
        5.63803 wiki   page 865781  Vandelay Industries
        4.69835 wiki   page 932333  Art Vandelay
        4.69835 wiki   page 2147975 Can't Stand Ya
        4.67351 wiki   page 2486208 Art vandelay
        4.07630 wiki   page 2147959 Costanza
        3.23200 wiki   page 2147971 The Costanza family
        3.21007 wiki   page 2147972 Costanza family
        2.94863 wiki   page 4946953 Santa costanza
         Total: 118186
     
    查询master
         % es master
        J-erllamTOiW5WoGVUd04A 127.0.0.1 Slade, Frederick
     
    查询索引状态
        % es indices -v
        status name   pri rep    docs        size
        green  _river   0   1       4        8068
        green  wiki     1   1 1104894 13805525784
        % es indices | grep \^red
        red    bb           5 0
        red    test         4 1   218b   218  0
        red    enron        5 0
        red    uno          1 0
     
    查看节点信息
        % es nodes
        Uv1Iy8FvR0y6_RzPXKBolg 127.0.0.1 9201 127.0.0.1 9300   d Cannonball I
        J-erllamTOiW5WoGVUd04A 127.0.0.1 9200 127.0.0.1 9301 * d Slade, Frederick
        j27iagsmQQaeIpl6yU6mCg 127.0.0.1 9203 127.0.0.1 9303 - c Georgianna Castleberry
        T1aFDU2BSUm748gYxjEN9w 127.0.0.1 9202 127.0.0.1 9302   d Living Tribunal
     
    查看节点的变化状态日志
        % es lifecycle /tmp/es-*/logs/elasticsearch.log
        2013-02-08 13:47:15,516 Lurking Unknown INIT   0.21.0.Beta1-SNAPSHOT
        2013-02-08 13:47:20,413 Lurking Unknown MASTER Lurking Unknown
        2013-02-08 13:47:20,467 Lurking Unknown START
        2013-02-08 13:47:36,319 Cameron Hodge   INIT   0.21.0.Beta1-SNAPSHOT
        2013-02-08 13:47:41,211 Lurking Unknown ADD    Cameron Hodge
        2013-02-08 13:47:41,223 Cameron Hodge   MASTER Lurking Unknown
        2013-02-08 13:47:41,278 Cameron Hodge   START
        2013-02-08 13:47:59,426 Armageddon      INIT   0.21.0.Beta1-SNAPSHOT
        2013-02-08 13:48:04,279 Lurking Unknown ADD    Armageddon
        2013-02-08 13:48:04,280 Cameron Hodge   ADD    Armageddon
        2013-02-08 13:48:04,287 Armageddon      MASTER Lurking Unknown
        2013-02-08 13:48:04,340 Armageddon      START
        2013-02-08 13:48:30,333 Lurking Unknown REMOVE Armageddon
        2013-02-08 13:48:30,339 Cameron Hodge   REMOVE Armageddon
        2013-02-08 13:48:30,362 Armageddon      STOP
     
    查看jvm heap占用
        % es heap | sort -rnk6
        XO6c2A1D 23.9mb 25138608 123.7mb  129761280 19.4% 127.0.0.1 Junkpile
        uVP8g9_l 94.6mb 99257976 990.7mb 1038876672  9.6% 127.0.0.1 Hammond, Jim
        pjbeg_k8 76.9mb 80730208 990.7mb 1038876672  7.8% 127.0.0.1 Scarlet Centurion
         可以通过下面脚本来实时监控
        % while true; do es heap | sort -rnk6 | head -1; sleep 60; done
        XO6c2A1D 57.3mb 60157200 123.7mb 129761280 46.4% 127.0.0.1 Junkpile
        XO6c2A1D 54.7mb 57405904 123.7mb 129761280 44.2% 127.0.0.1 Junkpile
        XO6c2A1D 62.7mb 65834752 123.7mb 129761280 50.7% 127.0.0.1 Junkpile
        XO6c2A1D 56.9mb 59743504 123.7mb 129761280 46.0% 127.0.0.1 Junkpile
        XO6c2A1D 52.1mb 54676216 123.7mb 129761280 42.1% 127.0.0.1 Junkpile
        XO6c2A1D 37.1mb 38971744 123.7mb 129761280 30.0% 127.0.0.1 Junkpile
        XO6c2A1D   52mb 54528424 123.7mb 129761280 42.0% 127.0.0.1 Junkpile
        XO6c2A1D 46.5mb 48787064 123.7mb 129761280 37.6% 127.0.0.1 Junkpile
     
    查看分片状态
        % es shards
        wiki 0 p STARTED    1160290 7.2gb 7776371641 127.0.0.1 Feline
        wiki 0 r STARTED    1160290 7.2gb 7776371602 127.0.0.1 Jenkins, Abner
        wiki 1 p RELOCATING 1159509 7.5gb 8116295811 127.0.0.1 Feline -> 127.0.0.1 Amphibius
        wiki 1 r STARTED    1159509 7.5gb 8116295811 127.0.0.1 Jenkins, Abner
    展开全文
  • 为什么Elasticsearch查询变得这么慢了?

    万次阅读 多人点赞 2018-10-14 16:05:30
    ”或者是:“我的ES查询耗时很长,我该怎么做?” 包含但不限于:Nested慢查询、集群查询慢、range查询慢等问题。 1、两个维度 每当我们得到这些类型的问题时,我们首先要深入研究两个主要方面: 配置维度 -...

    Elasticsearch 最少必要知识实战教程直播回放

    0、引言

    Elasticsearch社区中经常看到慢查询问题:“你能帮我看看Elasticsearch的响应时间吗?”或者是:“我的ES查询耗时很长,我该怎么做?”

    包含但不限于:Nested慢查询、集群查询慢、range查询慢等问题。
    在这里插入图片描述

    1、两个维度

    每当我们得到这些类型的问题时,我们首先要深入研究两个主要方面:

    • 配置维度 - 查看当前系统资源和默认Elasticsearch选项。
    • 开发维度 - 查看查询,其结构以及要搜索的数据的映射(Mapping)。

    我们将首先关注开发方面的问题。 我们将获得慢查询,讨论DSL查询语言,并查看有助于改进Elasticsearch查询的小型常规选项。

    2、开发维度—你的查询有多慢?

    第一步是查看发送到群集的查询所花费的时间。 在研究如何打开慢速日志时,Elasticsearch文档可能有点不清楚,因此我将在下面展示一些示例。

    • 首先,Elasticsearch中有两个版本的慢速日志:索引慢速日志(index slow logs )和搜索慢速日志( search slow logs)。
      由于我们试图解决的问题涉及慢查询,我们将专注于搜索慢速日志。 但是,如果在索引文档/添加文档时问题解决了性能问题,那么我们将查看索引慢速日志。

    默认情况下,所有版本的Elasticsearch都会关闭慢速日志,因此您必须对群集设置和索引设置进行一些更新。
    这些示例适用于使用elasticsearch 6.2,但您可以在此处找到所有以前的版本。
    只需将$ES_version替换为您正在使用的版本,
    例如5.5版本设置官网参考:http://t.cn/E7Hq2NG。

    向_cluster API发送放置请求以定义要打开的慢速日志级别:警告,信息,调试和跟踪。 (有关日志记录级别的更多信息参考:http://t.cn/E7Hqc5e。)

    curl -XPUT http://localhost:$ES_PORT/_cluster/settings -H ‘Content-Type: application/json’ -d’
    {
    "transient" : {
    "logger.index.search.slowlog" : "DEBUG",
    "logger.index.indexing.slowlog" : "DEBUG"
    }
    }'
    
    • 所有慢速日志记录都在索引级别启用,因此您可以再次向index _settings API发送请求以打开,但如果您每月,每季度等都在滚动更新索引,则还必须添加到索引模板中。

    • 将API调用调整为索引设置以匹配您想要命中的慢日志时间阈值。 (您可以设置为0s以分析实例并收集正在发送的所有查询,并设置为-1以关闭慢速日志。)
      使用您在_clustersettings中选择使用的日志级别设置。 在这个例子中,“DEBUG”。
      ES_PORT是一个持久的环境变量。

      curl -XPUT http://localhost:$ES_PORT/*/_settings?pretty -H 'Content-Type: application/json' -d 
      '{"index.search.slowlog.threshold.query.debug": "-1",
       "index.search.slowlog.threshold.fetch.debug": "-1",}'
      
    • 现在,您需要收集日志。 每个分片生成慢速日志并按数据节点收集。 如果您只有一个包含五个主分片的数据节点(这是默认值),您将在慢速日志中看到一个查询的五个条目。 由于Elasticsearch中的搜索发生在每个分片中,因此每个分片都会看到一个。 每个数据节点存储慢速日志,默认情况如下

    location:/ var / log / elasticsearch / $ClusterID_index_slowlog_query
    和 / var / log / elasticsearch / $ClusterID_index_slowlog_fetch。

    如您所见,搜索慢速日志再次根据搜索阶段分解为单独的日志文件:获取(fetch)和查询(query)。
    现在我们在日志中有结果,我们可以拉入一个条目并将其分开。

    [2018-05-21T12:35:53,352][DEBUG ][index.search.slowlog.query] 
    [DwOfjJF] [blogpost-slowlogs][4] took[1s], took_millis[0], types[], 
    stats[], search_type[QUERY_THEN_FETCH], total_shards[5], 
    source[{"query":{"match":{"name":{"query":"hello world",
     "operator":"OR","prefix_length":0,"max_expansions":50,
    "fuzzy_transpositions" :true,"lenient":false,"zero_terms_query":
     "NONE","boost":1.0}}},"sort":[{"price": {"order":"desc"}}]}], 
    

    在这里,您看到:

     1. 日期
     2. 时间戳 
     3. 日志级别 
     4. 慢速类型 
     5. 节点名称 
     6. 索引名称 
     7. 分片号 
     8. 时间花费 
     9. 查询的主体(_source>)
    

    一旦我们获得了我们认为花费的时间太长的查询,我们就可以使用一些工具来分解查询:

    工具1:Profile API

    Profile API提供有关搜索的信息页面,并分解每个分片中发生的情况,直至每个搜索组件(match/range/match_phrase等)的各个时间。 搜索越详细,_profile输出越详细。

    工具2:The Kibana profiling 工具

    这与_profileAPI密切相关。 它提供了各个搜索组件的完美的可视化效果表征各个分解阶段以及各阶段查询的时间消耗。 同样,这允许您轻松选择查询的问题区域。
    在这里插入图片描述

    3、开发维度—Elasticsearch的查询原理

    现在我们已经确定了一个很慢的查询,我们通过一个分析器profile来运行它。 但是,查看单个组件时间结果并未使搜索速度更快。 怎么办?

    通过两个阶段(下面)了解查询的工作原理,允许您以从速度和相关性方面获得Elasticsearch最佳结果的方式重新设计查询。
    在这里插入图片描述

    3.1 Query阶段

    • 路由节点接受该查询。
    • 路由节点识别正在搜索的索引(或多个索引)。
    • 路由节点生成一个节点列表,其中包含索引的分片(主要和副本的混合)。
    • 路由节点将查询发送到节点(上一步节点列表列出的节点)。
    • 节点上的分片处理查询。
    • 查询(默认情况下)对前10个文档进行评分。
    • 该列表将发送回路由节点。

    3.2 fetch阶段

    获取阶段由路由节点开始,路由节点确定每个分片发送的50个(5个分片×10个结果)结果中的前10个文档。
    路由节点向分片发出对前10个文档的请求。 (可能是包含最高得分文档的一个分片,或者它们可能分散在多个分片中。)

    返回列表后,主节点会在查询响应的_hits部分中显示文档。

    4、开发维度—filter过滤器查询优化

    结果分数是Elasticsearch的关键。 通常,当您使用搜索引擎时,您需要最准确的结果。 例如,如果您正在搜索“苹果”,您不希望结果包括“苹果手机”。
    Elasticsearch根据您提供的参数对查询结果进行评分。
    虽然查询相关性不是本篇文章的重点,但重要的是在此提及,因为如果您有快速搜索需求但结果不是您要查找的结果,则整个搜索都是浪费时间。
    那么,你如何加快搜索速度?

    4.1 查询时,使用query-bool-filter组合取代普通query

    提高搜索性能的一种方法是使用过滤器。 过滤后的查询可能是您最需要的。
    首先过滤是很重要的,因为搜索中的过滤器不会影响文档分数的结果,因此您在资源方面使用很少的资源来将搜索结果范围缩小到很小。
    使用过滤查询,结合使用布尔匹配,您可以在评分之前搜索包含X的所有文档,或者不包含Y的所有文档。此外,可以filter是可以被缓存的。
    过滤器filter查询不是加速Elasticsearch查询的唯一方法。

    【from腾讯】默认情况下,ES通过一定的算法计算返回的每条数据与查询语句的相关度,并通过score字段来表征。
    但对于非全文索引的使用场景,用户并不care查询结果与查询条件的相关度,只是想精确的查找目标数据。
    此时,可以通过query-bool-filter组合来让ES不计算score,
    并且尽可能的缓存filter的结果集,供后续包含相同filter的查询使用,提高查询效率。

    filter原理推荐阅读:吃透 | Elasticsearch filter和query的不同

    5、开发维度——其他优化

    5.1 避免使用script查询

    避免使用脚本查询来计算匹配。 推荐:建立索引时存储计算字段。

    例如,我们有一个包含大量用户信息的索引,我们需要查询编号以“1234”开头的所有用户。
    您可能希望运行类似“source”的脚本查询:“doc [‘num’]。value.startsWith(‘1234’)。”
    此查询非常耗费资源并且会降低整个系统的速度。 合理的建议:考虑在索引时添加名为“num_prefix”的字段。
    然后我们可以查询“name_prefix”:“1234”。

    5.2 避免使用wildcard查询

    主要原因:
    wildcard类似mysql中的like,和分词完全没有了关系。

    出现错误:
    用户输入的字符串长度没有做限制,导致首尾通配符中间可能是很长的一个字符串。 后果就是对应的wildcard Query执行非常慢,非常消耗CPU。

    根本原因:
    为了加速通配符和正则表达式的匹配速度,Lucene4.0开始会将输入的字符串模式构建成一个DFA (Deterministic Finite Automaton),带有通配符的pattern构造出来的DFA可能会很复杂,开销很大。

    可能的优化方案:

    1. wildcard query应杜绝使用通配符打头,实在不得已要这么做,就一定需要限制用户输入的字符串长度。
    2. 最好换一种实现方式,通过在index time做文章,选用合适的分词器,比如nGram tokenizer预处理数据,然后使用更廉价的term query来实现同等的模糊搜索功能。
    3. 对于部分输入即提示的应用场景可以考虑优先使用completion suggester, phrase/term/suggeter一类性能更好,模糊程度略差的方式查询,待suggester没有匹配结果的时候,再fall back到更模糊但性能较差的wildcard, regex, fuzzy一类的查询。
      详尽原理参考:https://elasticsearch.cn/article/171

    5.3 合理使用keyword类型

    ES5.x里对数值型字段做TermQuery可能会很慢。

    在ES5.x+里,一定要注意数值类型是否需要做范围查询,看似数值,但其实只用于Term或者Terms这类精确匹配的,应该定义为keyword类型。

    典型的例子就是索引web日志时常见的HTTP Status code。

    详尽原理参考:https://elasticsearch.cn/article/446

    5.4 控制字段的返回

    一是:数据建模规划的时候,在Mapping节点对于仅存储、是否构建倒排索引通过enabled、index参数进行优化。
    二是:_source控制返回,不必要的字段不需要返回,举例:采集的原文章详情内容页,根据需要决定是否返回。

    5.5 让Elasticsearch干它擅长的事情

    在检索/聚合结果后,业务系统还有没有做其他复杂的操作,花费了多少时间?
    这块是最容易忽视的时间耗费担当。

    Elasticsearch显然更擅长检索、全文检索,其他不擅长的事情,尽量不要ES处理。比如:频繁更新、确保数据的ACID特性等操作。

    6、配置维度——核心配置

    6.1 节点职责明晰

    区分路由节点、数据节点、候选主节点。

    路由节点的主要优点是:

    1. 由于路由节点减少了搜索和聚合的压力,因此数据节点上的内存压力略有降低;
    2. “智能路由”——因为他们知道所有数据存在的地方,他们可以避免额外的跳跃;“智能路由”——因为他们知道所有数据存在的地方,他们可以避免额外的跳跃;
    3. 从架构上讲,将路由节点用作集群的访问点非常有用,因此您的应用程序无需了解详细信息。 从架构上讲,将路由节点用作集群的访问点非常有用,因此您的应用程序无需了解详细信息。

    尽量将主节点与数据节点分开,因为它将减少所有群集的负载。

    以下时间开始考虑专用主节点:

    1. 群集大小开始变得难以驾驭,可能像10个节点或更高?
    2. 您会看到由于负载导致集群不稳定(通常由内存压力引起,导致长GC,导致主节点暂时从集群中退出)您会看到由于负载导致集群不稳定(通常由内存压力引起,导致长GC,导致主节点暂时从集群中退出)

    分离主节点的主要目的是使“主节点的职责”与负载隔离,因为高负载可能导致长GC,从而导致集群不稳定。

    分离主节点后,一个高负载的集群只会影响数据节点(显然仍然不好),但能保证主节点稳定,一旦集群超载,基本上专门的主节点给你喘息的空间,而不是整个集群走向崩溃。

    另外,与数据节点相比,主节点通常可以非常“轻”。几GB的RAM,中等CPU,普通磁盘等或许就能满足需求(需要根据实际业务场景权衡)。

    推荐阅读:http://t.cn/E7HM4ML

    6.2 分配合理的堆内存

    搜索引擎旨在快速提供答案。 为此,他们使用的大多数数据结构必须驻留在内存中。 在很大程度上,他们假设你为他们提供了足够的记忆。 如果不是这种情况,这可能会导致问题 - 不仅仅是性能问题,还有集群的可靠性问题。

    合理的堆内存大小配置建议:宿主机内存大小的一半和31GB,取最小值

    推荐阅读:https://blog.csdn.net/laoyang360/article/details/79998974

    6.3 设置合理的分片数和副本数

    shard数量设置过多或过低都会引发一些问题。

    1. shard数量过多,则批量写入/查询请求被分割为过多的子写入/子查询,导致该index的写入、查询拒绝率上升;

    对于数据量较大的index,当其shard数量过小时,无法充分利用节点资源,造成机器资源利用率不高 或 不均衡,影响写入/查询的效率。

    对于每个index的shard数量,可以根据数据总量、写入压力、节点数量等综合考量后设定,然后根据数据增长状态定期检测下shard数量是否合理。

    腾讯基础架构部数据库团队的推荐方案是:

    1. 对于数据量较小(100GB以下)的index,往往写入压力查询压力相对较低,一般设置3~5个shard,副本设置为1即可(也就是一主一从,共两副本)
    2. 对于数据量较大(100GB以上)的index:一般把单个shard的数据量控制在(20GB~50GB)

    让index压力分摊至多个节点:可通过index.routing.allocation.totalshardsper_node参数,强制限定一个节点上该index的shard数量,让shard尽量分配到不同节点上

    综合考虑整个index的shard数量,如果shard数量(不包括副本)超过50个,就很可能引发拒绝率上升的问题,此时可考虑把该index拆分为多个独立的index,分摊数据量,同时配合routing使用,降低每个查询需要访问的shard数量。

    ——建议参考:https://blog.csdn.net/laoyang360/article/details/78080602

    6.4 设置合理的线程池和队列大小

    节点包含多个线程池,以便改进节点内线程内存消耗的管理方式。 其中许多池也有与之关联的队列,这允许保留挂起的请求而不是丢弃。

    search线程——用于计数/搜索/推荐操作。 线程池类型为fixed_auto_queue_size,大小为int((available of available_ * 3)/ 2)+ 1,初始队列大小为1000。

    5.X版本之后,线程池设置是节点级设置。因此,无法通过群集设置API更新线程池设置。
    查看线程池的方法:

    GET /_cat/thread_pool
    

    6.4 硬件资源的实时监控

    排查一下慢查询时间点的时候,注意观察服务器的CPU, load average消耗情况,是否有资源消耗高峰,可以借助:xpack、cerbero或者elastic-hd工具查看。

    当您遇到麻烦并且群集工作速度比平时慢并且使用大量CPU功率时,您知道需要做一些事情才能使其再次运行。 当Hot Threads API可以为您提供查找问题根源的必要信息。 热线程hot thread是一个Java线程,它使用高CPU量并执行更长的时间。

    Hot Threads API返回有关ElasticSearch代码的哪一部分是最耗费cpu或ElasticSearch由于某种原因而被卡住的信息。

    热线程使用方法:

    GET /_nodes/hot_threads
    

    7、小结

    回答文章开头的问题:——为什么Elasticsearch查询变得这么慢了?
    和大数据量的业务场景有关,您可以通过几个简单的步骤优化查询:

    1. 启用慢速日志记录,以便识别长时间运行的查询
    2. 通过_profiling API运行已识别的搜索,以查看各个子查询组件的时间通过_profiling API运行已识别的搜索,以查看各个子查询组件的时间
    3. 过滤,过滤,过滤过滤,过滤,过滤
      在这里插入图片描述

    Elasticsearch优化非一朝一夕之功,需要反复研究、实践甚至阅读源码分析。
    本文综合了国外、国内很多优秀的实践建议,核心点都已经实践验证可行。
    欢迎大家留言讨论!

    参考:
    http://t.cn/E7HJaPI
    http://t.cn/RQSwH4X
    http://t.cn/RInoI4c

    这里写图片描述
    打造Elasticsearch基础、进阶、实战第一公众号!

    展开全文
  • 一、Elasticsearch Count查询 当我们使用 Elasticsearch 的时候,如果只想知道符合条件的结果集,应该怎么查询? 更多教程点击: Elasticsearch教程 。 1.1 Elasticsearch count Java API 查询   Client...

    https://www.sojson.com/blog/206.html

     

    一、Elasticsearch Count查询

    当我们使用  Elasticsearch  的时候,如果只想知道符合条件的结果集,应该怎么查询?

    更多教程点击:  Elasticsearch教程  。

    1.1 Elasticsearch count Java API 查询

    
     
    1. Client client = ESTools.client;
      SearchResponse response = client.prepareSearch(MappingManager.ASK)
      .setTypes(MappingManager.ASK)
      .setQuery(new TermQueryBuilder("id", id))//设置查询类型
      .setSearchType(SearchType.COUNT)//设置查询类型,有的版本可能过期
      .setSize(0)//设置返回结果集为0
      .get();
      long length = response.getHits().totalHits();

    最后返回了符合结果集的Count 数量,但是不返回结果集,不反回结果集靠size = 0  来决定,当然我觉得  Elasticsearch  在一些版本里应该会对数据级别的Count 查询应该有更好的优化,自己对应想当前版本的  API  。我的Version:2.0.2 。

    1.2 Elasticsearch count Http API 查询

    
     
    1. POST - http://192.168.0.1:9200/index/type/_search/
    2. {
    3. "size" : 0,
    4. "query" : {
    5. "term" : {
    6. "id" : "adf183208e9a4116353e9d9cd78f2b6a"
    7. }
    8. }
    9. }


     

    1.3 Elasticsearch Index Count查询

    
     
    1. CountResponse response = client.prepareCount("index1","index2").get();
    2. long count = response.getCount();//返回当前index Count数量

    1.4 Elasticsearch Type Count查询

    
     
    1. CountResponse response = client.prepareCount("index1","index2").setTypes("type1","type2").get();
    2. long count = response.getCount();//返回符合条件的数据

    二、Elasticsearch 查询数据是否存在

    我也是认为  Elasticsearch  一些版本会有这个方法。下面看看官方的介绍:https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-exists.html 

    2.1 curl 方式查询数据是否存在:

    查询:

    
     
    1. $ curl -XGET 'http://localhost:9200/twitter/tweet/_search/exists?q=user:kimchy'
    2.  
    3. $ curl -XGET 'http://localhost:9200/twitter/tweet/_search/exists' -d '
    4. {
    5. "query" : {
    6. "term" : { "user" : "kimchy" }
    7. }
    8. }'

     

    返回结果:

    
     
    1. {
    2. "exists" : true
    3. }

      Java  API 我这个版本我没找到,其他版本有一些应该有 Java API 。

    2.2 Elasticsearch Java API 数据Exists判断。

    
     
    1. /**
    2. * 判断数据是否存在
    3. * @param id
    4. * @return
    5. */
    6. public static boolean existsById(String id){
    7. Client client = ESTools.client;
    8. SearchRequestBuilder searchBuilder = client.prepareSearch(MappingManager.ASK)
    9. .setTypes(MappingManager.ASK)
    10. .setQuery(new TermQueryBuilder("id", id))//设置查询类型
    11. .setSearchType(SearchType.COUNT)//设置查询类型,有的版本可能过期
    12. .setSize(0);//设置返回结果集为0
    13. SearchResponse response = searchBuilder.get();
    14. long length = response.getHits().totalHits();
    15. return length > 0;
    16. }

    2.3 Elasticsearch Java API 判断 Index 是否存在。

    
     
    1. //Index 可以多个
    2. ExistsRequest request = new ExistsRequest("index1","index2");
    3. ExistsResponse response = client.exists(request).get();
    4. //返回是否存在
    5. boolean exists = response.exists();

    2.4 Elasticsearch Java API 判断 Type 是否存在。

    
     
    1. //Index 可以多个
    2. ExistsRequest request = new ExistsRequest("index1","index2").types("type1","type2");
    3. ExistsResponse response = client.exists(request).get();
    4. //返回是否存在
    5. boolean exists = response.exists();
    展开全文
  • 一、Elasticsearch Count查询 当我们使用 Elasticsearch 的时候,如果只想知道符合条件的结果集,应该怎么查询? 更多教程点击: Elasticsearch教程 。 1.1 Elasticsearch count Java API 查询 ...
  • Elasticsearch查询数据保存到csv 1.本人使用的ES是版本是7.8,编写python脚本将查询的数据保存到本地csv文件: 注:需要下载elasticsearch模块:pip install elasticsearch from elasticsearch import Elastic...
  • Elasticsearch查询去重

    千次阅读 2018-11-18 23:44:07
    Elasticsearch查询去重 实现查询去重、分页 例如:实现依据qid去重,createTime排序 DSL: GET /nb_luban_answer/_search { "query": { "match": { "status": 1 } }, "...
  • elasticsearch-es查询并清理重复数据

    万次阅读 2019-10-12 20:12:09
    由于数据入库时发生一些错误,导致录入重复数据到es内 第一种办法 根据单个字段进行查询重复数据 POST index/type/_search { "size": 10, "aggs": { "duplicateCount": { "terms": { "field": "link", "min...
  • elasticsearch查询模板示例

    千次阅读 2019-11-10 21:16:34
    elasticsearch查询模板示例 elasticsearch查询模板功能非常强大,可以参数化复杂查询,对于定义用户应用场景非常有帮助。 本文记录一个项目中的示例,希望对你有帮助。 1. 需求描述 统计用户在单位时间内用户数,...
  • Elasticsearch查询模式一种是像传递URL参数一样去传递查询语句,被称为简单查询GET /library/books/_search //查询index为library,type为books的全部内容 GET /library/books/_search?q=price:10 //查询index为...
  • 使用elasticsearch查询百亿级数据必然会影响查询的速度但是es与客户端的的默认响应时间只有30秒查询大量的数据时30秒的时间一般都不够用
  • 场景2 查询范围过大,一次查询过多的分片,如全表扫描查询。 场景3 进行深度翻页查询,如查询10000之后的结果。 场景4 查询返回的结果集过大,如10w。 场景5 查询语句不是最优,如过滤查询可以使用filter。 场景6 ...
  • 其实之前关于ElasticSearch的一些书,感觉对于查询是有点懵逼的,一会查询,一会过滤查询。而且有的语法在6.x的版本上已经废弃了。所以看起来更加困惑了。五一这两天又静下心来看了一些,感觉像我平时的一些基本使用...
  • php elasticsearch查询封装

    千次阅读 2018-09-14 11:03:01
    es收集的数据虽然可以在kibina里展示,但是要局限也比较大,不能用kibina展示的只能自己动手写web展示了,...贴代码吧:es查询拼装类 <?php use Elasticsearch\ClientBuilder; class es { private $es; p...
  • elasticsearch查询时termQuery查询中文匹配失败:

    千次阅读 多人点赞 2019-03-04 16:23:02
    elasticsearch查询时termQuery查询中文匹配失败: NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(QueryBuilders.termQuery("category", "...
  • ElasticSearch查询原理一篇文章搞懂

    千次阅读 2019-06-22 18:11:37
    1ES架构简介 国际惯例,站在上帝的视角看看闻名的ElasticSearch长什么样,由于今天仅仅讲查询模块,所以对图中的大多数模块不会涉及。...2ES查询分类 ElasticSearch支持的查询有三种 query_and_fetch ...
  • 这段代码的功能是查询es里面的数据进行分页展示,使用的jar版本为2.4 大概流程 添加maven依赖 org.elasticsearch elasticsearch 2.4.0 properties属性文件配置 spring.elasticsearch.host
  • 1 Query String Search(查询串检索) 2 Query DSL(ES特定语法检索) 3 Query Filter(过滤检索) 4 Full Text Search(全文检索) 5 Phrase Search(短语检索) 6 Highlight Search(高亮检索) 1 Query String Search...
  • ElasticSearch查询模板

    千次阅读 2018-06-17 17:03:32
    package util; import java.util.Arrays; import java.util.Iterator; import org.apache.lucene.search.Sort; import org.elasticsearch.action.search....import org.elasticsearch.action.search....
  • Elasticsearch查询计数

    万次阅读 2019-05-24 19:03:37
    Elasticsearch提供了计数的api: count. 计数的话就不会返回实际的字段数据,只会返回一个数量,支持所有查询语句。 示例: GET /twitter/tweet/_count { "query" : { "term" : { "user" : "kimchy" } } } 响应...
  • spring data jpa elasticsearch 查询

    千次阅读 2019-05-16 17:17:20
    ElasticSearch AggregationBuilders java api常用聚合查询...ElasticSearch 查询 https://blog.csd...
  • Elasticsearch查询过程

    千次阅读 2016-04-24 11:08:55
    Elasticsearch查询分两个阶段查询阶段和提取阶段 查询阶段 客户端向集群中的某个节点(假设节点1)发起查询请求,节点1会创建一个from+size大小的队列(from:偏移量,size:要取回的文档个数)。 节点1向集群中...
  • ElasticSearch查询—分页查询详解

    万次阅读 2017-12-08 12:35:29
    Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回。那么,如何实现分页查询呢?  按照一般的查询流程来说,如果我想查询前10条数据:  1)客户端请求发给某个节点  2)...
  • 在我们ES的日常使用中,需要根据业务去筛选不等于某一个数值或者字符串的查询,下面我将列出几种实现方式,并比较优缺点,给大家参考。 查询 must_not must_not和must、filter、should属于同一层级,都属于布尔查询...
  • PHP分页+Elasticsearch查询

    千次阅读 2017-05-22 22:10:49
    PHP分页+Elasticsearch查询分页,本质上就是根据给定的页码和偏移量从服务器端请求数据。原理很easy,实践起来却有诸多问题,这里总结一下目前使用的分页demo,通过es请求数据,前端自己构建页码。html的页码显示,...
  • elasticsearch 查询结果最大默认10000

    千次阅读 2019-09-04 22:47:45
    elasticsearch 查询结果默认最大是 10000 可以通过 index.max_result_window 参数进行修改 https://www.elastic.co/guide/en/elasticsearch/reference/6.7/index-modules.html index.max_result_window The maximum ...
  • <groupId>org.elasticsearch <artifactId>elasticsearch <version>7.5.0 <!--es client--> <groupId>org.elasticsearch.client <artifactId>elasticsearch-rest-high-level-client <version>...
  • ElasticSearch查询操作最大sharding数目限制 1. 问题说明 在ES中做一个大范围的查询时,经常会报这个错误: { "error":{ "root_cause":[ { "type":"illegal_argument...
  • Elasticsearch查询match、term和bool区别

    万次阅读 2017-07-17 08:33:02
    elasticsearch 查询(match和term) es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL)。 由于DSL查询更为直观也更为简易,所以大都使用这种方式。 DSL...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 132,753
精华内容 53,101
关键字:

elasticsearch查询