【搜索引擎】 4-ES在大数据量下提高查询效率方案

avatar 2020年11月26日10:24:22 6 3727 views
博主分享免费Java教学视频,B站账号:Java刘哥

在一些公司里,很多数据都喜欢丢到 ES 里,甚至有的人把其充当数据库的使用,这样是很危险的。很可能过个半年一年ES数据量就很大了,然后当时的申请的ES机器配置不高,查询速度变慢。所以,一开始架构评审应该做好,预计几年内数据量的规模,从而选择什么样配置的ES集群。下面说几个比较重要的优化方面。

一、给机器预留足够的系统内存

前面我们已经讲过,es查询数据先从内存(即 os cache)中查询,查不到再去磁盘(segment file) 中查询。

从内存中查询基本都是几十毫秒到几百毫秒,从磁盘查询可能要好几秒。

为了保证 ES 能尽量从内存中查询,我们需要确保系统有足够的剩余内存可以使用。

比如一台ES的节点机器有 64GB 内存,我们可以给ES进程分配32GB(即JVM参数设置最大堆32GB),然后留32GB作为 os cache 的内存。然后我们尽量确保这台ES节点上的索引数据不要超过剩余可用内存(即32GB), 这样就能最大程度保证尽量走内存查询而非磁盘查询。

 

二、ES只存必要的字段

因为我们的内存容量有限,所以尽量不要把所有的数据写在内存里,因此每个索引的字段也不要太多。

比如商品信息的索引,我们可以只存ID、标题、类别、品牌、价格等用于搜索的必要字段。然后其他字段可以存储在MySQL或HBase等关系型数据库中,推荐使用 ES + HBase。

也就是说,用户根据标题搜素标题,查到5个,然后用这个5个的id去MySQL/HBase数据库查询,因为id一般有索引查询会比较快。

 

三、数据预热,定时主动搜索

对于那些比较热门或者访问量高的数据,可以做一个专门的缓存预热子系统,每隔一段时间,主动去搜索一下ES,把数据刷到 os cache 里。

 

四、冷热分离

可以把热门的数据单独放到一个索引里,当然这个索引是放在新的更高配的机器上。冷门的数据的索引,可以放在低配的机器上。

 

五、doucment设计,适当冗余关联字段

为了提高查询速度,避免使用 join/nested/parent-child 等关联查询操作,我们的 document 可以适当冗余字段。

比如MySQL商品表有 ID、店铺ID、品牌ID、分类ID、标题、价格。我们可以把店铺名称、店铺等级、品牌名称和分类名称也冗余对应 document 里。这样可以直接根据品牌名称或者店铺名称来搜商品。

 

六、分页性能优化

ES分页很坑,前几页一般比较快,后面的就比较慢了。比如有5个分片(primary shard),每个分片有1000条数据,总共5000条数据。一页10条,查询第50页,协调节点需要在每个shard上查询前500条数据,然后把5个shard数据合并排序,再筛选拿出10条。

 

解决办法:

1. 不允许深度分页,比如只允许查看前面10页

2. 前端控制不允许跳页,只能一页一页翻,可以一次性多查询一些数据,存储在前端缓存里,分页时前端自己拿数据,减少调用后台次数

 

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:0   待审核评论数:0