天天看點

Elasticsearch資料寫入流程寫請求原理

寫請求原理

Elasticsearch資料寫入流程寫請求原理

以下是寫單個文檔所需的步驟:

(1 )用戶端向 NODE I 發送寫請求。

(2)檢查Active的Shard數。

(3) NODEI 使用文檔 ID 來确定文檔屬于分片 0,通過叢集狀态中的内容路由表資訊獲知分片 0 的主分片位于 NODE3 ,是以請求被轉發到 NODE3 上。

( 4 ) NODE3 上的主分片執行寫操作 。 如果寫入成功,則它将請求并行轉發到 NODE I 和

NODE2 的副分片上,等待傳回結果 。當所有的副分片都報告成功, NODE3 将向協調節點報告

成功,協調節點再向用戶端報告成功 。

在用戶端收到成功響應時 ,意味着寫操作已經在主分片和所有副分片都執行完成。

1. 為什麼要檢查Active的Shard數?

ES中有一個參數,叫做waitforactiveshards,這個參數是Index的一個setting,也可以在請求中帶上這個參數。這個參數的含義是,在每次寫入前,該shard至少具有的active副本數。假設我們有一個Index,其每個Shard有3個Replica,加上Primary則總共有4個副本。如果配置waitforactiveshards為3,那麼允許最多有一個Replica挂掉,如果有兩個Replica挂掉,則Active的副本數不足3,此時不允許寫入。

這個參數預設是1,即隻要Primary在就可以寫入,起不到什麼作用。如果配置大于1,可以起到一種保護的作用,保證寫入的資料具有更高的可靠性。但是這個參數隻在寫入前檢查,并不保證資料一定在至少這些個副本上寫入成功,是以并不是嚴格保證了最少寫入了多少個副本。

在以前的版本中,是寫一緻性機制,現被替換為waitforactiveshards

one:要求我們這個寫操作,隻要有一個primary shard是active活躍可用的,就可以執行

all:要求我們這個寫操作,必須所有的primary shard和replica shard都是活躍的,才可以執行這個寫操作

quorum:要求所有的shard中,必須是大部分的shard都是活躍的,可用的,才可以執行這個寫操作

寫一緻性的預設政策是 quorum,即多數的分片(其中分片副本可以是主分片或副分片)在

寫入操作時處于可用狀态。

put /index/type/id?consistency=quorum
quroum = int( (primary + number_of_replicas) / 2 ) + 1
           
參數 簡 介
version 設定文檔版本号。主要用于實作樂觀鎖
version_type 詳見版本類型
op_type 可設定為 create 。 代表僅在文檔不存在時才寫入 。 如果文檔己存在,則寫請求将失敗
routing ES 預設使用文檔 ID 進行路由,指定 routing 可使用 routing 值進行路由
wait_for_active_shards 用于控制寫一緻性,當指定數量的分片副本可用時才執行寫入,否則重試直至逾時 。預設為 l , 主分片可用 即執行寫入
refresh 寫入完畢後執行 refresh ,使其對搜尋可見
timeout 請求逾時時間 , 預設為 l 分鐘
pipeline 指定事先建立好的 pipeline 名稱

寫入Primary完成後,為何要等待所有Replica響應(或連接配接失敗)後傳回

在更早的ES版本,Primary和Replica之間是允許異步複制的,即寫入Primary成功即可傳回。但是這種模式下,如果Primary挂掉,就有丢資料的風險,而且從Replica讀資料也很難保證能讀到最新的資料。是以後來ES就取消異步模式了,改成Primary等Replica傳回後再傳回給用戶端。

因為Primary要等所有Replica傳回才能傳回給用戶端,那麼延遲就會受到最慢的Replica的影響,這确實是目前ES架構的一個弊端。之前曾誤認為這裡是等waitforactive_shards個副本寫入成功即可傳回,但是後來讀源碼發現是等所有Replica傳回的。

如果Replica寫入失敗,ES會執行一些重試邏輯等,但最終并不強求一定要在多少個節點寫入成功。在傳回的結果中,會包含資料在多少個shard中寫入成功了,多少個失敗了

 本文涉及的知識可以參考其他網友文章:https://zhuanlan.zhihu.com/p/94915597 和 https://blog.csdn.net/haibucuoba/article/details/97166155

備注:本文内容轉自魯班學院語雀筆記,如有問題請聯系删除。