Elasticsearch 大數(shù)據(jù)量掃描三招改動,性能提升 2 倍!
1、背景問題
球友最近接手了一個數(shù)據(jù)處理項目,需要對 Elasticsearch 中4000多萬條數(shù)據(jù)進(jìn)行全量掃描和處理。 項目初期,單線程處理方式讓整個任務(wù)耗時過長,嚴(yán)重影響了業(yè)務(wù)進(jìn)度。
更棘手的是,在全量掃描期間,還有增量數(shù)據(jù)不斷寫入,部分文檔字段會被軟刪除,這就要求我們既要保證掃描的完整性,又要處理好增量更新的問題。
412e48567e56d1802cec55ebdf16df92.jpg
經(jīng)過一番交流、調(diào)研和實踐,通過三個核心優(yōu)化策略,將處理性能提升了2倍,現(xiàn)在將這次優(yōu)化的經(jīng)驗總結(jié)分享給大家。
2、問題分析
面對 4000 萬數(shù)據(jù)的處理需求,我們首先分析了性能瓶頸所在。通過監(jiān)控 ES 集群的指標(biāo),發(fā)現(xiàn)主要問題集中在以下幾個方面:
- 問題1:查詢響應(yīng)時間長。
單次查詢返回數(shù)據(jù)量大,網(wǎng)絡(luò)傳輸耗時明顯。通過 ES 慢查詢?nèi)罩景l(fā)現(xiàn),大部分查詢耗時都在數(shù)據(jù)傳輸階段,而不是搜索本身。 - 問題2:資源利用率低。
單線程處理無法充分利用服務(wù)器的多核資源,明顯存在資源浪費。 - 問題3:索引遍歷效率差。 項目中使用了日期別名來管理按天分割的索引,一個別名對應(yīng)了多個底層索引,ES需要在多個索引間進(jìn)行查詢合并,增加了不必要的開銷。
圖片
- 問題4:字段冗余問題。
業(yè)務(wù)邏輯實際只需要幾個核心字段,但查詢時卻返回了文檔的所有字段,包括一些大文本字段,造成了帶寬和內(nèi)存的雙重浪費。
基于這些問題,我們制定了針對性的優(yōu)化方案。
3、解決方案設(shè)計
這是我們語音交流20多分鐘后,敲定的三大核心優(yōu)化策略。
3.1 策略一:字段精簡優(yōu)化
通過 _source filtering,只返回業(yè)務(wù)必需的字段。
原本每個文檔返回20多個字段,優(yōu)化后只返回4個核心字段,數(shù)據(jù)傳輸量減少了70%(估算)以上。
3.2 策略二:精確索引定位
日期別名的使用方式,改為直接指定具體的索引名稱。
這樣避免了ES在多個索引間進(jìn)行查詢合并的開銷,查詢效率顯著提升。
3.3 策略三:批量大小調(diào)優(yōu)
將單次查詢的 size 參數(shù)從默認(rèn)的 100 逐步增加到 200,500, 1000等更為合理的值(比如:5000)
在不超過線程池隊列限制的前提下,減少了查詢輪次,提高了整體吞吐量。
4、實戰(zhàn)代碼實現(xiàn)
4.1 Elasticsearch DSL優(yōu)化
優(yōu)化前的查詢DSL (僅供參考):
GET /data_alias/_search
{
"query": {
"range": {
"create_time": {
"gte": "2024-01-01",
"lte": "2024-01-02"
}
}
},
"size": 10,
"from": 0
}優(yōu)化后的查詢 DSL(做了模糊處理):
GET /data_20240101/_search
{
"_source": ["id", "status", "create_time", "update_time"],
"query": {
"range": {
"create_time": {
"gte": "2024-01-01T00:00:00",
"lte": "2024-01-01T23:59:59"
}
}
},
"size": 5000,
"sort": [
{
"_id": {
"order": "asc"
}
}
],
"search_after": ["last_doc_id"]
}4.2 增量數(shù)據(jù)處理策略
針對全量掃描期間的增量數(shù)據(jù)問題,我們采用了基于時間戳的增量同步方案:
GET /data_20240101/_search
{
"_source": ["id", "status", "create_time", "update_time"],
"query": {
"bool": {
"must": [
{
"range": {
"update_time": {
"gt": "2024-01-01T10:30:00"
}
}
}
],
"must_not": [
{
"term": {
"status": "deleted"
}
}
]
}
},
"size": 5000,
"sort": [
{
"update_time": {
"order": "asc"
}
}
]
}5、性能測試結(jié)果
經(jīng)過優(yōu)化后,我們對比了優(yōu)化前后的性能數(shù)據(jù):
5.1 處理時間對比
舉例原本需要 8 小時的全量掃描任務(wù),優(yōu)化后縮短到4小時,性能提升 100%。
5.2 資源利用率
CPU 利用率從 25% 提升到 85%,內(nèi)存使用更加均衡。
5.3 ES集群壓力
通過精確索引定位和字段精簡,集群的查詢響應(yīng)時間從平均 800 ms降低到 200ms,搜索壓力明顯減輕。
5.4 數(shù)據(jù)一致性
通過增量同步機(jī)制,確保了在全量掃描期間新增和更新的數(shù)據(jù)能夠被正確處理,數(shù)據(jù)完整性得到保障。
6、經(jīng)驗總結(jié)
這次優(yōu)化實踐讓我們深刻認(rèn)識到,大數(shù)據(jù)量處理的性能優(yōu)化需要從多個維度入手。單純依靠硬件擴(kuò)容往往收效甚微,而通過合理的架構(gòu)設(shè)計和查詢優(yōu)化,往往能夠取得更好的效果。
- 合理的線程數(shù)量配置能夠充分利用系統(tǒng)資源,但要注意控制并發(fā)度,避免對ES集群造成過大壓力。
- _source filtering 是一個簡單但非常有效的優(yōu)化手段,特別是在處理包含大文本字段的文檔時效果明顯。
- 能夠指定具體索引就不要使用別名,能夠精確匹配就不要使用范圍查詢,這些細(xì)節(jié)往往能帶來意想不到的性能提升。
- 在大數(shù)據(jù)量處理場景中,增量數(shù)據(jù)的處理策略同樣重要,需要在設(shè)計階段就考慮好相應(yīng)的方案。
性能優(yōu)化是一個持續(xù)的過程,需要根據(jù)實際的業(yè)務(wù)場景和數(shù)據(jù)特點不斷調(diào)整和完善。
希望這次的優(yōu)化經(jīng)驗?zāi)軌驗橛龅筋愃茊栴}的同行提供一些參考和借鑒。
最后我想說的:AI時代,如果沒有對知識建立體系化的理解,而是遇到問題就直接問 AI 就會誤入歧途,反而會走更多的彎路且無法自拔?!@是我和球友溝通得到的最真實的反饋。

























