elasticsearch專欄:https://www.cnblogs.com/hello-shf/category/1550315.htmlhtml
在對document的curd進行深度分析以前,咱們不得不瞭解如下幾個小的知識點,不瞭解一下幾個知識點咱們將很難理解document是如何進行增刪改查的。node
你們有沒有考慮過這個問題,當你索引一個文檔,它被存儲在單獨一個主分片上。Elasticsearch是如何知道文檔屬於哪一個分片的呢?當你建立一個新文檔,它是如何知道是應該存儲在分片1仍是分片2上的呢? 進程不能是隨機的,由於咱們未來要檢索文檔。事實上,它根據一個簡單的算法決定:算法
shard = hash(routing) % number_of_primary_shards
routing值是一個任意字符串,它默認是 _id 但也能夠自定義。這個 routing 字符串經過哈 希函數生成一個數字,而後除以主切片的數量獲得一個餘數(remainder),餘數的範圍永遠 是 0 到 number_of_primary_shards - 1 ,這個數字就是特定文檔所在的分片。負載均衡
這也解釋了爲何主分片的數量只能在建立索引時定義且不能修改:若是主分片的數量在將來改變了,全部先前的路由值就失效了,文檔也就永遠找不到了。async
咱們演示一下這個路由的過程。假設咱們有三個節點,一個student索引,對應有三個primary shard和一個replica shard。此時集羣如圖1所示elasticsearch
向該節點中插入一個document,而且咱們指定_id(在es中_id能夠自定義es也能夠自動生成)假如_id = 1000,根據咱們上面描述,此時會按照以下算法計算其會命中哪一個shard。假設此時hash(1000)= 13;函數
shard = hash(routing) % number_of_primary_shards 即: shard = 13 % 3 = 1;(假設hash(1000) = 13) 注:由於es的hash函數具體是怎麼計算的不得而知,也不重要,咱們主要是關注其原理。
根據計算可得該插入請求會命中P1,shard此時會將該document插入到P1。是否是很簡單。性能
以上也可就是es路由的過程,也可稱爲es索引(這個索引是動詞,理解一下)過程。spa
在es集羣中每一個節點,每一個shard(包括primary shard和replica shard)都具有處理任何請求的能力。這意味着在es集羣中節點間是高度的負載均衡的,即並非只有主節點是流量的入口,每一個節點都具有處理請求的能力。primary shard和replica shard也是高度負載均衡的,由於並非只有primary shard才具有處理curd的能力,replica shard可處理檢索的請求。這也是es的性能爲何表現這麼好的緣由之一。code
新建、索引和刪除請求都是寫(write)操做,它們必須在primary shard上成功完成才能複製到相關的replica shard分片上。
關於新增document索引過程能夠參考《es的索引過程》
如上圖所示,從客戶端發起請求到es集羣向客戶端響應大體能夠分爲以上6個階段。
階段1:
客戶端向node1發起增、刪、改請請求。node1將做爲協調節點(coordinate node)進行相關工做。
階段2:
node1根據文檔 _id 計算出命中的primary shard爲P1,而後將請求轉發到node2,P1分片位於node2上面。
階段3:
node2在P1上處理該請求。若是請求處理成功,node2將會把請求繼續轉發到其副本R1上。R1位於node3。
階段4:
node3在R1上處理完該請求,若是成功,node3會將處理成功的消息返回給node2。
階段5:
node2收到P1副本處理成功的消息,也就意味着該請求已經處理完成。而後將處理結果返回給node1節點。
階段6:
協調節點node1收到響應結果後,將該結果返回給客戶端。
整個過程就完成了。
看到這裏你們是否是也在思考一個請求進來,我還要等待全部的分片都處理完成這個操做纔算是完成,這樣是否是很影響響應速度。基於這個思考,es一樣也給咱們提供了自定義參數的支持,好比咱們可使用replication參數來指定primary shard是否是要等到replica shard處理完成後才能響應到客戶端。可是,該配置配置參數並不推薦使用,你們知道有這麼個東西就好了。
1 one:要求咱們這個寫操做,只要有一個primary shard是active活躍可用的,就能夠執行。 2 all:要求咱們這個寫操做,必須全部的primary shard和replica shard都是活躍的,才能夠執行這個寫操做 3 quorum:默認的值,要求全部的shard中,必須是大部分的shard都是活躍的,可用的,才能夠執行這個寫操做
上面三點其實很好理解,只有quorum所謂的「大部分」感受不是那麼的明確。下面有個公式,當集羣中的active(可用)分片數量達到以下公式結果時寫操做就是能夠執行的。不然該操做將沒法進行。
int( (primary + number_of_replicas) / 2 ) + 1
依然用咱們上面的例子,假設咱們建立了一個student索引,而且設置primary shard爲3個,replica shard有1個(這個1個是相對於索引來講的,對於主分片該數字1意味着每一個primary shard都對應的存在一個副本)。也就意味着primary=3,number_of_replicas=1(依然是相對於索引)。shard總數爲6。
此時計算上面公式可知:
int((3+1)/2) + 1 = 3
PUT /index/type/id?consistency=quorum
固然若是咱們不指定就是使用默認的,也就是quorum。
檢索過程大體能夠分爲4個階段
階段1:
客戶端向node1發送檢索請求。node1將做爲協調節點(coordinate node)進行相關工做。
階段2:
node1根據文檔 _id 計算出命中的primary shard爲P1,node1會找到P1的全部副本,而後經過round-robin隨機輪詢算法,在primary shard以及其全部replica中隨機選擇一個,讓讀請求負載均衡。假如此時隨機選取的是P1,node1會將該請求轉發到P1對應的節點上。
階段3:
P1處理完該請求將結果返回給協調節點node1。
階段4:
協調節點node1收到該node2的相應結果,進而將該結果返回給客戶端。
參考文獻:
《elasticsearch-權威指南》
若有錯誤的地方還請留言指正。
原創不易,轉載請註明原文地址:http://www.javashuo.com/article/p-qdjxjksb-cn.html