路由一個(gè)文檔到一個(gè)分片中
當(dāng)索引一個(gè)文檔的時(shí)候十艾,文檔會(huì)被存儲(chǔ)到一個(gè)主分片中抵代。 Elasticsearch 如何知道一個(gè)文檔應(yīng)該存放到哪個(gè)分片中呢?當(dāng)我們創(chuàng)建文檔時(shí)忘嫉,它如何決定這個(gè)文檔應(yīng)當(dāng)被存儲(chǔ)在分片 1 還是分片 2 中呢荤牍?
實(shí)際上,這個(gè)過(guò)程是根據(jù)下面這個(gè)公式?jīng)Q定的:
shard = hash(routing) % number_of_primary_shards
routing 是一個(gè)可變值庆冕,默認(rèn)是文檔的 _id 康吵,也可以設(shè)置成一個(gè)自定義的值。 routing 通過(guò) hash 函數(shù)生成一個(gè)數(shù)字访递,然后這個(gè)數(shù)字再除以 number_of_primary_shards (主分片的數(shù)量)后得到 余數(shù) 晦嵌。這個(gè)分布在 0 到 number_of_primary_shards-1 之間的余數(shù),就是我們所尋求的文檔所在分片的位置拷姿。
所有的文檔 API( get 惭载、 index 、 delete 响巢、 bulk 描滔、 update 以及 mget )都接受一個(gè)叫做 routing 的路由參數(shù) ,通過(guò)這個(gè)參數(shù)我們可以自定義文檔到分片的映射踪古。
主分片與副本分片如何交互
- 我們可以發(fā)送請(qǐng)求到集群中的任一節(jié)點(diǎn)含长。 每個(gè)節(jié)點(diǎn)都有能力處理任意請(qǐng)求靶衍。 每個(gè)節(jié)點(diǎn)都知道集群中任一文檔位置,所以可以直接將請(qǐng)求轉(zhuǎn)發(fā)到需要的節(jié)點(diǎn)上茎芋。
- 當(dāng)發(fā)送請(qǐng)求的時(shí)候颅眶, 為了擴(kuò)展負(fù)載,更好的做法是輪詢(xún)集群中所有的節(jié)點(diǎn)田弥。
新建涛酗、刪除、索引文檔
以下是在主副分片和任何副本分片上面 成功新建偷厦,索引和刪除文檔所需要的步驟順序:
- 客戶(hù)端向 Node 1 發(fā)送新建商叹、索引或者刪除請(qǐng)求。
- 節(jié)點(diǎn)使用文檔的 _id 確定文檔屬于分片 0 只泼。請(qǐng)求會(huì)被轉(zhuǎn)發(fā)到 Node 3
剖笙,因?yàn)榉制?0 的主分片目前被分配在
Node 3 上。 - Node 3 在主分片上面執(zhí)行請(qǐng)求请唱。如果成功了弥咪,它將請(qǐng)求并行轉(zhuǎn)發(fā)到 Node 1 和 Node 2 的副本分片上。一旦所有的副本分片都報(bào)告成功, Node 3 將向協(xié)調(diào)節(jié)點(diǎn)報(bào)告成功十绑,協(xié)調(diào)節(jié)點(diǎn)向客戶(hù)端報(bào)告成功聚至。
- 在客戶(hù)端收到成功響應(yīng)時(shí),文檔變更已經(jīng)在主分片和所有副本分片執(zhí)行完成本橙,變更是安全的扳躬。
有一些可選的請(qǐng)求參數(shù)允許您影響這個(gè)過(guò)程,可能以數(shù)據(jù)安全為代價(jià)提升性能甚亭。這些選項(xiàng)很少使用贷币,因?yàn)镋lasticsearch已經(jīng)很快,但是為了完整起見(jiàn)亏狰,在這里闡述如下:
- consistency役纹,即一致性。在默認(rèn)設(shè)置下骚揍,即使僅僅是在試圖執(zhí)行一個(gè)寫(xiě)操作之前字管,主分片都會(huì)要求 必須要有 規(guī)定數(shù)量(quorum)(或者換種說(shuō)法啰挪,也即必須要有大多數(shù))的分片副本處于活躍可用狀態(tài)信不,才會(huì)去執(zhí)行寫(xiě)操作(其中分片副本可以是主分片或者副本分片)。這是為了避免在發(fā)生網(wǎng)絡(luò)分區(qū)故障(network partition)的時(shí)候進(jìn)行寫(xiě)操作亡呵,進(jìn)而導(dǎo)致數(shù)據(jù)不一致抽活。規(guī)定數(shù)量即:
int( (primary + number_of_replicas) / 2 ) + 1
- timeout。如果沒(méi)有足夠的副本分片會(huì)發(fā)生什么锰什? Elasticsearch會(huì)等待下硕,希望更多的分片出現(xiàn)丁逝。默認(rèn)情況下,它最多等待1分鐘梭姓。 如果你需要霜幼,你可以使用 timeout 參數(shù) 使它更早終止: 100 100毫秒,30s 是30秒誉尖。
取回單個(gè)文檔
以下是從主分片或者副本分片檢索文檔的步驟順序:
- 客戶(hù)端向 Node 1 發(fā)送獲取請(qǐng)求罪既。
- 節(jié)點(diǎn)使用文檔的 _id 來(lái)確定文檔屬于分片 0 。分片 0 的副本分片存在于所有的三個(gè)節(jié)點(diǎn)上铡恕。 在這種情況下琢感,它將請(qǐng)求轉(zhuǎn)發(fā)到 Node 2 。
- Node 2 將文檔返回給 Node 1 探熔,然后將文檔返回給客戶(hù)端驹针。
備注:
- 在處理讀取請(qǐng)求時(shí),協(xié)調(diào)結(jié)點(diǎn)在每次請(qǐng)求的時(shí)候都會(huì)通過(guò)輪詢(xún)所有的副本分片來(lái)達(dá)到負(fù)載均衡诀艰。
- 在文檔被檢索時(shí)柬甥,已經(jīng)被索引的文檔可能已經(jīng)存在于主分片上但是還沒(méi)有復(fù)制到副本分片。 在這種情況下其垄,副本分片可能會(huì)報(bào)告文檔不存在暗甥,但是主分片可能成功返回文檔。 一旦索引請(qǐng)求成功返回給用戶(hù)捉捅,文檔在主分片和副本分片都是可用的撤防。
局部更新文檔
以下是部分更新一個(gè)文檔的步驟:
- 客戶(hù)端向 Node 1 發(fā)送更新請(qǐng)求。
- 它將請(qǐng)求轉(zhuǎn)發(fā)到主分片所在的 Node 3 棒口。
- Node 3 從主分片檢索文檔寄月,修改 _source 字段中的 JSON ,并且嘗試重新索引主分片的文檔无牵。 如果文檔已經(jīng)被另一個(gè)進(jìn)程修改漾肮,它會(huì)重試步驟 3 ,超過(guò) retry_on_conflict 次后放棄茎毁。
- 如果 Node 3 成功地更新文檔克懊,它將
新版本的文檔
并行轉(zhuǎn)發(fā)到 Node 1 和 Node 2 上的副本分片点待,重新建立索引吊圾。 一旦所有副本分片都返回成功, Node 3 向協(xié)調(diào)節(jié)點(diǎn)也返回成功匕积,協(xié)調(diào)節(jié)點(diǎn)向客戶(hù)端返回成功橡卤。
備注:當(dāng)主分片把更改轉(zhuǎn)發(fā)到副本分片時(shí)扮念, 它不會(huì)轉(zhuǎn)發(fā)更新請(qǐng)求。 相反碧库,它轉(zhuǎn)發(fā)完整文檔的新版本
多文檔模式
mget 和 bulk API 的 模式類(lèi)似于單文檔模式柜与。區(qū)別在于協(xié)調(diào)節(jié)點(diǎn)知道每個(gè)文檔存在于哪個(gè)分片中巧勤。 它將整個(gè)多文檔請(qǐng)求分解成 每個(gè)分片 的多文檔請(qǐng)求,并且將這些請(qǐng)求并行轉(zhuǎn)發(fā)到每個(gè)參與節(jié)點(diǎn)弄匕。
-
使用 mget 取回多個(gè)文檔
以下是使用單個(gè) mget 請(qǐng)求取回多個(gè)文檔所需的步驟順序:
- 客戶(hù)端向 Node 1 發(fā)送 mget 請(qǐng)求颅悉。
- Node 1 為每個(gè)分片構(gòu)建多文檔獲取請(qǐng)求,然后并行轉(zhuǎn)發(fā)這些請(qǐng)求到托管在每個(gè)所需的主分片或者副本分片的節(jié)點(diǎn)上迁匠。一旦收到所有答復(fù)签舞, Node 1 構(gòu)建響應(yīng)并將其返回給客戶(hù)端。
-
使用 bulk 修改多個(gè)文檔
bulk API 按如下步驟順序執(zhí)行:
- 客戶(hù)端向 Node 1 發(fā)送 bulk 請(qǐng)求柒瓣。
- Node 1 為每個(gè)節(jié)點(diǎn)創(chuàng)建一個(gè)批量請(qǐng)求儒搭,并將這些請(qǐng)求并行轉(zhuǎn)發(fā)到每個(gè)包含主分片的節(jié)點(diǎn)主機(jī)。
- 主分片一個(gè)接一個(gè)按順序執(zhí)行每個(gè)操作芙贫。當(dāng)每個(gè)操作成功時(shí)搂鲫,主分片并行轉(zhuǎn)發(fā)新文檔(或刪除)到副本分片,然后執(zhí)行下一個(gè)操作磺平。一旦所有的副本分片報(bào)告所有操作成功魂仍,該節(jié)點(diǎn)將向協(xié)調(diào)節(jié)點(diǎn)報(bào)告成功,協(xié)調(diào)節(jié)點(diǎn)將這些響應(yīng)收集整理并返回給客戶(hù)端拣挪。