日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ElasticSearch探索之路(三)分布式原理:分布式路由、存储、搜索原理

發布時間:2024/4/11 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ElasticSearch探索之路(三)分布式原理:分布式路由、存储、搜索原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 分布式存儲
    • 路由
    • 新增、索引和刪除文檔
    • 取回文檔
    • 并發控制
  • 分布式搜索
    • 查詢階段
    • 取回階段


分布式存儲

路由

當索引一個文檔的時候,Elasticsearch會通過哈希來決定將文檔存儲到哪一個主分片中,路由計算公式如下:

shard = hash(routing) % number_of_primary_shards//routing:默認為文檔id,也可以自定義。 //number_of_primary_shards:主分片的數量
  • 查詢時指定routing:可以直接根據routing信息定位到某個分片查詢,不需要查詢所有的分配,經

    過協調節點排序。

  • 查詢時不指定routing:因為不知道要查詢的數據具體在哪個分片上,所以整個過程分為 2 個步驟

  • 分發:請求到達協調節點后,協調節點將查詢請求分發到每個分片上。
  • 聚合:協調節點搜集到每個分片上查詢結果,在將查詢的結果進行排序,之后給用戶返回結果。

從上面的這個公式我們也可以看到一個問題,路由的邏輯與當前主分片的數量強關聯,也就是說如果分片數量變化了,那么所有之前路由的值都會無效,文檔也再也找不到了。這也就是為什么我們要在創建索引的時候就確定好主分片的數量并且永遠不會改變這個數量


分片數量固定是否意味著會使索引難以進行擴容?

答案是否定的,Elasticsearch還提供了其他的一些方案來讓我們輕松的實現擴容,如:

  • 分片預分配:一個分片存在于單個節點,但一個節點可以持有多個分片。因此我們可以根據未來的數據的擴張狀況來預先分配一定數量的分片到各個節點中。(注意??:預先分配過多的分片會導致性能的下降以及影響搜索結果的相關度)
  • 新建索引:分片數不夠時,可以考慮新建索引,搜索1個有著50個分片的索引與搜索50個每個都有1個分片的索引完全等價。

更多關于水平拓展的內容可以參考官方文檔擴容設計


新增、索引和刪除文檔

我們可以發送請求到集群中的任一節點。 每個節點都有能力處理任意請求。 每個節點都知道集群中任一文檔位置,所以可以直接將請求轉發到需要的節點上。 在下面的例子中,將所有的請求發送到 Node 1 ,我們將其稱為協調節點(coordinating node)

當發送請求的時候, 為了擴展負載,更好的做法是輪詢集群中所有的節點。

新建、索引和刪除請求都是寫操作, 必須在主分片上面完成之后才能被復制到相關的副本分片。

新建、索引和刪除單個文檔

