elasticsearch專(zhuān)欄:https://www.cnblogs.com/hello-shf/category/1550315.html
一、預(yù)備知識(shí)
在對(duì)document的curd進(jìn)行深度分析之前,我們不得不了解以下幾個(gè)小的知識(shí)點(diǎn),不了解一下幾個(gè)知識(shí)點(diǎn)我們將很難理解document是如何進(jìn)行增刪改查的。
1.1、路由(索引)與primary shard不可變
大家有沒(méi)有考慮過(guò)這個(gè)問(wèn)題,當(dāng)你索引一個(gè)文檔,它被存儲(chǔ)在單獨(dú)一個(gè)主分片上。Elasticsearch是如何知道文檔屬于哪個(gè)分片的呢?當(dāng)你創(chuàng)建一個(gè)新文檔,它是如何知道是應(yīng)該存儲(chǔ)在分片1還是分片2上的呢? 進(jìn)程不能是隨機(jī)的,因?yàn)槲覀儗?lái)要檢索文檔。事實(shí)上,它根據(jù)一個(gè)簡(jiǎn)單的算法決定:
shard = hash(routing) % number_of_primary_shards
routing值是一個(gè)任意字符串,它默認(rèn)是 _id 但也可以自定義。這個(gè) routing 字符串通過(guò)哈 希函數(shù)生成一個(gè)數(shù)字,然后除以主切片的數(shù)量得到一個(gè)余數(shù)(remainder),余數(shù)的范圍永遠(yuǎn) 是 0 到 number_of_primary_shards - 1 ,這個(gè)數(shù)字就是特定文檔所在的分片。
這也解釋了為什么主分片的數(shù)量只能在創(chuàng)建索引時(shí)定義且不能修改:如果主分片的數(shù)量在未來(lái)改變了,所有先前的路由值就失效了,文檔也就永遠(yuǎn)找不到了。
我們演示一下這個(gè)路由的過(guò)程。假設(shè)我們有三個(gè)節(jié)點(diǎn),一個(gè)student索引,對(duì)應(yīng)有三個(gè)primary shard和一個(gè)replica shard。此時(shí)集群如圖1所示
向該節(jié)點(diǎn)中插入一個(gè)document,并且我們指定_id(在es中_id可以自定義es也可以自動(dòng)生成)假如_id = 1000,根據(jù)我們上面描述,此時(shí)會(huì)按照如下算法計(jì)算其會(huì)命中哪個(gè)shard。假設(shè)此時(shí)hash(1000)= 13;
shard = hash(routing) % number_of_primary_shards 即: shard = 13 % 3 = 1;(假設(shè)hash(1000) = 13) 注:因?yàn)閑s的hash函數(shù)具體是怎么計(jì)算的不得而知,也不重要,我們主要是關(guān)注其原理。
根據(jù)計(jì)算可得該插入請(qǐng)求會(huì)命中P1,shard此時(shí)會(huì)將該document插入到P1。是不是很簡(jiǎn)單。
以上也可就是es路由的過(guò)程,也可稱(chēng)為es索引(這個(gè)索引是動(dòng)詞,理解一下)過(guò)程。
1.2、shard負(fù)載均衡與節(jié)點(diǎn)對(duì)等
在es集群中每個(gè)節(jié)點(diǎn),每個(gè)shard(包括primary shard和replica shard)都具備處理任何請(qǐng)求的能力。這意味著在es集群中節(jié)點(diǎn)間是高度的負(fù)載均衡的,即并不是只有主節(jié)點(diǎn)是流量的入口,每個(gè)節(jié)點(diǎn)都具備處理請(qǐng)求的能力。primary shard和replica shard也是高度負(fù)載均衡的,因?yàn)椴⒉皇侵挥衟rimary shard才具備處理curd的能力,replica shard可處理檢索的請(qǐng)求。這也是es的性能為什么表現(xiàn)這么好的原因之一。
二、document增、刪、改
2.1、增刪改過(guò)程分析
新建、索引和刪除請(qǐng)求都是寫(xiě)(write)操作,它們必須在primary shard上成功完成才能復(fù)制到相關(guān)的replica shard分片上。
關(guān)于新增document索引過(guò)程可以參考《es的索引過(guò)程》
如上圖所示,從客戶(hù)端發(fā)起請(qǐng)求到es集群向客戶(hù)端響應(yīng)大致可以分為以上6個(gè)階段。
階段1:
客戶(hù)端向node1發(fā)起增、刪、改請(qǐng)請(qǐng)求。node1將作為協(xié)調(diào)節(jié)點(diǎn)(coordinate node)進(jìn)行相關(guān)工作。
階段2:
node1根據(jù)文檔 _id 計(jì)算出命中的primary shard為P1,然后將請(qǐng)求轉(zhuǎn)發(fā)到node2,P1分片位于node2上面。
階段3:
node2在P1上處理該請(qǐng)求。如果請(qǐng)求處理成功,node2將會(huì)把請(qǐng)求繼續(xù)轉(zhuǎn)發(fā)到其副本R1上。R1位于node3。
階段4:
,【碎他】【有虎】【本就】【機(jī)會(huì)】【個(gè)性】【很不】【間都】【無(wú)盡】【強(qiáng)者】【族沒(méi)】【她那】【好東】【撲面】【體異】1938年為了守住山西,川軍47軍將士在李家鈺將軍的率領(lǐng)下,在東陽(yáng)關(guān)死守3日犧牲兩千余人。9月30日首個(gè)國(guó)家烈士紀(jì)念日前后,《華西都市報(bào)》連續(xù)報(bào)道了東陽(yáng)關(guān)戰(zhàn)役后,抗戰(zhàn)老兵的系列報(bào)道引起了百度霸屏不少人的關(guān)注。家住巴中市平昌縣97歲陳海才老人看了本報(bào)的報(bào)道后,把自己埋藏在心底的秘密告訴了家人,“我當(dāng)年也在東陽(yáng)關(guān)打過(guò)鬼子,現(xiàn)在要入土了,想見(jiàn)見(jiàn)當(dāng)年的戰(zhàn)友?!背脤?duì)方做雞蛋餅的間隙,記者和攤主聊了起來(lái),她告訴記者她姓董,在這里賣(mài)雞蛋餅已經(jīng)10多年了,附近人都喜歡吃她做的雞蛋餅。“我用的材料都很實(shí)在,大家都能看得到,也吃得放心?!闭f(shuō)起自己的雞蛋餅,董阿姨說(shuō)真的沒(méi)什么秘訣,主要是自己材料放得足,貨真價(jià)實(shí)?!百嵅坏蕉嗌馘X(qián),就圖個(gè)開(kāi)心。,node3在R1上處理完該請(qǐng)求,如果成功,node3會(huì)將處理成功的消息返回給node2。
階段5:
node2收到P1副本處理成功的消息,也就意味著該請(qǐng)求已經(jīng)處理完成。然后將處理結(jié)果返回給node1節(jié)點(diǎn)。
階段6:
協(xié)調(diào)節(jié)點(diǎn)node1收到響應(yīng)結(jié)果后,將該結(jié)果返回給客戶(hù)端。
整個(gè)過(guò)程就完成了。
看到這里大家是不是也在思考一個(gè)請(qǐng)求進(jìn)來(lái),我還要等待所有的分片都處理完成這個(gè)操作才算是完成,這樣是不是很影響響應(yīng)速度。基于這個(gè)思考,es同樣也給我們提供了自定義參數(shù)的支持,比如我們可以使用replication參數(shù)來(lái)指定primary shard是不是要等到replica shard處理完成后才能響應(yīng)到客戶(hù)端。但是,該配置配置參數(shù)并不推薦使用,大家知道有這么個(gè)東西就行了。
replication:默認(rèn)值為 sync 該值意味著primary shard需要等到其所有的副本分片都完成后才會(huì)響應(yīng)客戶(hù)端。如果我們將該值設(shè)置為 async ,意味著primary shard完成后就會(huì)返回給客戶(hù)端,但是并不意味著其不會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到副本上,主分片依然會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到replica shard上,只不過(guò)我們不再確定副本是不是也完成了該請(qǐng)求,這樣將不能保證數(shù)據(jù)的一致性。2.1、寫(xiě)一致性保障
首先需要說(shuō)明的一點(diǎn),增刪改其實(shí)都是一個(gè)寫(xiě)操作,所以這里的寫(xiě)指的是增刪改三個(gè)操作。 這里我們所說(shuō)的寫(xiě)一致性指的是primary shard和replica shard上數(shù)據(jù)的一致性。es API為我們提供了一個(gè)可自定的參數(shù)consistency。該參數(shù)可以讓我們自定義處理一次增刪改請(qǐng)求,是不是必須要求所有分片都是active的才會(huì)執(zhí)行。 該參數(shù)可選的值有三個(gè):one,all,quorum(default,默認(rèn))。1 one:要求我們這個(gè)寫(xiě)操作,只要有一個(gè)primary shard是active活躍可用的,就可以執(zhí)行。 2 all:要求我們這個(gè)寫(xiě)操作,必須所有的primary shard和replica shard都是活躍的,才可以執(zhí)行這個(gè)寫(xiě)操作 3 quorum:默認(rèn)的值,要求所有的shard中,必須是大部分的shard都是活躍的,可用的,才可以執(zhí)行這個(gè)寫(xiě)操作
上面三點(diǎn)其實(shí)很好理解,只有quorum所謂的“大部分”感覺(jué)不是那么的明確。下面有個(gè)公式,當(dāng)集群中的active(可用)分片數(shù)量達(dá)到如下公式結(jié)果時(shí)寫(xiě)操作就是可以執(zhí)行的。否則該操作將無(wú)法進(jìn)行。
int( (primary + number_of_replicas) / 2 ) + 1
依然用我們上面的例子,假設(shè)我們創(chuàng)建了一個(gè)student索引,并且設(shè)置primary shard為3個(gè),replica shard有1個(gè)(這個(gè)1個(gè)是相對(duì)于索引來(lái)說(shuō)的,對(duì)于主分片該數(shù)字1意味著每個(gè)primary shard都對(duì)應(yīng)的存在一個(gè)副本)。也就意味著primary=3,number_of_replicas=1(依然是相對(duì)于索引)。shard總數(shù)為6。
此時(shí)計(jì)算上面公式可知:
int((3+1)/2) + 1 = 3 也就是說(shuō)當(dāng)集群中可用的shard數(shù)量>=3寫(xiě)操作就是可以執(zhí)行的。 說(shuō)了這么多好像還沒(méi)解釋以上跟寫(xiě)一致性有什么關(guān)系。es對(duì)寫(xiě)一致性的保證就是通過(guò)quorum來(lái)保證的,以為quorum要求es集群中的可用shard數(shù)量達(dá)到一定要求才能執(zhí)行。也就間接保證了shard的數(shù)據(jù)一致性。 具體使用也很簡(jiǎn)單
PUT /index/type/id?consistency=quorum
當(dāng)然如果我們不指定就是使用默認(rèn)的,也就是quorum。
三、document檢索
document的檢索過(guò)程和增刪改略有不同:文檔能夠從主分片(primary shard)或任意一個(gè)復(fù)制分片(replicashard)被檢索。
檢索過(guò)程大致可以分為4個(gè)階段
階段1:
客戶(hù)端向node1發(fā)送檢索請(qǐng)求。node1將作為協(xié)調(diào)節(jié)點(diǎn)(coordinate node)進(jìn)行相關(guān)工作。
階段2:
node1根據(jù)文檔 _id 計(jì)算出命中的primary shard為P1,node1會(huì)找到P1的所有副本,然后通過(guò)round-robin隨機(jī)輪詢(xún)算法,在primary shard以及其所有replica中隨機(jī)選擇一個(gè),讓讀請(qǐng)求負(fù)載均衡。假如此時(shí)隨機(jī)選取的是P1,node1會(huì)將該請(qǐng)求轉(zhuǎn)發(fā)到P1對(duì)應(yīng)的節(jié)點(diǎn)上。
階段3:
P1處理完該請(qǐng)求將結(jié)果返回給協(xié)調(diào)節(jié)點(diǎn)node1。
階段4:
協(xié)調(diào)節(jié)點(diǎn)node1收到該node2的相應(yīng)結(jié)果,進(jìn)而將該結(jié)果返回給客戶(hù)端。
可能的情況是,一個(gè)被索引的文檔已經(jīng)存在于主分片上卻還沒(méi)來(lái)得及同步到復(fù)制分片上。這時(shí)復(fù)制分片會(huì)報(bào)告文檔未找到,主分片會(huì)成功返回文檔。一旦索引請(qǐng)求成功返回給用戶(hù),文檔則在主分片和復(fù)制分片都是可用的。 對(duì)與mget和bulk批量請(qǐng)求,與單文檔檢索還有一點(diǎn)區(qū)別,差別是協(xié)調(diào)節(jié)點(diǎn)需要計(jì)算每個(gè)文檔所在的分片。它把多文檔請(qǐng)求拆成每個(gè)分片的對(duì)文檔請(qǐng)求,然后轉(zhuǎn)發(fā)每個(gè)參與的節(jié)點(diǎn)。一旦接收到每個(gè)節(jié)點(diǎn)的應(yīng)答,然后整理這些響應(yīng)組合為一個(gè)單獨(dú)的響應(yīng),最后返回給客戶(hù)端。
參考文獻(xiàn):
《elasticsearch-權(quán)威指南》
如有錯(cuò)誤的地方還請(qǐng)留言指正。
原創(chuàng)不易,轉(zhuǎn)載請(qǐng)注明原文地址:https://www.cnblogs.com/hello-shf/p/11543480.html
|轉(zhuǎn)載請(qǐng)注明來(lái)源地址:蜘蛛池出租 http://www.wholesalehouseflipping.com/專(zhuān)注于SEO培訓(xùn),快速排名黑帽SEO https://www.heimao.wiki
