优化分页查询
优化分页查询可以和分库分表结合在一起,在Elasticsearch里面,当你执行分页查询的时候,是使用FROM X SIZE Y的语法,基本等同于SQL里的OFFSET X LIMIT Y。
如果查询命中了Elasticsearch的N个分片,最终查询的数据量是 N*(X + Y)
在Elasticsearch里面,也有两种可行的优化手段。
- Scroll 和 Scroll Scan:这种方式适合一次性查询大量的数据,比如说导出数据之类的场景,这种用法更加接近你在别的语言或者中间件里面接触到的游标的概念。
- Search After:也就是翻页,在查询的时候需要在当次查询里面加入上一次查询中返回的search_after字段。
在面试的时候建议使用Search After来回答,因为Search After适用的场景更加广泛。
我还优化过Elasticsearch的分页查询,也就是用Search After来优化的,类似于分库分表中使用的禁用跳页查询的方案,也就是不支持随机翻页,每次查询都加入上一次查询的search_after字段。
优点在于查询的数据量不再和偏移量有关,只和每一页的大小,以及命中的分片数量有关。之前在分库分表里也优化过类似的分页查询,不过分库分表本身没有search_after之类的字段,只能是业务层面上搞出来的一个类似的search_after
这里的search_after类似于分库分表中禁用跳页查询里面加入的WHERE id > $max_id
这种极值过滤条件
增大刷新间隔
数据最开始是写入Buffer中,经过refresh菜被写入到Page Cache。基本可以预计,如果频繁地把数据刷新到Page Cache里,性能会有损耗。一个比较简单地优化方案就是调大这个刷新间隔。
之前我优化 Elasticsearch 的时候,把 index.refresh_interval 调大到了 30。调整之后,性能大概提升了 20%。
你可以尝试在自己的业务里面调整这个参数,看看性能提升的幅度。
批量提交
也是前面地内容里见过的优化手段,需要复习一下之前对批量提交为什么能提高性能的分析,在面试Elasticsearch 的适合一样用得到。
批量提交也有两种策略。
第一种策略是化单个为批量。
早期我有一个业务,是把数据库里的数据同步到Elasticsearch ,最开始的时候是每次用户更新了数据,就直接更新Elasticsearch 。但是这样效果很不好,因为用户基本是一条条数据更新 。
后来考虑到这个业务对数据一致性的要求不是很高 ,就把实时同步修改成了异步同步,也就是定时扫描数据库中发生变化的数据,然后批量提交变更数据到Elasticsearch 。
异步任务设置的是每秒同步一次,和原来每一次写请求都要操作Elasticsearch 比起来,压力小很多,同时业务方的响应时间也下降了50%。
这种单个转批次的方案还可以用在kafka和Elasticsearch结合使用的方案中,有些公司的架构把数据写入到Elasticsearch 的时候,并不是直接写入的,而是统一写入到kafka,然后再由一些消费者把Kafka里的数据写入到Elasticsearch 。
这里可以用一个利用批量提交来解决消息积压问题的方案。
我们公司的很多业务都不是直接同步数据到Elasticsearch,而是要经过一个kafka,然后由kafka的消费者把数据写入到Elasticsearch。
但是随着业务的增长,越来越多的数据要写入到Elasticsearch,尤其是在业务高峰期,很容易产生消息积压的问题。
为了解决这个问题,做了一个优化就是批量消费,批量提交到Elasticsearch 。也就是说,早期kafka的消费者是每次消费一条消息,就写一条数据到Elasticsearch 。而现在改成了一次拉取100条消息(这个参数是应该是可配置的),做成一个批次,提交给Elasticsearch ,就解决了消息积压的问题。
这个方案的好处是能够把消息积压和Elasticsearch的知识点联系在一起,能够从这个案例里看出你的思维很灵活。当然这也会把话题引导到kafka或消息积压上,要记得复习。
另外一个是调整批次,这一类手段非常适合用在日志同步中,这里给出一个调整批次和降级的方案。
公司是要利用Logstash直接同步到Elasticsearch的,在业务繁忙的时候,日志就有可能同步得很慢,或者Elasticsearch压力很大。在这种情况下,把日志同步到Elasticsearch的批次调大了一些 ,显著降低了Elasticsearch的负载。
此外,还引入了一个降级机制 。正常公司的日志是全量同步的,但是如果发现Elasticsearch有问题,就会触发降级,触发降级的时候会先丢掉INFO级别的日志 ,运行一段时间后,如果Elasticsearch还是没能恢复正常,就把WARN级别的也丢弃 。
这一个方案亮点在于你把调整批次和降级结合在一起,能体现你综合运用各种手段解决实际问题的能力。