在 Elasticsearch 中,使用 PUT 請(qǐng)求存儲(chǔ)一條數(shù)據(jù)(即索引一個(gè)文檔)是一個(gè)涉及多個(gè)組件的復(fù)雜過程,它不僅包括數(shù)據(jù)的存儲(chǔ),還涵蓋了數(shù)據(jù)處理、路由、復(fù)制等一系列服務(wù)。下面我們將詳細(xì)解析從發(fā)起 PUT 請(qǐng)求到數(shù)據(jù)最終落地的完整流程。
1. 客戶端發(fā)起請(qǐng)求
用戶通過 REST API 向 Elasticsearch 集群發(fā)送一個(gè) PUT 請(qǐng)求,其基本格式為:PUT /<index>/_doc/<id>。其中 <index> 是目標(biāo)索引名稱,<id> 是指定的文檔 ID(如果省略,Elasticsearch 會(huì)自動(dòng)生成一個(gè))。請(qǐng)求體包含了要存儲(chǔ)的 JSON 格式文檔數(shù)據(jù)。
2. 請(qǐng)求到達(dá)協(xié)調(diào)節(jié)點(diǎn)
Elasticsearch 集群中的任意節(jié)點(diǎn)都可以接收請(qǐng)求,這個(gè)節(jié)點(diǎn)被稱為“協(xié)調(diào)節(jié)點(diǎn)”。協(xié)調(diào)節(jié)點(diǎn)負(fù)責(zé)處理客戶端的請(qǐng)求,并將其路由到正確的數(shù)據(jù)節(jié)點(diǎn)。它首先會(huì)解析請(qǐng)求,檢查索引是否存在、映射是否定義等。如果索引是自動(dòng)創(chuàng)建的(根據(jù)配置),協(xié)調(diào)節(jié)點(diǎn)會(huì)觸發(fā)索引的創(chuàng)建過程。
3. 文檔路由與主分片定位
Elasticsearch 索引由一個(gè)或多個(gè)主分片(及可選的副本分片)組成。協(xié)調(diào)節(jié)點(diǎn)根據(jù)文檔 ID 計(jì)算其應(yīng)該存儲(chǔ)在哪個(gè)主分片上。默認(rèn)的路由算法是:shard<em>num = hash(</em>routing) % num<em>primary</em>shards,其中 _routing 默認(rèn)為文檔 ID。通過計(jì)算,協(xié)調(diào)節(jié)點(diǎn)確定目標(biāo)主分片及其所在的數(shù)據(jù)節(jié)點(diǎn)(稱為“主分片節(jié)點(diǎn)”)。
4. 轉(zhuǎn)發(fā)請(qǐng)求到主分片節(jié)點(diǎn)
協(xié)調(diào)節(jié)點(diǎn)將索引請(qǐng)求轉(zhuǎn)發(fā)到上一步確定的主分片節(jié)點(diǎn)。此時(shí),主分片節(jié)點(diǎn)開始本地的索引處理流程。
5. 本地索引處理(數(shù)據(jù)處理階段)
在主分片節(jié)點(diǎn)上,數(shù)據(jù)會(huì)經(jīng)歷一系列處理步驟:
- 解析與驗(yàn)證:系統(tǒng)解析 JSON 文檔,驗(yàn)證其結(jié)構(gòu)。
- 字段映射與類型轉(zhuǎn)換:根據(jù)索引的映射(mapping)定義,對(duì)字段進(jìn)行類型處理。例如,將字符串日期轉(zhuǎn)換為
date類型,或?qū)ξ谋咀侄芜M(jìn)行分詞設(shè)置。如果字段未預(yù)先定義且動(dòng)態(tài)映射開啟,Elasticsearch 會(huì)自動(dòng)推斷其類型并更新映射。 - 分析過程:對(duì)于文本字段(
text類型),會(huì)調(diào)用相應(yīng)的分析器(analyzer)進(jìn)行分詞、過濾(如小寫化、去除停用詞等),生成倒排索引所需的詞項(xiàng)。 - 生成文檔數(shù)據(jù)結(jié)構(gòu):處理后的文檔會(huì)被轉(zhuǎn)換為內(nèi)部存儲(chǔ)結(jié)構(gòu),包括源文檔(
_source,默認(rèn)存儲(chǔ)原始 JSON)、倒排索引條目、文檔值(用于排序和聚合)等。
6. 寫入事務(wù)日志與內(nèi)存緩沖區(qū)
為確保數(shù)據(jù)的持久性和一致性,Elasticsearch 采用了以下步驟:
- 事務(wù)日志(Translog)寫入:在數(shù)據(jù)真正寫入磁盤前,操作會(huì)首先被記錄到事務(wù)日志中。Translog 提供了崩潰恢復(fù)機(jī)制,防止數(shù)據(jù)丟失。
- 內(nèi)存緩沖區(qū):文檔數(shù)據(jù)被添加到索引的內(nèi)存緩沖區(qū)中,此時(shí)尚不可被搜索。
7. 刷新(Refresh)與可搜索性
內(nèi)存緩沖區(qū)會(huì)定期刷新(默認(rèn)每 1 秒一次,可通過 refresh_interval 配置)。刷新過程會(huì):
- 將內(nèi)存緩沖區(qū)中的內(nèi)容寫入一個(gè)新的段(segment)中,這是一個(gè)輕量級(jí)的提交。
- 重新打開索引,使得新段內(nèi)的文檔變得可搜索。
注意:刷新操作不會(huì)立即將數(shù)據(jù)持久化到磁盤,而是先寫入文件系統(tǒng)緩存,速度較快。
8. 副本同步(存儲(chǔ)支持服務(wù)的關(guān)鍵)
如果索引配置了副本分片(replica shards),主分片節(jié)點(diǎn)在本地處理完成后,會(huì)將索引請(qǐng)求并行轉(zhuǎn)發(fā)到所有副本分片所在的節(jié)點(diǎn)。副本分片執(zhí)行相同的本地索引處理流程。只有當(dāng)所有副本分片也成功完成操作后(或根據(jù)配置的 consistency 級(jí)別),主分片節(jié)點(diǎn)才會(huì)向協(xié)調(diào)節(jié)點(diǎn)報(bào)告成功。這提供了數(shù)據(jù)的高可用性和容錯(cuò)能力。
9. 響應(yīng)客戶端
協(xié)調(diào)節(jié)點(diǎn)收到主分片節(jié)點(diǎn)的成功響應(yīng)后,會(huì)向客戶端返回一個(gè)確認(rèn),通常包含索引名稱、文檔 ID、版本號(hào)以及操作結(jié)果(如 "result": "created")。
10. 后續(xù)持久化:刷寫(Flush)與段合并
為了數(shù)據(jù)的長期持久化,Elasticsearch 會(huì)定期執(zhí)行刷寫操作:
- Translog 刷寫:當(dāng) Translog 達(dá)到一定大小時(shí)(默認(rèn) 512MB)或定期(默認(rèn) 30 分鐘),會(huì)觸發(fā)一次刷寫。此時(shí),內(nèi)存中所有未持久化的段會(huì)被完全寫入磁盤,同時(shí)清空 Translog。
- 段合并:由于頻繁刷新會(huì)產(chǎn)生大量小段,Elasticsearch 會(huì)在后臺(tái)自動(dòng)合并小段為更大的段,優(yōu)化存儲(chǔ)和搜索性能,并刪除已刪除的文檔。
###
Elasticsearch 的 PUT 過程是一個(gè)分布式、多階段的數(shù)據(jù)處理與存儲(chǔ)流程。它巧妙地將數(shù)據(jù)路由、實(shí)時(shí)處理(映射、分析)、內(nèi)存緩沖、事務(wù)日志、刷新與刷寫機(jī)制,以及副本復(fù)制結(jié)合起來,在保證性能、可搜索性和可靠性的提供了強(qiáng)大的數(shù)據(jù)存儲(chǔ)支持服務(wù)。理解這一流程有助于更好地設(shè)計(jì)索引、調(diào)優(yōu)性能和診斷問題。