前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES大数据量下的查询优化

ES大数据量下的查询优化

作者头像
名字是乱打的
发布2021-12-24 08:55:28
1.8K0
发布2021-12-24 08:55:28
举报
文章被收录于专栏:软件工程

在数据规模很大(比如万恶的trace日志)的时候我们有时候会发现第一次访问查询特别慢,可能有几秒钟的样子,然后后面的访问就很快了,这是为啥?

filesystem cache对es性能的影响.png

一 .filesystem的影响

filesystem类似于我们在mysql上建立一层redis缓存;

es的搜索引擎严重依赖于底层的filesystem cache,如果给filesystem cache更多的内存,尽量让内存可以容纳所有的indx segment file索引数据文件,那么你搜索的时候就基本都是走内存的,性能会非常高。

两者差距非常大,走磁盘和走systenfile cache的读取的性能差距可以说是秒级和毫秒级的差距了;

举个反例: 有个同学es节点有3台机器,每台机器,看起来内存很多,64G,总内存,64 * 3 = 192g 但是每台机器给es jvm heap是32G,那么剩下来留给filesystem cache的就是每台机器才32g,总共集群里给filesystem cache的就是32 * 3 = 96g内存; 结果es里写了1t的数据,那么一个结点就是333G数据,只有十分之一的数据可以进走内存就返回,剩下的全都走磁盘,这样就导致我们数据可能十秒钟才写到cache再回去;

要让es性能要好,最佳的情况下,就是我们的机器的内存,至少可以容纳你的数据量的一半

二生产es的建议

1.尽量少存数据(存储搜索条件即可),让内存可以存储更多值

最佳的情况下,是仅仅在es中就存少量的数据,存储要用来搜索的那些索引,内存留给filesystem cache的,如果就100G,那么你就控制数据量在100gb以内,相当于是,你的数据几乎全部走内存来搜索,性能非常之高,一般可以在1秒以内

比如说现在有一行数据 id name age ....30个字段 但是你现在搜索,只需要根据id name age三个字段来搜索 如果你傻乎乎的往es里写入一行数据所有的字段,就会导致说70%的数据是不用来搜索的,结果硬是占据了es机器上的filesystem cache的空间,单挑数据的数据量越大,就会导致filesystem cahce能缓存的数据就越少 仅仅只是写入es中要用来检索

的少数几个字段就可以了,比如说,就写入es id name age三个字段就可以了,然后你可以把其他的字段数据存在mysql里面,我们一般是建议用es + hbase的一个架构。 hbase的特点是适用于海量数据的在线存储,就是对hbase可以写入海量数据,不要做复杂的搜索,就是做很简单的一些根据id或者范围进行查询的这么一个操作就可以了

2.数据预热

如果确实内存不足,但是我们又存储了比较多的数据,比如只有30g给systemfile cache,但是存储了60g数据情况,这种情况可以做数据预热;

我们可以将一些高频访问的热点数据(比如微博知乎的热榜榜单数据,电商的热门商品(旗舰版手机,榜单商品信息)等等)提前预热,定期访问刷到我们es里;(比如定期访问一下当季苹果旗舰手机关键词,比如现在的iphone12)

对于那些你觉得比较热的,经常会有人访问的数据,最好做一个专门的缓存预热子系统,就是对热数据,每隔一段时间,提前访问一下,让数据进入filesystem cache里面去。这样下次别人访问的时候,一定性能会好一些。

3.冷热分离

我们可以将冷数据写入一个索引中,然后热数据写入另外一个索引中,这样可以确保热数据在被预热之后,尽量都让他们留在filesystem os cache里,别让冷数据给冲刷掉。

假设我们有6台机器,2个索引,一个放冷数据,一个放热数据,每个索引3个shard 3台机器放热数据index;另外3台机器放冷数据index 然后这样的话,我们大量的时候是在访问热数据index,热数据可能就占总数据量的10%,此时数据量很少,几乎全都保留在filesystem cache里面了,就可以确保热数据的访问性能是很高的。 但是对于冷数据而言,是在别的index里的,跟热数据index都不再相同的机器上,大家互相之间都没什么联系了。如果有人访问冷数据,可能大量数据是在磁盘上的,此时性能差点就差点吧,就10%的人去访问冷数据;90%的人在访问热数据。

4.尽量不走多索引的关联查询

尽量做到设计document的时候就把需要数据结构都做好,这样搜索的数据写入的时候就完成。对于一些太复杂的操作,比如join,nested,parent-child搜索都要尽量避免,性能都很差的。

5.分页性能优化

es的分页是较坑的,为啥呢?举个例子吧,假如你每页是10条数据,你现在要查询第100页,实际上是会把每个shard上存储的前1000条数据都查到一个协调节点上,如果你有个5个shard,那么就有5000条数据,接着协调节点对这5000条数据进行一些合并、处理,再获取到最终第100页的10条数据。

因为他是分布式的,你要查第100页的10条数据,你是不可能说从5个shard,每个shard就查2条数据?最后到协调节点合并成10条数据?这样肯定不行,因为我们从单个结点上拿的数据几乎不可能正好是所需的数据。我们必须得从每个shard都查1000条数据过来,然后根据你的需求进行排序、筛选等等操作,最后再次分页,拿到里面第100页的数据。

你翻页的时候,翻的越深,每个shard返回的数据就越多,而且协调节点处理的时间越长。非常坑爹。所以用es做分页的时候,你会发现越翻到后面,就越是慢。

我们之前也是遇到过这个问题,用es作分页,前几页就几十毫秒,翻到10页之后,几十页的时候,基本上就要5~10秒才能查出来一页数据了

优化建议
  • 1)不允许深度分页/默认深度分页性能很惨

你系统不允许他翻那么深的页,或者产品同意翻的越深,性能就越差

  • 2)类似于app里的推荐商品不断下拉出来一页一页的

如果是类似于微博中,下拉刷微博,刷出来一页一页的,可以用scroll api scroll api1 scroll api2 scroll会一次性给你生成所有数据的一个快照,然后每次翻页就是通过游标移动,获取下一页下一页这样子,性能会比上面说的那种分页性能也高很多很多

scroll的原理实际上是保留一个数据快照,然后在一定时间内,你如果不断的滑动往后翻页的时候,类似于你现在在浏览微博,不断往下刷新翻页。那么就用scroll不断通过游标获取下一页数据,这个性能是很高的,比es实际翻页要好的多的多。

缺点:

  • 这个适合于那种类似微博下拉翻页的,不能随意跳到任何一页的场景。 因为scroll api是只能一页一页往后翻的,是不能说,先进入第10页,然后去120页,回到58页,不能随意乱跳页。所以现在很多产品,都是不允许你随意翻页的,app,也有一些网站,做的就是你只能往下拉,一页一页的翻,无论翻多少页,性能基本上都是毫秒级的
  • 同时这个scroll是要保留一段时间内的数据快照的,需要确保用户不会持续不断翻页翻几个小时。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/8/19 上,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 .filesystem的影响
  • 二生产es的建议
    • 1.尽量少存数据(存储搜索条件即可),让内存可以存储更多值
    • 2.数据预热
    • 3.冷热分离
    • 4.尽量不走多索引的关联查询
    • 5.分页性能优化
      • 优化建议
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档