ES搜素性能分析
性能优化杀手锏-filesystem cache
ES 的搜索引擎严重依赖底层的fileSystem cache,如果过能给到FileSystem cache更多的内存,尽可能让内存容纳所有的index segment file索引数据文件,那么搜索的时候基本都是走内存的,性能会非常高
fileSystem Cache 对ES搜索效率的影响
ES 搜索走FileSystemCache 和 走磁盘的性能差距有多大:如果搜索走的是磁盘文件检索,那么响应的时间基本上是在s级别,如果是在FileSystem-cache中获取,则响应的时间基本是在ms,一般来说是几ms到几百ms之间不等
根据上面的数据量来推断,如果总的数据量是1T左右,那么所有的ES集群中的FileSystem-cache加起来最少要得有半数的内存,这样你的ES检索速度才能提上来,性能是可以直接到2,3,5s
ES存储数据限制,简单来说,如果在检索的时候,只需要根据id, name, age三个字段来搜索,但是在每次往es写入数据的时候,直接往es中存入了所有的数据,这就导致每一个数据中的70%的数据是不用搜索的,但是这些数据硬生生占用了FileSystemCache的空间
一般来说可以通过ES+Hbase来进行大数据量检索,因为hbase支持大数据量的存储,但是检索性能着实太低,所以,可以使用ES来检索关键数据,然后由Hbase来补充其余数据就可以
从ES中根据name和age去进行检索,然后获取的结果可能就是20个doc id,然后根据doc id去hbase中查询每个doc id对应的完整的数据,将结果查询出来,然后再返回给前端,这样的性能完全是ms级的
所以说最好的方式就是ES中只存放检索的数据,然后其他的数据存放在Mysql或者hbase中,最好的就是Es 中存放的数据尽量不要大于file system cache 的空间,或者是略微大于
数据预热
上述可以解决一定的问题,但是如果Es中存储的数据着实超过了file system cahe的空间,还可以通过数据预热的方式来进行查询效率的优化,写一个定时任务,每隔一段时间执行一下慢查询的数据,这样用户体验起来要好很多
冷热分离,最好是将冷数据写入一个索引中,然后热数据写入另一个索引中,这样可以确保热数据被预热知乎,尽量让他们都留在fileSystem OS cache中,别让冷数据冲刷掉,类似于Mysql的水平拆分,有一台Shard专门处理热数据检索
document模型设计
document模型设计是非常重要的,尽量不要去执行es的复杂操作,譬如说join, nested,parent-child搜索都需要避免,性能很差,能用java处理的操作用java处理,然后es只做简单的查询
分页查询的性能优化
es的分页其实是比较坑的,举个例子,每页10条数据,现在查询第100页,实际上就是会把每个shard上存储的前1000条数据都查到一个协调节点上,假如说有5个es,就会将获取到5000条数据,然后对这些数据进行合并,处理,然后再获取到最终100页的10条数据
翻页的时候,翻的越深,每个shard返回的数据就越多,而且协调节点处理的时间越长,比较坑,所以用es做分页的时候,越到后面,就越慢
针对这个问题,可以采用用scroll来进行处理,scroll的原理实际上就是保留一个数据快照,然后在一定时间内,如果不断地滑动往后翻页的时候,类似于现在浏览微博,不断往下刷新翻页,那么就用scroll不断通过游标获取下一页数据,这个性能是很高的,但是有个问题,scroll不能做到随机翻页,只能直接往下滑,所以可用性还是比较局限
不允许深度分页/默认深度分页性能很差