Elasticsearch 雖然強大,但開箱設定偏「通用」。
預設值是為了「能安全啟動」,而不是「效能最佳」。
今天我們要用實際例子,看看怎麼調整幾個關鍵參數,讓 Jeopardy! 搜尋真正跑起來。
在真實系統中,要在兩者之間取捨:
但 ES 每次 refresh 都會生成新的 segment,太頻繁會壓力大;太慢又查不到最新資料。
今天要做的是找兩者之間的平衡。
在大規模匯入時(像 Jeopardy! 十幾萬筆),建議先讓 ES「全力寫入」,關掉不必要的即時性。
# 關掉 refresh(避免每筆都強制 flush segment)
curl -X PUT "localhost:9200/jeopardy/_settings" -H 'Content-Type: application/json' -d'
{
"index" : {
"refresh_interval" : "-1",
"number_of_replicas" : 0
}
}'
說明:
"refresh_interval": "-1"
:匯入時不要自動 refresh"number_of_replicas": 0"
:暫時關掉副本,省下同步成本等 Bulk 完成後,再開回來。
匯入完成後,記得把設定調回來:
curl -X PUT "localhost:9200/jeopardy/_settings" -H 'Content-Type: application/json' -d'
{
"index" : {
"refresh_interval" : "1s",
"number_of_replicas" : 1
}
}'
這樣查詢結果就會在 1 秒內更新,並且有一份備援。
ES 會自動為 filter 查詢建立快取,但我們可以顯式確認或開啟。
curl -X GET "localhost:9200/jeopardy/_stats/query_cache?pretty"
若看到 hit_count
明顯提升,代表熱查詢已經進入 cache。
對於固定查詢(例如前端熱門關鍵字),可以搭配應用層 cache(例如 Redis)再一層保護。
這一步是驗證「我們的優化是否真的有效」。
假設你在 Golang 寫了一個 /search?q=Shakespeare
的 API,
可以用 hey 進行壓測:
hey -n 1000 -c 20 'http://localhost:8080/search?q=Shakespeare'
觀察輸出:
Requests/sec: 180.3
Latency avg: 112.5 ms
如果 latency 顯著下降(例如從 300ms → 100ms),代表優化奏效。
想要更細部分析,可以打開 Elasticsearch 的 _nodes/stats/jvm,fs,os
,看 JVM heap、I/O 與 CPU 的走勢。
幾個常見可以微調的參數:
設定 | 用途 | 建議值 |
---|---|---|
refresh_interval |
查詢新鮮度 | 匯入時 -1 ,正式 1s |
number_of_replicas |
副本數量 | 單節點可 0,多節點 ≥1 |
indices.memory.index_buffer_size |
寫入緩衝區 | 預設 10%,可調到 20–30% |
indices.store.throttle.type |
I/O 節流 | 匯入時 none ,正常用 merge |
這些設定不是越大越好,要根據節點記憶體與磁碟 I/O 實測。
Elasticsearch 優化不是「改幾個設定、重開就好」,但事實上,它更像是「工程與觀察」的循環:
是現代軟體工程裡常見的 loop:
Measure → Adjust → Measure again.
有了 Jeopardy! 這個資料集,我們終於有足夠的真實規模可以做這樣的觀察。
這讓明天「快照備份與還原」更有意義,因為那時我們備份的不只是資料,而是整個實驗狀態。