ES在几十亿数据量级的场景下的性能优化

  es性能优化没有什么银弹。不要指望调一个参数,就可以万能的应对所有场景。

1、性能优化杀手锏—filesystem cache

在这里插入图片描述
  ES数据检索的流程如上所示,第一次检索一个数据时是从磁盘里读的,慢;以后读会从filesystem cache中拿,快。filesystem cache是操作系统级的缓存。
  es严重依赖于filesystem cache,如果filesystem cache很大,可以容纳所有的indx segment file索引数据文件,那么搜索时基本都是走内存,性能非常高。走磁盘一般秒级别,走filesystem cache毫秒级。
  一般,尽量让机器内存可以容纳数据量的一半。最佳的情况,仅在es中存少量数据,留给filesystem cache的内存要能存下所有数据,这样数据几乎全部走内存来搜索,性能非常高,一般可以在1秒以内。比如现在有一行数据,id name age …30个字段,现在只需要根据id name age三个字段来搜索,就可以只写入这几个字段,然后其他字段存在mysql或hbase中。建议用es + hbase的。
  hbase适用于海量数据的在线存储,不做复杂搜索,就做简单的根据id或者范围查询就可以了。从es中根据name和age去搜索,结果可能就10个doc id,然后根据doc id到hbase里去查询每个doc id对应的完整数据,再返回给前端即可。

2、数据预热

  做一个缓存预热系统,专门用于对那些比较热的数据,每隔一段时间访问一下,让数据进入filesystem cache。比如微博,看的人很多的数据;再比如电商的热门商品P30。

3、冷热分离

  大量的冷门数据一个索引;热数据另一个索引。这可确保热数据在被预热后,尽量都留在filesystem os cache里,别让冷数据给冲刷掉。

4、document模型设计

订单表:id、order_code、total_price
订单条目表:id、order_id、goods_id、purchase_count、price

  mysql可以很方便的进行多表关联查询。但是在es中,复杂的关联查询尽量别用,用了性能不好。对于这种情况,设计es数据模型可以搞成两个索引,order索引,orderItem索引

order索引:id、order_code、total_price
orderItem索引:id、order_code、total_price、id、order_id、goods_id、purchase_count、price

  首先完成两种数据的关联,然后再将关联好的数据直接写入es中,搜索时,就不需要利用es的语法去完成join了。
  总之,对于太复杂的操作,比如join,nested,parent-child搜索都要尽量避免。对于要执行一些复杂操作的思路:
1)在写入时,就设计好模型,加几个字段专门用于存放处理好的数据。
2)用es查出来,然后在程序中封装。

5、分页性能优化

  es的分页是比较坑。假如每页10条数据,现在要查询第100页,实际上会把每个shard上的前1000条数据都查到协调节点上,如果有5个shard,协调节点就要对这5000条数据进行一些合并、处理,再获取到最终第100页的10条数据。
  翻页时,越深,处理的数据就越多。所以我们会发现越翻到后面,就越是慢。
  解决方法:
(1)不允许深度分页
系统不允许翻页太深,产品经理可能不同意。
(2)基于scroll api
在这样一些场合,比如app里的推荐商品不断下拉出一页一页的数据,可以基于scroll api来做。
scroll的原理是一次性生成所有数据的快照,每次翻页就是通过游标移动,获取下一页数据,这个性能是很高的,无论翻多少页,都是毫秒级的。
缺陷:
1)适合一页一页往下翻,不能随意跳,也不能往上翻。
2)要保留一段时间内的数据快照,需要确保用户不会持续翻页几个小时。

发布了104 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zjuwzp/article/details/99696413