日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

ElasticSearch探索之路(五)集群与分片:选举、动态更新、近实时搜索、事务日志、段合并

發(fā)布時間:2024/4/11 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ElasticSearch探索之路(五)集群与分片:选举、动态更新、近实时搜索、事务日志、段合并 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 集群內(nèi)部原理
    • 集群與節(jié)點
    • 分片
    • 選舉
  • 分片內(nèi)部原理
    • 索引不變性
    • 動態(tài)更新索引
    • 近實時搜索
    • 事務(wù)日志
    • 段合并


集群內(nèi)部原理

集群與節(jié)點

一個運行中的Elasticsearch實例稱為一個節(jié)點,而集群是由一個或者多個擁有相同 cluster.name 配置的節(jié)點組成, 它們共同承擔(dān)數(shù)據(jù)和負(fù)載的壓力。當(dāng)有節(jié)點加入集群中或者從集群中移除節(jié)點時,集群將會重新平均分布所有的數(shù)據(jù)。

一個有3個節(jié)點的集群,索引被劃分為五份分片,每個分片有一個副本分片

由于Elasticsearch采用了主從模式,所以當(dāng)一個節(jié)點被選舉成為主節(jié)點時, 它將負(fù)責(zé)管理集群范圍內(nèi)的所有變更,例如增加、刪除索引,或者增加、刪除節(jié)點等。 因為主節(jié)點并不需要涉及到文檔級別的變更和搜索等操作,所以當(dāng)集群只擁有一個主節(jié)點的情況下,即使流量的增加它也不會成為瓶頸。 任何節(jié)點都可以成為主節(jié)點。

作為用戶,我們可以將請求發(fā)送到集群中的任何節(jié)點(這個處理請求的節(jié)點也叫做協(xié)調(diào)節(jié)點)。 每個節(jié)點都知道任意文檔所處的位置,并且能夠?qū)⑽覀兊恼埱笾苯愚D(zhuǎn)發(fā)到存儲我們所需文檔的節(jié)點。 無論我們將請求發(fā)送到哪個節(jié)點,它都能負(fù)責(zé)從各個包含我們所需文檔的節(jié)點收集回數(shù)據(jù),并將最終結(jié)果返回給客戶端。


分片

在分布式系統(tǒng)中,單機無法存儲規(guī)模巨大的數(shù)據(jù),要依靠大規(guī)模集群處理和存儲這些數(shù)據(jù),一般通過增加機器數(shù)量來提高系統(tǒng)水平擴展能力。因此,需要將數(shù)據(jù)分成若干小塊分配到各個機器上。然后通過某種路由策略找到某個數(shù)據(jù)塊所在的位置。

分片(shard)是底層的基本讀寫單元,分片的目的是分割巨大索引,讓讀寫可以并行操作,由多臺機器共同完成。讀寫請求最終落到某個分片上,分片可以獨立執(zhí)行讀寫工作。Elasticsearch利用分片將數(shù)據(jù)分發(fā)到集群內(nèi)各處。分片是數(shù)據(jù)的容器,文檔保存在分片內(nèi),不會跨分片存儲。分片又被分配到集群內(nèi)的各個節(jié)點里。當(dāng)集群規(guī)模擴大或縮小時,Elasticsearch會自動在各節(jié)點中遷移分片,使數(shù)據(jù)仍然均勻分布在集群里。

為了應(yīng)對并發(fā)更新問題,Elasticsearch將分片分為兩部分,即主分片(primary shard)副本分片(replica shard)。主數(shù)據(jù)作為權(quán)威數(shù)據(jù),寫過程中先寫主分片,成功后再寫副分片,恢復(fù)階段以主分片為準(zhǔn)。

一個副本分片只是一個主分片的拷貝。副本分片作為硬件故障時保護數(shù)據(jù)不丟失的冗余備份,并為搜索和返回文檔等讀操作提供服務(wù)。

數(shù)據(jù)分片和數(shù)據(jù)副本的關(guān)系

那索引與分片之間又有什么關(guān)系呢?

一個Elasticsearch索引包含了很多個分片,每個分片又是一個Lucene的索引,它本身就是一個完整的搜索引擎,可以獨立執(zhí)行建立索引和搜索任務(wù)。Lucene索引又由很多分段組成,每個分段都是一個倒排索引。Elasticsearch每次refresh都會生成一個新的分段,其中包含若干文檔的數(shù)據(jù)。在每個分段內(nèi)部,文檔的不同字段被單獨建立索引。每個字段的值由若干詞(Term)組成,Term是原文本內(nèi)容經(jīng)過分詞器處理和語言處理后的最終結(jié)果。