流程如下:

  • 客戶端向 Node 1 發送新建、索引或者刪除請求。
  • 節點使用文檔的 _id 確定文檔屬于分片 0 。請求會被轉發到 Node 3,因為分片 0 的主分片目前被分配在 Node 3 上。
  • Node 3 在主分片上面執行請求。如果成功了,它將請求并行轉發到 Node 1 和 Node 2 的副本分片上。一旦所有的副本分片都報告成功, Node 3 將向協調節點報告成功,協調節點向客戶端報告成功。

  • 取回文檔

    由于取回文檔為讀操作,我們可以從主分片或者從其它任意副本分片檢索文檔。

    取回單個文檔

    流程如下:

  • 客戶端向 Node 1 發送獲取請求。
  • 節點使用文檔的 _id 來確定文檔屬于分片 0 。分片 0 的副本分片存在于所有的三個節點上。 在這種情況下,它將請求轉發到 Node 2 。
  • Node 2 將文檔返回給 Node 1 ,然后將文檔返回給客戶端。
  • 在處理讀取請求時,協調結點在每次請求的時候都會通過輪詢所有的副本分片來達到負載均衡。


    并發控制

    在數據庫領域中,有兩種方法通常被用來確保并發更新時變更不會丟失:

    • 悲觀并發控制:這種方法被關系型數據庫廣泛使用,它假定有變更沖突可能發生,因此阻塞訪問資源以防止沖突。 一個典型的例子是讀取一行數據之前先將其鎖住,確保只有放置鎖的線程能夠對這行數據進行修改。
    • 樂觀并發控制:Elasticsearch中使用的這種方法假定沖突是不可能發生的,并且不會阻塞正在嘗試的操作。 然而,如果源數據在讀寫當中被修改,更新將會失敗。應用程序接下來將決定該如何解決沖突。 例如,可以重試更新、使用新的數據、或者將相關情況報告給用戶。

    Elasticsearch是分布式的。當文檔創建、更新或刪除時, 新版本的文檔必須復制到集群中的其他節點。Elasticsearch也是異步和并發的,這意味著這些復制請求被并行發送,并且到達目的地時也許會亂序。所以Elasticsearch 需要一種方法確保文檔的舊版本不會覆蓋新的版本。

    在Elasticsearch中,其通過版本號機制來實現樂觀并發控制。即每一個文檔中都會有一個_version版本號字段,當文檔被修改時版本號遞增。 Elasticsearch使用_version來確保變更以正確順序得到執行。如果舊版本的文檔在新版本之后到達,它可以被簡單的忽略。

    我們可以利用_version號來確保應用中相互沖突的變更不會導致數據丟失。我們通過指定想要修改文檔的 version 號來達到這個目的。 如果該版本不是當前版本號,我們的請求將會失敗。

    // 例如我們想更新文檔的內容,并指定版本號為1 PUT /website/blog/1?version=1 {"title": "My first blog entry","text": "Starting to get the hang of this..." }// 當文檔的版本號為1時,次請求成功,同時響應體告訴我們版本號遞增到2 {"_index": "website","_type": "blog","_id": "1","_version": 2"created": false }// 此時我們再次嘗試更新文檔的內容,仍然指定版本號為1,由于版本號不符合,此時返回409 Conflict HTTP 響應碼 {"error": {"root_cause": [{"type": "version_conflict_engine_exception","reason": "[blog][1]: version conflict, current [2], provided [1]","index": "website","shard": "3"}],"type": "version_conflict_engine_exception","reason": "[blog][1]: version conflict, current [2], provided [1]","index": "website","shard": "3"},"status": 409 }


    分布式搜索

    搜索需要一種更加復雜的執行模型,因為我們不知道查詢會命中哪些文檔,這些文檔有可能在集群的任何分片上。 一個搜索請求必須詢問我們關注的索引的所有分片的某個副本來確定它們是否含有任何匹配的文檔。

    但是找到所有的匹配文檔僅僅完成事情的一半。 在 search 接口返回一個 page 結果之前,多分片中的結果必須組合成單個排序列表。 為此,搜索被執行成一個兩階段過程,我們稱之為query then fetch(查詢后取回)。


    查詢階段

    在查詢階段時, 查詢會廣播到索引中每一個分片拷貝(主分片或者副本分片)。 每個分片在本地執行搜索并構建一個匹配文檔的優先隊列。

    分布式搜索的查詢過程

    查詢階段包含以下三個步驟

  • 客戶端發送一個 search 請求到 Node 3 ,此時Node 3成為協調節點,由它來負責本次的查詢。
  • Node 3 將查詢請求廣播到索引的每個主分片或副本分片中。每個分片在本地執行查詢并添加結果到大小為 from + size 的本地有序優先隊列中。
  • 每個分片返回各自優先隊列中所有文檔的ID和排序值給協調節點,也就是 Node 3 ,它合并這些值到自己的優先隊列中來產生一個全局排序后的結果列表。至此查詢過程結束。
  • 一個索引可以由一個或幾個主分片組成, 所以一個針對單個索引的搜索請求需要能夠把來自多個分片的結果組合起來。 針對 multiple 或者 all 索引的搜索工作方式也是完全一致的——僅僅是包含了更多的分片而已。


    取回階段

    在查詢階段中,我們標識了哪些文檔滿足搜索請求,而接下來我們就需要取回這些文檔。

    分布式搜索的取回階段

    取回階段由以下步驟構成

  • 協調節點辨別出哪些文檔需要被取回并向相關的分片提交多個 GET 請求。例如,如果我們的查詢指定了 { "from": 90, "size": 10 } ,最初的90個結果會被丟棄,只有從第91個開始的10個結果需要被取回。
  • 每個分片加載并豐富文檔(如_source字段和高亮參數),接著返回文檔給協調節點。
  • 協調節點等待所有文檔被取回,將結果返回給客戶端。
  • 總結

    以上是生活随笔為你收集整理的ElasticSearch探索之路(三)分布式原理:分布式路由、存储、搜索原理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。