ES插入/查询优化

1. 多线程插入

可以根据服务器情况开启多个线程插入数据,速度可以提高n倍,n>=2。但是线程也不是越多越好,要根据服务器的memory,cpu,io等定。

2. 设置复制分片数量

如果有多台机器,可以以每台设置n个shards的方式,根据业务情况,可以考虑取消replias(复制分片),等数据插入结束以后再进行更新操作,设置复制分片。此方法可使插入速度提高一倍。但要注意,主分片的数量是不可以更改的。

3. 提高ES占用内存

ES GC调优,内存适当调大,初始是256M,最大1G, 调大后,最小和最大一样,避免GC, 并根据机器情况,设置内存大小。

4、减少shard刷新间隔

建立的索引,不会立马查到,这是为什么elasticsearch为near-real-time的原因
需要配置index.refresh_interval参数,默认是1s。
你如下调用接口配置:

curl -XPUT 'http://127.0.0.1:9200/index_rfm_test/_settings' -d '{ 
    "index" : { 
        "refresh_interval" : "-1" 
    } 
}' 

//完成插入后再修改为初始值 
curl -XPUT 'http://127.0.0.1:9200/index_rfm_test/_settings' -d '{
    "index" : { 
        "refresh_interval" : "1s" 
    } 
}' 

也可以直接写到conf/elasticsearch.yaml文件中
index.refresh_interval:1s
这样所有新建的索引都使用这个刷新频率。

5、设置一个shard的segment最大值

ES中的分片和副本本质上都是Lucene索引,而Lucene索引又基于多个索引段构建(至少一个),索引文件中的绝大多数都是只被写一次,读多次,在Lucene内在机制控制下,当满足某种条件的时候多个索引段会被合并到一个更大的索引段,而那些旧的索引段会被抛弃并移除磁盘,这个操作叫做段合并。

Lucene要执行段合并的理由很简单充分:索引段粒度越小,查询性能越低且耗费的内存越多。频繁的文档更改操作会导致大量的小索引段,从而导致文件句柄打开过多的问题,如修改系统配置,增大系统允许的最大文件打开数。总的来讲,当索引段由多一个合并为一个的时候,会减少索引段的数量从而提高ES性能。
所以要设置合理的segment最大值。

//可以减少段文件数,提高查询速度 
curl -XPUT 'http://xxxxx:9400/index_rfm_test/_optimize?max_num_segments=5' 

//强制merger
curl -XPOST 'http://xxxxx:9400/index_rfm_test/_forcemerge?max_num_segments=1&only_expunge_deletes=true'

segment最大值过大导致不断有segment合并,导致过多的merge,耗费性能。

6、去掉mapping中_all域

Index中默认会有_all的域,这个会给查询带来方便,但是会增加索引时间和索引数据大小。

7、适当增大节点threadpool参数

curl -XPUT 'http://xxxxx:9400/_cluster/settings' -d '{"transient":{"threadpool.index.queue_size":5000,"threadpool.bulk.queue_size": 5000}}'

8.合理设置主节点和数据节点

elasticsearch.yml配置如下:

node.master: true
node.data: true
  1. 当master为true,而data为true时,主节点且是数据节点;
  2. 当master为false,而data为true时,纯数据节点;
  3. 当master为true,而data为false时,主节点,作为一个协调者;
  4. 当master为false,data也为false时,该节点就变成了一个负载均衡器。

9.避免内存交换

由于操作系统的虚拟内存页交换机制,会降低性能,如数据写满内存会写入Linux中的Swap分区。可以通过在elasticsearch.yml文件中的bootstrap.mlockall设置为true来实现,但是需要管理员权限,修改操作系统的相关配置文件。

你可能感兴趣的:(ES插入/查询优化)