前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES查询性能调优实践,亿级数据查询毫秒级返回

ES查询性能调优实践,亿级数据查询毫秒级返回

作者头像
腾讯移动品质中心TMQ
发布2019-05-16 15:41:08
18.4K0
发布2019-05-16 15:41:08
举报

1、概述

本文简要描述ES查询性能的优化过程。忽略很多细节,其实整个过程并不顺利,因为并没有一个明确的指引,教你怎么做就能让性能大幅提升。很多时候不同业务有不同的场景,还是需要自己摸索一番。比如用filter过滤取代query查询,明明官方文档说filter速度更快。但应用到我们业务来,一开始却没有明显效果。经过反复测试,发现虽然filter可以省略计算分数的环节,但我们的业务查询场景,一次返回数据量不会很多,最大的瓶颈不在于打分,而在于range过滤和排序。可是range过滤和排序,这方面在网上却很少被提及。所以还是要自己根据业务场景多思考多验证。 一开始优化效果很突出,耗时从100秒一下子降低到10秒以内。但越往后其实越难做。好比从10分考到60分不容易,但90分考到95分就更加困难。 我们自己定的优化目标是1秒,是达到效果了。

2、ES查询性能优化效果

优化前,随便一个ES查询耗时就高达170秒,接近3分钟。

注意上面的ES查询语句还不是最复杂的,还可以加上qua搜索、关键词模糊搜索,再把日期范围拉长,再加上日期排序。无法想像,耗时会变得多么惨不忍睹,简直要变成离线查询了。

可实际上,yiya页面是在线用户进行实时查询,所以这么高的耗时是不能忍受的,需要优化。那么,数据量有上亿,耗时优化到多少才合适呢?作为一个实时接口,能不能做到1秒内ES查询返回结果呢?

经过优化,ES查询耗时从之前的动辄3分钟,已经变成毫秒级了。

3、ES查询性能调优

3.1 拆分索引

ES能存千亿数据,不表示你可以在匹配到千亿数据时还能秒级返回。拆分索引是指你在搜索时,必须尽量缩小搜索的数据集范围。

  1. 按照数据源拆分,每个数据源独立索引。
  2. 按照时间拆分,每月建索引。

原先是按照数据源天然地分开索引。但日积月累,单个数据源的数据也日益膨胀,月新增一亿条数据。所以要按照时间拆分,把单个数据源按照年月进一步地拆分。

3.2 字段拉平

原先是把几个搜索字段都放在extra_info里面,导致只能在extra_info进行搜索。这带来两个问题:

  1. extra_info字段巨大,查询性能很低。
  2. 由于extra_info字段是黑盒,只能在里面进行模糊匹配,性能进一步降低。

优化后,把搜索字段全部拉平到上一层,不再从extra_info字段进行查询。

3.3 减少模糊匹配

模糊匹配耗时会随数据量线性增长,尽量使用match匹配(有索引),避免使用模糊匹配(wildcard)。 跟yiya业务方沟通过,qua字段的搜索没有必要是模糊搜索,所以修改为精确匹配。 但业务方要求关键词搜索必须是模糊搜索。不过即使模糊匹配,也尽量避免左模糊这样的模式匹配,资源消耗严重。可以使用match进行分词搜索。

3.4 使用日期字段搜索范围

原先ES的日期date_created字段是用字符串存储。

但对字符串的字段类型进行range过滤并不高效。 字符串范围适用于一个基数较小的字段,一个唯一短语个数较少的字段。你的唯一短语数越多,搜索就越慢。 数字和日期字段的索引方式让他们在计算范围时十分高效。但对于字符串来说却不是这样。为了在字符串上执行范围操作,Elasticsearch 会在这个范围内的每个短语执行 term 操作。这比日期或数字的范围操作慢得多。 优化后,date_created字段改成日期类型。

3.5 使用过滤器上下文

原先使用的是query查询子句,优化后改成filter过滤器。 query查询子句用于回答“这个文档与此子句相匹配的程度”,而filter过滤器子句用于回答“这个文档是否匹配这个子句”,Elasticsearch只需要回答“是”或“否”,不需要为过滤器子句计算相关性分数,而且过滤器结果可以缓存。 查询在Query查询上下文和Filter过滤器上下文中,执行的操作是不一样的:

  1. 查询上下文: 在查询上下文中,查询会回答这个问题——“这个文档匹不匹配这个查询,它的相关度高么?” 如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂的,因此也需要一定的时间。 查询上下文 是在 使用query进行查询时的执行环境,比如使用search的时候。
  2. 过滤器上下文: 在过滤器上下文中,查询会回答这个问题——“这个文档匹不匹配?” 答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。 过滤上下文 是在使用filter参数时候的执行环境,比如在bool查询中使用Must_not或者filter。 另外,过滤器上下文中,查询的结果可以被缓存。

filter速度要快于query,filter是不计算相关性的,同时可以cache。所以尽可能使用过滤器上下文(Filter)替代查询上下文(Query)。 因为业务场景并不需要计算相关性分数,所以改用filter。

后期我们会根据每个维度陆续写相关的测试文章,如果你有兴趣,请关注我们哦。


长按指纹识别图中的二维码,获取更多测试干货分享!

 将我们公众号置顶 

 不会漏掉我们的原创干货哦!

var first_sceen__time = (+new Date());if ("" == 1 && document.getElementById('js_content')) { document.getElementById('js_content').addEventListener("selectstart",function(e){ e.preventDefault(); }); } (function(){ if (navigator.userAgent.indexOf("WindowsWechat") != -1){ var link = document.createElement('link'); var head = document.getElementsByTagName('head')[0]; link.rel = 'stylesheet'; link.type = 'text/css'; link.href = "//res.wx.qq.com/mmbizwap/zh_CN/htmledition/style/page/appmsg_new/winwx45ba31.css"; head.appendChild(link); } })();

马捷驰

赞赏

长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

阅读

分享 在看

已同步到看一看

取消 发送

我知道了

朋友会在“发现-看一看”看到你“在看”的内容

确定

已同步到看一看写下你的想法

最多200字,当前共字 发送

已发送

朋友将在看一看看到

确定

写下你的想法...

取消

发布到看一看

确定

最多200字,当前共字

发送中

微信扫一扫 关注该公众号

微信扫一扫 使用小程序

即将打开""小程序

取消 打开

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯移动品质中心TMQ 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2、ES查询性能优化效果
  • 3、ES查询性能调优
    • 3.1 拆分索引
      • 3.2 字段拉平
        • 3.3 减少模糊匹配
          • 3.4 使用日期字段搜索范围
            • 3.5 使用过滤器上下文
            相关产品与服务
            云开发 CloudBase
            云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档