ElasticSearch性能优化

398 阅读3分钟

硬件层面

  1. 物理内存:ES查询性能依赖OS的Page Cache,所以物理内存(除了Java堆以外)越大越好,最好是能将全部的(大部分热的)索引数据存放在内存中,这样大多数的查询都是在内存中进行性的;

  2. Linux服务器需要设置禁用swap交换内存,交换分区主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因内存不够用而导致oom或者更致命的情况出现,但是使用了Swap会导致性能严重下降。

配置优化

  1. 在进行批量数据写入的时候,可以通过配置设置副本的数量为0,这样可以加快索引速度,等到数据写入完成后再重新设置副本数量。

架构设计

  1. 冷热数据分离,将冷数据和热数据进行分离,可以分别存在在不同的集群中,不同的集群采用不同的硬件配置,如热数据可以配置大内存和高性能的SSD,而冷数据由于较少访问并且几乎不再写入可以使用廉价的机器,这样可以节省成本,并且可以防止偶然访问冷数据对缓存的干扰,以保证热点数据的查询性能;

文档设计

  1. ES只存储需要的索引字段,对于不需要索引的字段可以存到其他的存储中如HBase等(查询到主键rowkey然后去HBase查询详细的数据),尽可能的减少Document的大小,这样可以使得内存中存放更多的Document信息;

  2. 对于复杂的关联查询,可以直接将聚合好的结果写入ES,查询时可以直接得到结果避免额外的计算(这个和1其实并不冲突,更多的是业务需求的取舍);

  3. 如果没有特殊的业务要求最好是使用系统自动生成的文档id,如果是自定义的索引id在索引达到一定量的时候,写入性能会急剧下降,这是由于所有插入的索引都会进行是否重复的检查(等一系列其他操作),这个检查在索引量巨大的时候会有巨大的性能损耗,所以推荐方式是将文档id设置为自动生成。

读写优化

  1. 数据预热,查询前可以对一些热点数据进行预热,这样可以尽可能的将数据缓存在内存中,以加快查询性能;

  2. 海量数据的读写可以使用批量操作(使用Bulk APi),减少网络IO次数,减少带宽;

  3. 分页查询的时候避免使用深分页,如果需要做遍历操作的话可以使用Scroll Api;

  4. 如果对ES的实时性要求不是很高,可以设置refresh_interval大一点,这样可以避免产生大量的Segment,对检索性能有影响,而且大量的Segment合并也会有性能损失。