索引、分片、段、字段、詞之間的關(guān)系

選舉

在主節(jié)點選舉算法的選擇上,基本原則是不重復(fù)造輪子。最好實現(xiàn)一個眾所周知的算法,這樣的好處是其中的優(yōu)點和缺陷是已知的。Elasticsearch的選舉算法的選擇上主要考慮下面兩種。

  • Bully算法:Leader選舉的基本算法之一。它假定所有節(jié)點都有一個唯一的ID,使用該ID對節(jié)點進行排序。任何時候的當(dāng)前Leader都是參與集群的最高ID節(jié)點。該算法的優(yōu)點是易于實現(xiàn)。但是,當(dāng)擁有最大ID的節(jié)點處于不穩(wěn)定狀態(tài)的場景下會有問題。例如,Master負(fù)載過重而假死,集群擁有第二大ID的節(jié)點被選為新主,這時原來的Master恢復(fù),再次被選為新主,然后又假死……
  • Paxos算法:Paxos非常強大,尤其在什么時機,以及如何進行選舉方面的靈活性比簡單的Bully算法有很大的優(yōu)勢,因為在現(xiàn)實生活中,存在比網(wǎng)絡(luò)連接異常更多的故障模式。但Paxos實現(xiàn)起來非常復(fù)雜。

Elasticsearch的選主算法是基于Bully算法的改進,主要思路是對節(jié)點ID排序,取ID值最大的節(jié)點作為Master,每個節(jié)點都運行這個流程。同時,為了解決Bully算法的缺陷,其通過推遲選舉,直到當(dāng)前的Master失效來解決上述問題,只要當(dāng)前主節(jié)點不掛掉,就不重新選主。但是容易產(chǎn)生腦裂(雙主),為此,再通過法定得票人數(shù)過半解決腦裂問題。

