Elasticsearch是非常靈活且功能豐富的搜索引擎,提供了開箱即用的美好體驗。但是,在實戰(zhàn)業(yè)務(wù)場景中,經(jīng)常會出現(xiàn)遠遠低于預(yù)期的索引和查詢速度。
下面是針對Elasticsearch索引性能進行調(diào)優(yōu)的建議。
一、使用批量請求(bulk requests)
批量請求將產(chǎn)生比單文檔索引請求好得多的性能。
為了知道批量請求的最佳大小,嘗試在具有單個分片的單個節(jié)點上運行基準測試。 首先嘗試索引100個文檔,然后是200,然后是400,等等。 當索引速度開始穩(wěn)定時,就達到了數(shù)據(jù)批量請求的最佳大小。
一般而言,寧可批量索引文檔少一些,而不是在太多文檔的方向上犯錯。 請注意,如果批量請求文檔太大,可能會使Elasticsearch集群受到內(nèi)存壓力,因此建議避免每個請求超出幾十兆字節(jié),即使較大的請求看起來效果更好。
二、使用多個工作者(workers)或線程向Elasticsearch發(fā)送數(shù)據(jù)
發(fā)送批量請求的單個線程不太可能將Elasticsearch集群的索引容量最大化。 為了使用集群的所有資源,可以從多個線程或進程發(fā)送數(shù)據(jù)。 除了更好地利用集群的資源,這應(yīng)該有助于降低每個fsync的成本。
請注意TOO_MANY_REQUESTS(429)響應(yīng)代碼(JAVA客戶端的EsRejectedExecutionException),這是Elasticsearch提示無法跟上當前索引速率的方式。 發(fā)生這種情況時,應(yīng)該再次嘗試暫停索引,理想情況下使用隨機策略調(diào)整索引并發(fā)量。
與調(diào)整批量請求(bulk request)大小類似,只有測試才能確定最佳的worker數(shù)量。 這可以通過逐漸增加工作者數(shù)量來測試,直到集群上的I/O或CPU飽和。
三、調(diào)大refresh interval參數(shù)
為了讓索引文檔對查詢可見,需要執(zhí)行refresh操作,該操作是有成本的。當正在進行索引時,不斷地執(zhí)行refresh操作,將影響索引速度。
默認的index.refresh_interval是1s,這迫使Elasticsearch每秒創(chuàng)建一個新的分段。 增加這個參數(shù)值(比如說30s)將提升索引速度。
PUT INDEX-NAME/_settings
{
"refresh_interval" : "30s"
}
四、初始化數(shù)據(jù)加載臨時禁用refresh和replicas
如果需要一次加載大量數(shù)據(jù),則應(yīng)該將index.refresh_interval設(shè)置為-1,并將index.number_of_replicas設(shè)置為0,來禁用刷新(refresh)。這會暫時使索引處于危險之中,因為任何分片的丟失都將導(dǎo)致數(shù)據(jù)丟失,但是同時索引將會更快,因為文檔只被索引一次。初始加載完成后,可以將index.refresh_interval和index.number_of_replicas設(shè)置回其原始值。
五、禁用swApping交換內(nèi)存
通過禁止swap交換內(nèi)存,確保操作系統(tǒng)不會交換出Java進程。
具體禁用swapping的操作,可以參考下面鏈接:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/setup-configuration-memory.html
六、提供內(nèi)存給filesystem cache
文件系統(tǒng)緩存(filesystem cache)將用于緩沖I/O操作。 確保運行Elasticsearch的節(jié)點獲得至少一半的主機內(nèi)存,提供給filesystem cache。
七、使用自動生成的id(auto-generated ids)
索引具有顯式id的文檔時,Elasticsearch需要檢查具有相同id的文檔是否已經(jīng)存在于相同的分片中,這是費時的操作,并且隨著索引增長而變得更加費時。 通過使用自動生成的ID,Elasticsearch可以跳過這個檢查,這使索引更快。
PUT test-index
{
"settings":{
"number_of_shards": 3,
"number_of_replicas": 1
}
}
POST test-index/_doc
{
"sku": "002",
"title": "bbb"
}
GET test-index/_search
八、使用更快的硬件
一般而言,索引是I/O密集的,需要準備如下硬件:
(1)為filesystem cache分配更多的內(nèi)存;
(2)使用SSD硬盤;
(3)使用local storage(不要使用NFS、SMB 等remote filesystem)
九、索引緩存區(qū)(Indexing buffer size)
如果節(jié)點只做大量的索引,確保index.memory.index_buffer_size足夠大,每個分片最多可以提供512 MB的索引緩沖區(qū)。超過這一設(shè)置,索引性能通常也不會提升。
Elasticsearch采用該設(shè)置(Java堆的百分比,或者絕對字節(jié)大小),并將其作為所有活動分片(active shards)的共享緩沖區(qū)。非常活躍的分片自然比執(zhí)行輕量級索引的分片,更多地使用這個緩沖區(qū)。
默認設(shè)置為 10%,通常是足夠的。如我們給JVM 10GM內(nèi)存,索引緩沖區(qū)將為1GB,這足以兩個索引很重的分片。