在一些公司里,很多数据都喜欢丢到 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. 前端控制不允许跳页,只能一页一页翻,可以一次性多查询一些数据,存储在前端缓存里,分页时前端自己拿数据,减少调用后台次数
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