Elasticsearch對Bully附加的三個約定條件

  • 參選人數(shù)需要過半。當(dāng)達到多數(shù)時就選出臨時主節(jié)點,為什么是臨時的?每個節(jié)點運行排序取最大值的算法,結(jié)果不一定相同。舉個例子,集群有5臺主機,節(jié)點ID分別是1、2、3、4、5。當(dāng)產(chǎn)生網(wǎng)絡(luò)分區(qū)或節(jié)點啟動速度差異較大時,節(jié)點1看到的節(jié)點列表是1、2、3、4,選出4;節(jié)點2看到的節(jié)點列表是2、3、4、5,選出5。結(jié)果就不一致了,由此產(chǎn)生下面的第二條限制。
  • 得票數(shù)需要過半。某節(jié)點被選為主節(jié)點,必須判斷加入它的節(jié)點數(shù)達到半數(shù)以上,才確認(rèn)Master身份(推遲選舉)。
  • 當(dāng)探測到節(jié)點離開事件時,必須判斷當(dāng)前節(jié)點數(shù)是否過半。如果達不到半數(shù)以上,則放棄Master身份,重新加入集群。如果不這么做,則設(shè)想以下情況:假設(shè)5臺機器組成的集群產(chǎn)生網(wǎng)絡(luò)分區(qū),2臺一組,3臺一組,產(chǎn)生分區(qū)前,Master位于2臺中的一個,此時3臺一組的節(jié)點會重新并成功選取Master,產(chǎn)生雙主,俗稱腦裂。(節(jié)點失效檢測)
  • 流程如下圖

    主節(jié)點選舉流程

    節(jié)點失效檢測會監(jiān)控節(jié)點是否離線,然后處理其中的異常。失效檢測是選主流程之后不可或缺的步驟,不執(zhí)行失效檢測可能會產(chǎn)生腦裂(雙主或多主)。在此我們需要啟動兩種失效探測器:

    • 在Master節(jié)點,啟動NodesFaultDetection,簡稱NodesFD。定期探測加入集群的節(jié)點是否活躍。
    • 非Master節(jié)點啟動MasterFaultDetection,簡稱MasterFD。定期探測Master節(jié)點是否活躍。


    分片內(nèi)部原理

    索引不變性

    早期的全文檢索會為整個文檔集合建立一個很大的倒排索引并將其寫入到磁盤。 一旦新的索引就緒,舊的就會被其替換,這樣最近的變化便可以被檢索到。

    倒排索引被寫入磁盤后是不可改變的,索引的不變性具有以下好處:

    • 不需要鎖。如果你從來不更新索引,你就不需要擔(dān)心多進程同時修改數(shù)據(jù)的問題。
    • 一旦索引被讀入內(nèi)核的文件系統(tǒng)緩存,便會留在哪里。由于其不變性,只要文件系統(tǒng)緩存中還有足夠的空間,那么大部分讀請求會直接請求內(nèi)存,而不會命中磁盤。這提供了很大的性能提升。
    • 緩存(像過濾器緩存)在索引的生命周期內(nèi)始終有效。它們不需要在每次數(shù)據(jù)改變時被重建,因為數(shù)據(jù)不會變化。
    • 寫入單個大的倒排索引允許數(shù)據(jù)被壓縮,減少磁盤 I/O 和 需要被緩存到內(nèi)存的索引的使用量。

    當(dāng)然,一個不變的索引也有不好的地方。最大的缺點就是它是不可變的,我們無法對其進行修改。如果我們需要讓一個新的文檔可被搜索,就需要重建整個索引。這不僅對一個索引所能包含的數(shù)據(jù)量造成了巨大的限制,而且對索引可被更新的頻率同樣造成了影響。


    動態(tài)更新索引

    那么我們?nèi)绾文茉诒A舨蛔冃缘那疤嵯聦崿F(xiàn)倒排索引的動態(tài)更新呢?

    答案就是使用更多的索引即新增內(nèi)容并寫到一個新的倒排索引中,查詢時,每個倒排索引都被輪流查詢,查詢完再對結(jié)果進行合并。

    Elasticsearch基于Lucene引入了按段寫入的概念——每次內(nèi)存緩沖的數(shù)據(jù)被寫入文件時,會產(chǎn)生一個新的Lucene段,每個段都是一個倒排索引。同時,在提交點中描述了當(dāng)前Lucene索引都含有哪些分段。

    按段寫入的流程如下:

  • 新文檔被收集到內(nèi)存的索引中緩存
  • 當(dāng)緩存堆積到一定規(guī)模時,就會進行提交
    • 一個新的段(倒排索引)被寫入磁盤。
    • 一個新的提交點被寫入磁盤。
    • 所有在文件系統(tǒng)緩存中等待的寫入都刷新到磁盤,以確保它們被寫入物理文件。
  • 新的段被開啟,讓它包含的文檔可見以被搜索
  • 內(nèi)存緩存被清空,等待接收新的文檔
  • 一個在內(nèi)存緩存中包含新文檔的 Lucene 索引

    在一次提交后,一個新的段被添加到提交點而且緩存被清空。

    當(dāng)一個查詢被觸發(fā),所有已知的段按順序被查詢。詞項統(tǒng)計會對所有段的結(jié)果進行聚合,以保證每個詞和每個文檔的關(guān)聯(lián)都被準(zhǔn)確計算。 這種方式可以用相對較低的成本將新文檔添加到索引。


    那插入和更新又如何實現(xiàn)呢?

    段是不可改變的,所以既不能從把文檔從舊的段中移除,也不能修改舊的段來進行反映文檔的更新。 取而代之的是,每個提交點會包含一個 .del 文件,文件中會列出這些被刪除文檔的段信息。

    • 當(dāng)一個文檔被刪除時,它實際上只是在 .del 文件中被標(biāo)記刪除。一個被標(biāo)記刪除的文檔仍然可以被查詢匹配到, 但它會在最終結(jié)果被返回前從結(jié)果集中移除。
    • 當(dāng)一個文檔被更新時,舊版本文檔被標(biāo)記刪除,文檔的新版本被索引到一個新的段中。 可能兩個版本的文檔都會被一個查詢匹配到,但被刪除的那個舊版本文檔在結(jié)果集返回前就已經(jīng)被移除。


    近實時搜索

    Elasticsearch和磁盤之間是文件系統(tǒng)緩存,在執(zhí)行寫操作時,為了降低從索引到可被搜索的延遲,一般新段會被先寫入到文件系統(tǒng)緩存,再將這些數(shù)據(jù)寫入硬盤(磁盤I/O是性能瓶頸)。

    在寫操作中,一般會先在內(nèi)存中緩沖一段數(shù)據(jù),再將這些數(shù)據(jù)寫入硬盤,每次寫入硬盤的這批數(shù)據(jù)稱為一個分段。如同任何寫操作一樣,通過操作系統(tǒng)的write接口寫到磁盤的數(shù)據(jù)會先到達系統(tǒng)緩存(內(nèi)存)。write函數(shù)返回成功時,數(shù)據(jù)未必被刷到磁盤。通過手工調(diào)用flush,或者操作系統(tǒng)通過一定策略將文件系統(tǒng)緩存刷到磁盤。

    這種策略大幅提升了寫入效率。從write函數(shù)返回成功開始,無論數(shù)據(jù)有沒有被刷到磁盤,只要文件已經(jīng)在緩存中, 就可以像其它文件一樣被打開和讀取了。

    在內(nèi)存緩沖區(qū)中包含了新文檔的 Lucene 索引

    Lucene允許新段被寫入和打開——使其包含的文檔在未進行一次完整提交時便對搜索可見。 這種方式比進行一次提交代價要小得多,并且在不影響性能的前提下可以被頻繁地執(zhí)行。

    緩沖區(qū)的內(nèi)容已經(jīng)被寫入一個可被搜索的段中,但還沒有進行提交

    Elasticsearch中將寫入和打開一個新段的過程叫做refresh(刷新) 。 默認(rèn)情況下每個分片會每秒自動刷新一次。這就是為什么我們說Elasticsearch是近實時搜索——文檔的變化并不是立即對搜索可見,但會在一秒之內(nèi)變?yōu)榭梢姟?/strong>


    事務(wù)日志

    由于系統(tǒng)先緩沖一段數(shù)據(jù)才寫,且新段不會立即刷入磁盤,這兩個過程中如果出現(xiàn)某些意外情況(如主機斷電),則會存在丟失數(shù)據(jù)的風(fēng)險。

    為了解決這個問題,Elasticsearch增加了一個translog(事務(wù)日志),在每一次對Elasticsearch進行操作時均進行了日志記錄,當(dāng)Elasticsearch啟動的時候,重放translog中所有在最后一次提交后發(fā)生的變更操作。

    其執(zhí)行流程如下:

  • 一個文檔被索引之后,就會被添加到內(nèi)存緩沖區(qū),并且追加到了translog
    • 新的文檔被添加到內(nèi)存緩沖區(qū)并且被追加到了事務(wù)日志,如下圖
  • 分片會每秒自動執(zhí)行一次刷新,這些內(nèi)存緩沖區(qū)的文檔被寫入新的段中并打開以便搜索,同時清空內(nèi)存緩沖區(qū)。
    • 刷新完成后, 緩存被清空但是事務(wù)日志不會,同時新段寫入文件系統(tǒng)緩沖區(qū)
  • 這個進程繼續(xù)工作,更多的文檔被添加到內(nèi)存緩沖區(qū)和追加到translog
    • 事務(wù)日志不斷積累文檔
  • 當(dāng)translog足夠大時,就會執(zhí)行全量提交,對文件系統(tǒng)緩存執(zhí)行flush,將其內(nèi)容全部寫入硬盤中,并清空事務(wù)日志。
    • 在刷新(flush)之后,段被全量提交,并且事務(wù)日志被清空
  • 除此之外,translog還有下面這些功能

    • translog提供所有還沒有被刷到磁盤的操作的一個持久化紀(jì)錄。當(dāng)Elasticsearch啟動的時候, 它會從磁盤中使用最后一個提交點去恢復(fù)已知的段,并且會重放translog中所有在最后一次提交后發(fā)生的變更操作。
    • translog也被用來提供實時CRUD 。當(dāng)你試著通過ID查詢、更新、刪除一個文檔,在從相應(yīng)的段中檢索之前, 首先檢查translog任何最近的變更。這意味著它總是能夠?qū)崟r地獲取到文檔的最新版本。


    段合并

    由于自動刷新流程每秒會創(chuàng)建一個新的段 ,這樣會導(dǎo)致短時間內(nèi)的段數(shù)量暴增。而段數(shù)目太多會帶來較大的麻煩。 每一個段都會消耗文件句柄、內(nèi)存和cpu運行周期。更重要的是,每個搜索請求都必須輪流檢查每個段,所以段越多,搜索也就越慢

    Elasticsearch通過在后臺進行段合并來解決這個問題,其會選擇大小相似的分段進行合并。在合并過程中,標(biāo)記為刪除(更新)的數(shù)據(jù)不會寫入新分段,當(dāng)合并過程結(jié)束,舊的分段數(shù)據(jù)被刪除,標(biāo)記刪除的數(shù)據(jù)才從磁盤刪除。

    流程如下圖

    兩個提交了的段和一個未提交的段正在被合并到一個更大的段

    一旦合并結(jié)束,老的段被刪除

    合并大的段需要消耗大量的I/O和CPU資源,如果任其發(fā)展會影響搜索性能。Elasticsearch在默認(rèn)情況下會對合并流程進行資源限制,所以搜索仍然有足夠的資源很好地執(zhí)行。

    整體寫入流程如下圖

    整體寫入流程

    總結(jié)

    以上是生活随笔為你收集整理的ElasticSearch探索之路(五)集群与分片:选举、动态更新、近实时搜索、事务日志、段合并的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。