如同磁铁吸引四周的铁粉,热情也能吸引周围的人,改变周围的情况。

es windows服务启动时的权限问题

medcl 回复了问题 • 2 人关注 • 1 个回复 • 4901 次浏览 • 2017-10-18 15:04 • 来自相关话题

Elasticsearch5.X添加search-guard后TransportClient java连接权限问题?

yanlei 回复了问题 • 2 人关注 • 3 个回复 • 3446 次浏览 • 2017-10-11 14:27 • 来自相关话题

Elasticsearch 5.2.0启动后出现提示某节点[default_local]还没准备好

kennywu76 回复了问题 • 2 人关注 • 1 个回复 • 2077 次浏览 • 2017-10-09 11:34 • 来自相关话题

elastic2.3自定义插件,监测index变化,postIndex,postCreate的执行让我无法理解

kennywu76 回复了问题 • 2 人关注 • 1 个回复 • 2949 次浏览 • 2017-10-09 14:17 • 来自相关话题

搜索条件是否可以增加_score的过滤

shiyuan 回复了问题 • 3 人关注 • 1 个回复 • 3957 次浏览 • 2017-10-03 20:51 • 来自相关话题

ScrollID返回的一样

dengdaixiyuan 回复了问题 • 4 人关注 • 4 个回复 • 4824 次浏览 • 2018-01-31 10:41 • 来自相关话题

用keyword类型做时间范围查询靠谱吗?

liang637210 回复了问题 • 4 人关注 • 3 个回复 • 6173 次浏览 • 2017-10-10 14:38 • 来自相关话题

请问各位大神们,ElasticSearch中的各种request和requestBuilder是个什么样关系呢

回复

shengya 回复了问题 • 1 人关注 • 1 个回复 • 2390 次浏览 • 2017-09-30 11:33 • 来自相关话题

ES向Hadoop插入数据时出现异常[HEAD] on [索引/类型] failed

xuezhixu 回复了问题 • 3 人关注 • 4 个回复 • 10091 次浏览 • 2018-07-18 13:57 • 来自相关话题

ES2.4版本,completion suggest的中文支持

回复

private_void 发起了问题 • 1 人关注 • 0 个回复 • 3221 次浏览 • 2017-09-30 09:24 • 来自相关话题

一例Query Cache引起的性能问题分析

kennywu76 发表了文章 • 6 个评论 • 8329 次浏览 • 2017-09-29 19:18 • 来自相关话题

【携程旅行网 吴晓刚】

