[Elasticsearch] 如何提高索引速度
2017-10-27 本文已影响0人
techhow
问题背景
上亿规模的数据做索引按照Elasticsearch默认的配置做索引的速度非常慢,时间成本比较高,如何加快建索引的速度呢?
解决方法
使用bulk API,调整 bulk 线程池和队列
- 每个请求大小建议在5-15MB,逐步增大测试,当接收到EsRejectedExecutionException,就说明已经到达节点的瓶颈了,就需要减少并发或者升级硬件增加节点
- 当写入数据时,确保bulk请求时轮询访问所有节点,不要发送所有请求到一个结点导致这一个节点要在内存存储所有请求的数据去处理
加大 index refresh间隔, 目的除了降低 io, 更重要的降低了 segment merge 频率
比如,设置间隔refresh_interval: 120s。如果是初次建索引可以禁止replia和refresh,即number_of_replicas:0且refresh_interval:-1。
curl -XPUT 'localhost:9200/twitter/_settings?pretty' -H 'Content-Type: application/json' -d'
{
"index" : {
"refresh_interval" : "-1",
"number_of_replicas" : "0"
}
}
当然,最后别忘了再改回来,还有多执行一个merge操作
curl -XPUT 'localhost:9200/twitter/_settings?pretty' -H 'Content-Type: application/json' -d'
{
"index" : {
"refresh_interval" : "1s",
"number_of_replicas" : "1"
}
}
curl -XPOST 'hs002:9200/searchq/_forcemerge?max_num_segments=5&pretty'
加大 translog flush ,目的是降低 iops, writeblock
对于 flush 操作,Elasticsearch 默认设置为:每 30 分钟主动进行一次 flush,或者当 translog 文件大小大于 512MB (老版本是 200MB)时,主动进行一次 flush。这两个行为,可以分别通过 index.translog.flush_threshold_period 和 index.translog.flush_threshold_size 参数修改。
如果导入的文档没有唯一的ID,可以使用Elasticsearch自动生成的唯一ID
分析 Es 写入流程可以看到,写入 doc 时如果是外部指定了 id,es 会先尝试读取原来doc的版本号, 判断是否需要更新,使用自动生成 doc id 可以避免这个环节.
使用SSD
SSD 是经济压力能承受情况下的不二选择。减少碎片也可以提高索引速度,每天进行优化还是很有必要的。