問題背景
上億規(guī)模的數(shù)據(jù)做索引按照Elasticsearch默認的配置做索引的速度非常慢幔亥,時間成本比較高,如何加快建索引的速度呢察纯?
解決方法
使用bulk API帕棉,調(diào)整 bulk 線程池和隊列
- 每個請求大小建議在5-15MB,逐步增大測試,當接收到EsRejectedExecutionException饼记,就說明已經(jīng)到達節(jié)點的瓶頸了香伴,就需要減少并發(fā)或者升級硬件增加節(jié)點
- 當寫入數(shù)據(jù)時,確保bulk請求時輪詢訪問所有節(jié)點具则,不要發(fā)送所有請求到一個結(jié)點導(dǎo)致這一個節(jié)點要在內(nèi)存存儲所有請求的數(shù)據(jù)去處理
加大 index refresh間隔, 目的除了降低 io, 更重要的降低了 segment merge 頻率
比如即纲,設(shè)置間隔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"
}
}
當然,最后別忘了再改回來束昵,還有多執(zhí)行一個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 默認設(shè)置為:每 30 分鐘主動進行一次 flush,或者當 translog 文件大小大于 512MB (老版本是 200MB)時锹雏,主動進行一次 flush巴比。這兩個行為,可以分別通過 index.translog.flush_threshold_period 和 index.translog.flush_threshold_size 參數(shù)修改。
如果導(dǎo)入的文檔沒有唯一的ID轻绞,可以使用Elasticsearch自動生成的唯一ID
分析 Es 寫入流程可以看到,寫入 doc 時如果是外部指定了 id,es 會先嘗試讀取原來doc的版本號, 判斷是否需要更新,使用自動生成 doc id 可以避免這個環(huán)節(jié).
使用SSD
SSD 是經(jīng)濟壓力能承受情況下的不二選擇采记。減少碎片也可以提高索引速度,每天進行優(yōu)化還是很有必要的政勃。