注:本文是针对Elastic中文社区问题[question#2484](https://elasticsearch.cn/question/2484) 的分析和总结。

问题概述


一个线上集群,执行的Query DSL都是一样的,只是参数不同。 统计数据显示98-99%的查询响应速度都很快,只需要4 -6ms, 但有1%左右的查询响应时间在100ms - 200ms。 集群硬件配置较高,使用的SSD,系统可用内存远高于索引文件大小总和,并且线上已经运行有一段时间,数据应该已经充分预热。

***

诊断过程及结论


比较巧的是,问题提出者刚好是我们自家公司的开发者,因此内部联系沟通了下,为问题的快速诊断提供了不少便利。

首先用公司的监控系统排查了一遍集群所有关键数据,未发现任何可能引起查询耗时高的性能瓶颈问题。 因此初步怀疑就是有查询本身比较慢。 幸好公司有应用埋点系统和日志系统,因此很方便的拿到了应用端发出的一些慢查询样例,包括请求体以及耗时。

以下是埋点系统里记录的一个耗时150ms的查询 (隐去了敏感信息,去掉了非关键部分):

json<br /> POST /xxxindex/xxxdb/_search?routing=Mxxxxxxx<br /> {<br /> "from": 0,<br /> "size": 100,<br /> "query": {<br /> "bool": {<br /> "filter": [<br /> {<br /> "bool": {<br /> "must": [<br /> {<br /> "bool": {<br /> "must": [<br /> {<br /> "bool": {<br /> "should": [<br /> {<br /> "match_phrase": {<br /> "ord_orders_uid": {<br /> "query": "Mxxxxxxx",<br /> "slop": 0,<br /> "boost": 1<br /> }<br /> }<br /> }<br /> ],<br /> "disable_coord": false,<br /> "adjust_pure_negative": true,<br /> "boost": 1<br /> }<br /> },<br /> {<br /> "range": {<br /> "ord_orders_orderdate": {<br /> "from": "1405032032",<br /> "to": "1504014193",<br /> "include_lower": true,<br /> "include_upper": true,<br /> "boost": 1<br /> }<br /> }<br /> },<br /> {<br /> "term": {<br /> "ord_orders_ispackageorder": {<br /> "value": 0,<br /> "boost": 1<br /> }<br /> }<br /> },<br /> {<br /> "bool": {<br /> "must_not": [<br /> {<br /> "exists": {<br /> "field": "ord_hideorder_orderid",<br /> "boost": 1<br /> }<br /> }<br /> ],<br /> "disable_coord": false,<br /> "adjust_pure_negative": true,<br /> "boost": 1<br /> }<br /> }<br /> ],<br /> "disable_coord": false,<br /> "adjust_pure_negative": true,<br /> "boost": 1<br /> }<br /> }<br /> ],<br /> "disable_coord": false,<br /> "adjust_pure_negative": true,<br /> "boost": 1<br /> }<br /> }<br /> ],<br /> "disable_coord": false,<br /> "adjust_pure_negative": true,<br /> "boost": 1<br /> }<br /> }<br /> }<br />

拿到查询后,自己手动执行了一下,0 hits,耗时1ms。  心里明白,命中了Query Cache,所以才会这么快。 

于是用clear api清掉Query Cache,然后再执行几次,有以下发现:

  • 头两次查询耗时38ms左右。 这是因为没有cache,需要访问倒排索引,耗时符合预期。 之所以两次同样耗时,是因为索引有1个复制片,两次查询分别分配到主和副片上。
  • 接下来两次查询耗时150ms左右。  这里要打一个大大的问号???
  • 之后不管再查询多少次, 耗时全部是1ms,因为又开始命中Cache。

    至此,大致明白,埋点系统里记录到的高耗时查询,是步骤2的两次操作。 什么操作耗时这么久呢? 根据经验,我判断主要是用于为range filter生成缓存,也就生成生成文档列表的bitmap,然后存放到Query Cache里。 

    这个集群版本是5.1.1, 而我记得ES某个5版本开始,去掉了对term filter的cache,理由是term filter速度足够快,缓存term filter往往得不偿失。 查了官方release notes,证实这个改变正好是从5.1.1开始的[#21566](https://github.com/elastic/elasticsearch/pull/21566),因此上面查询里的term filters被排除掉,注意力集中到了查询里唯一的一个range filter。 

    单独执行了一下这个range filter,match的文档是千万数量级的。 询问用户,为何这个range filter会hit这么多文档,得知用户主要就是查询从当前时间开始至过去1年的数据,类似于做了一个now-1y  TO now这样的过滤。至此初步得出结论,因为这个range filter匹配的文档太多了,在Query Cache里为这个filter构建bitmap耗时会有些高,应该就是它带来了那额外的100多个ms。

    但是还有一个待解释的问题,这种高耗时查询比例为何这么高? 再仔细想想也就明白了:因为这个集群的搜索并发量还是有点高,300 -400/s的样子,加上时间字段的精度是秒,所以,在某一秒刚开始的时候,头2次查询因为没有cache,耗时可能在38ms左右,之后会有2次查询因为需要缓存range filter,耗时会增加到150-200ms的样子,之后这1秒里剩余的查询都会命中cache,全部是几个ms, 直到下一秒开始, 周而复始。 因为每秒钟都产生2个这样需要构建缓存的查询,耗时较高,对比每秒几百次的查询量,换算成百分比就有点高了。

    那么怎么解决这个问题? 对于大量含有从now-xxx TO now这样的range查询,实际上官方的文档有对应的加速技巧介绍:[tune-for-search-speed.html#_search_rounded_dates](https://www.elastic.co/guide/e ... _dates) 。也就是说,将查询时间的上下限round到整分钟,或者整小时,让range filter可以缓存得更久,避免出现这种过于频繁重建cache的情况。
    json<br /> {<br /> "range": {<br /> "my_date": {<br /> "gte": "now-1y/h",<br /> "lte": "now-1y/h"<br /> }<br /> }<br /> }<br />

    在原始Query里,将range filter写成上述形式,手动测试证实可行,range filter有效期延长到1小时,从而每个小时里,只需要为range filter重建2次Cache,至此问题解决。

    ---

    总结:


    1. Cache并非建得越多越好,因为Cache的生成和Evict会带来额外的开销。特别是结果集非常大的filter,缓存的代价相对查询本身可能非常高。
    2. ES 5.1.1开始取消了Terms filter Cache,因为Terms filter执行非常快,取消缓存多数情况下反而可以提高性能。
    3. 大量用到Now-xxxd To Now这样的Range filter时,可以借助round date技巧,提高Cache的有效期,减轻频繁重建Cache带来的性能问题。

求大神帮忙

xiaohu 回复了问题 • 2 人关注 • 3 个回复 • 1775 次浏览 • 2017-09-30 11:04 • 来自相关话题

为什么错了?

回复

xiaohu 发起了问题 • 1 人关注 • 0 个回复 • 1810 次浏览 • 2017-09-29 18:21 • 来自相关话题

ES5.6 分页查询问题

回复

benjamin31 发起了问题 • 1 人关注 • 0 个回复 • 3084 次浏览 • 2017-09-29 18:11 • 来自相关话题

elasticsearch-5.5.0集群安装问题

xiaoyang 回复了问题 • 2 人关注 • 1 个回复 • 3789 次浏览 • 2017-09-29 18:15 • 来自相关话题