Skip to content

ES index速度调节

使用Bulk requests

对单个节点进行测试,每次以100条\批、200条\批、400条\批的量进行批量插入,每次测试的条数双倍增加。直到插入速度平稳。测试出批量操作的最优条数。 每批操作的数据不要超过几十兆,避免内存压力。

多线程插入

单线程批量操作不太可能达到ES集群索引的最大能力。为了测试集群资源极限,应该多线程或多进程插入。除了能更好的利用集群资源外,还能降低fsync成本。 需要注意TOO_MANY_REQUESTS(429)错误、Java API的EsRejectedExecutionException异常,这表示ES插入速度跟不上业务需求了,需要暂停插入业务稍后再重试。 When it happens, you should pause indexing a bit before trying again, ideally with randomized exponential backoff. 当发生这种情况时,您应该在再次尝试之前暂停索引,理想情况下使用随机指数返回。 逐步增加业务请求,直到CPU或IO达到饱和。

取消或调高刷新间隔

包含使改变对搜索可见的操作叫做刷新,在索引期间调用刷新操作会降低索引速度。ES默认会对过去30秒接收过一次或多次搜索请求的索引每秒刷新一次。如果没有搜索流量或者比五分钟一次的频率还低,并且希望优化索引速度,这个默认配置是最佳的。 如果能承受读写不一致时间变长,可以增加 index.refresh_interval 的值来提高索引速度。文档示例为30s。

关闭复制集(replicas)

如果需要将大量数据一次性载入到ES中,为了提高索引速度,可以设置index.number_of_replicas为0。副本数设置为0会有丢失数据的风险,所以需要保留好载入的数据,以便载入失败后可以重新载入。等数据载入完成后,再将index.number_of_replicas改为原值。 如果settings中配置了index.refresh_interval,在载入数据时,取消这个参数,载入完成后改回原值也有效果。

关闭swapping

以下3种方法任选

ES的内存受JVM控制,所以不应该开启swapping。

Linux系统关闭swap的命令

Shell
sudo swapoff -a

永久关闭swap需要修改/etc/fstab文件,注释掉所有包含“swap”字样的配置。 Windows系统关闭分页文件 系统属性 -> 高级 -> 性能 -> 设置 -> 高级 -> 虚拟内存 -> 更改 -> 取消勾选"自动管理所有驱动器的分页文件大小" 并选择"无分页文件"

配置swappiness

设置sysctl的vm.swappiness为1。降低内核的swap倾向,正常场景下不进行swapping,紧急情况下进行swapping。

开启bootstrap.memory_lock

*nix系统上使用mlockall,Windows上使用VirualLock,将ES进程的地址空间在内存种锁定,以防止ES的内存被交换出内存。 开启方式为在config/elasticsearch.yml文件中添加

properties
bootstrap.memory_lock: true

尝试分配超过可用大小的内存,mlockall可能会导致JVM、Shell会话退出。 使用这个命令可以查询mlockall是否启用成功

shell
curl -X GET "localhost:9200/_nodes?filter_path=**.mlockall&pretty"

如果mlockall是false,可以在日志文件中查找"Unable to lock JVM Memory"字样,查看错误信息。 *nix系统中失败的原因大概率是没有权限锁内存,解决方法如下:

  1. 如果是.zip或.tar.gz方式安装ES 启动ES前以root权限执行
    shell

ulimit -l unlimited 或在/etc/security/limits.conf文件中修改memlock参数值为unlimited。 2. rpm或deb方式安装ES 配置文件中设置MAX_LOCKED_MEMORY参数值为unlimited。 rpm配置文件路径/etc/sysconfig/elasticsearch deb配置文件路径/etc/default/elasticsearch 3. 使用了systemd的系统 在systemd配置中设置LimitMEMLOCK参数值为infinity。 配置文件路径:/usr/lib/systemd/system/elasticsearch.service 自定义配置文件存放路径:/etc/systemd/system/elasticsearch.service.d/override.conf 命令方式修改 Shell sudo systemctl edit elasticsearch 添加的内容如下 properties [Service] LimitMEMLOCK=infinity 完成后重载units shell sudo systemctl daemon-reload ```

给文件系统缓存分配内存

文件系统缓存用来缓冲IO操作。应该分配机器的一半以上内存给文件系统缓存。

使用自动生成id

如果指定了id,ES在索引时需要检查同一分片下是否已经有相同id的数据,影响索引效率。使用自动生成的id,可以跳过相同id检查。

使用更快的硬件

如果IO是瓶颈,就需要给文件系统缓存更多的内存,或者用更快的磁盘。 用本地存储,避免使用NFS或SMB这些远程文件系统。如果需要使用AWS的EBS服务,需要选用IO优化实例。 将索引放在多个SSD组成的RAID0磁盘阵列中。这个操作一旦有一个SSD出现故障,都会导致索引丢失,可以通过部署多个节点组成复制集解决。

修改索引缓冲区大小

如果节点上只有大量索引操作,每个分片需要给indices.memory.index_buffer_size足够大的值,但不能超过512MB,超过这个值索引性能一般不会提升。这个值可以为百分数,也可以为绝对大小,所有分片共享这部分空间。 indices.memory.index_buffer_size默认值为10%

读写分离

单个集群内,搜索操作和索引操作会竞争资源。启用两个集群,配置复制参数,将数据从写集群复制到读集群,并且将搜索操作路由到读集群,这样搜索操作就不会和索引操作竞争资源。

https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html