ElasticSearch Index 速度优化 (官方翻译)

使用Bulk请求进行Index

  • Bulk请求将产生比单文档index请求有更好的性能。至于Bulk请求中文档数量的大小,建议使用单一节点单一分片进行测试,先试试看100个,然后200个,然后400这样,每次进行翻倍测试,只要速度稳定了,也就是最合适的大小了。但是要注意一下,并不是速度最合适了就OK,因为每次请求总的大小要进行一下控制。并发发送的时候,ES内存压力会很大,一定要避免每次请求超过几十兆,即便是这样插入的性能更好(这个我踩过坑,我这测试超过10M,ES就不接受请求,直接拒绝了)。

使用多个节点或者多线程进行Index

  • 一般来说一个线程,即便是使用了Bulk方式进行Index,也无法达到ES集群的瓶颈,所以为了最大限度的利用集群资源,使用多线程或者多进程的方式进行Index是一个很好的选择。这样不仅最大程度利用了集群资源,还帮助减少了fsync的成本。(这个fsync是什么 意思我暂时也没弄明白,后续补充)。
  • 要注意一下TOO_MANY_REQUESTS (429) 相应(对应Java Client 则是EsRejectedExecutionException), 这说明ES集群已经跟不上你Index的速度了,使用一些适当的方式限制一下速度吧。(官方文档说暂停Index一会或者使用随机指数函数Backoff)。
  • 类似Bulk Index 数量,多线程多进程Index也需要进行人工测试,直到找到一个合适线程数或者进程数。

增加refresh interval

  • 默认的 index.refresh_interval 是1s,在index的时候如果没有实时性检索需求,建议可以设置大一些,比如30S,如果不需要检索,等index完成才进行检索的话,可以设置为-1,也就是禁用,等完成index之后在调整回来。

禁用refresh,降低分片副本数

  • 如果需要一次index大量数据,最好禁用refresh,也就是将refresh_interval设置为-1,同时index.number_of_replicas 设置为0,也就是不需要副本。尽管这样会增加一些风险(真的很小很小),也就是在索引的时候可能导致数据丢失,但是这样可以大幅度增加索引速度,等完成索引后在增加副本,这样也可以保证数据的可靠性。

禁用Swapping

  • 一定确保操作系统禁用了swapping,这对ES性能有很大的提升。

给足够的内存文件系统缓存

  • 你应该分配机器的一半内存给ES使用,用于文件系统的缓存。文件系统缓存用于缓冲I/O操作。

使用系统自动生成id

  • 当你index一个document使用特定的id,ES需要去检查是否在同一个shard存在相同的ID的文档,这是一个相当昂贵的操作,并且随着文档数量的增加,花费呈指数增长。如果使用自动生成id,ES会跳过这个检查,使得Index速度更快。

使用更快的硬件

  • 如果I/O是瓶颈,那么最好考虑为文件系统提供更多内存或者购买更好的服务器。使用SSD硬盘能比一般的硬盘有更好的性能。另外尽量使用本地存储,不要考虑远程存储。也尽可能不要考虑Amazon等虚拟化存储,尽管比较简单的使用,但是性能比本地存储差很多。
  • 还有要尽可能冗余副本,以避免节点故障导致数据丢失。也可以用快照备份还原进一步降低数据糗事风险。

Indexing 缓冲大小

如果节点仅仅是大量Index,确保每个分片 indices.memory.index_buffer_size 大于512M,(尽管大于512M没有什么性能改善)。举个例子,默认值是10%,也是说如果你设置的jvm大小是10G,那么Index缓冲大小是1G,足以支撑2个shard的大量索引。

禁用 _field_names

  • 简单来说,如果你不需要运行exists查询,那么你就可以禁用_field_names。
posted @ 2018-02-10 16:07  EvilTuzki  阅读(5946)  评论(0编辑  收藏  举报