Elasticsearch 性能优化详解( 二 )


在经济压力能承受的范围下,尽量使用固态硬盘(SSD) 。固态硬盘相比于任何旋转介质(机械硬盘,磁带等) , 无论随机写还是顺序写,都会对 IO 有较大的提升 。

  1. 如果你正在使用 SSDs,确保你的系统 I/O 调度程序是配置正确的 。当你向硬盘写数据,I/O 调度程序决定何时把数据实际发送到硬盘 。大多数默认 *nix 发行版下的调度程序都叫做 cfq(完全公平队列) 。
  2. 调度程序分配时间片到每个进程 。并且优化这些到硬盘的众多队列的传递 。但它是为旋转介质优化的:机械硬盘的固有特性意味着它写入数据到基于物理布局的硬盘会更高效 。
  3. 这对 SSD 来说是低效的,尽管这里没有涉及到机械硬盘 。但是,deadline 或者 noop 应该被使用 。deadline 调度程序基于写入等待时间进行优化,noop 只是一个简单的 FIFO 队列 。
这个简单的更改可以带来显著的影响 。仅仅是使用正确的调度程序,我们看到了 500 倍的写入能力提升 。
如果你使用旋转介质(如机械硬盘),尝试获取尽可能快的硬盘(高性能服务器硬盘,15k RPM 驱动器) 。
使用 RAID0 是提高硬盘速度的有效途径 , 对机械硬盘和 SSD 来说都是如此 。没有必要使用镜像或其它 RAID 变体,因为 Elasticsearch 在自身层面通过副本,已经提供了备份的功能,所以不需要利用磁盘的备份功能 , 同时如果使用磁盘备份功能的话,对写入速度有较大的影响 。
最后,避免使用网络附加存储(NAS) 。人们常声称他们的 NAS 解决方案比本地驱动器更快更可靠 。除却这些声称 , 我们从没看到 NAS 能配得上它的大肆宣传 。NAS 常常很慢,显露出更大的延时和更宽的平均延时方差,而且它是单点故障的 。
索引优化设置索引优化主要是在 Elasticsearch 的插入层面优化 , Elasticsearch 本身索引速度其实还是蛮快的,具体数据 , 我们可以参考官方的 benchmark 数据 。我们可以根据不同的需求,针对索引优化 。
批量提交当有大量数据提交的时候 , 建议采用批量提交(Bulk 操作);此外使用 bulk 请求时,每个请求不超过几十M , 因为太大会导致内存使用过大 。
比如在做 ELK 过程中,Logstash indexer 提交数据到 Elasticsearch 中,batch size 就可以作为一个优化功能点 。但是优化 size 大小需要根据文档大小和服务器性能而定 。
像 Logstash 中提交文档大小超过 20MB,Logstash 会将一个批量请求切分为多个批量请求 。
如果在提交过程中,遇到 EsRejectedExecutionException 异常的话,则说明集群的索引性能已经达到极限了 。这种情况 , 要么提高服务器集群的资源,要么根据业务规则 , 减少数据收集速度,比如只收集 Warn、Error 级别以上的日志 。
增加 Refresh 时间间隔为了提高索引性能,Elasticsearch 在写入数据的时候,采用延迟写入的策略,即数据先写到内存中,当超过默认1秒(index.refresh_interval)会进行一次写入操作,就是将内存中 segment 数据刷新到磁盘中,此时我们才能将数据搜索出来,所以这就是为什么 Elasticsearch 提供的是近实时搜索功能,而不是实时搜索功能 。
如果我们的系统对数据延迟要求不高的话,我们可以通过延长 refresh 时间间隔,可以有效地减少 segment 合并压力,提高索引速度 。比如在做全链路跟踪的过程中 , 我们就将 index.refresh_interval 设置为30s,减少 refresh 次数 。再如 , 在进行全量索引时,可以将 refresh 次数临时关闭,即 index.refresh_interval 设置为-1,数据导入成功后再打开到正常模式,比如30s 。
在加载大量数据时候可以暂时不用 refresh 和 repliccas,index.refresh_interval 设置为-1,index.number_of_replicas 设置为0 。
相关原理,请参考[原理:ES原理之索引文档流程详解]
修改 index_buffer_size 的设置索引缓冲的设置可以控制多少内存分配给索引进程 。这是一个全局配置,会应用于一个节点上所有不同的分片上 。
indices.memory.index_buffer_size: 10%indices.memory.min_index_buffer_size: 48mbindices.memory.index_buffer_size 接受一个百分比或者一个表示字节大小的值 。默认是10%,意味着分配给节点的总内存的10%用来做索引缓冲的大小 。这个数值被分到不同的分片(shards)上 。如果设置的是百分比 , 还可以设置 min_index_buffer_size (默认 48mb)和 max_index_buffer_size(默认没有上限) 。


推荐阅读