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
- 当master为true,而data为true时,主节点且是数据节点;
- 当master为false,而data为true时,纯数据节点;
- 当master为true,而data为false时,主节点,作为一个协调者;
- 当master为false,data也为false时,该节点就变成了一个负载均衡器。
9.避免内存交换
由于操作系统的虚拟内存页交换机制,会降低性能,如数据写满内存会写入Linux中的Swap分区。可以通过在elasticsearch.yml文件中的bootstrap.mlockall设置为true来实现,但是需要管理员权限,修改操作系统的相关配置文件。