您好,登錄后才能下訂單哦!
本篇文章為大家展示了ElasticSearch中怎么實現(xiàn)集群分布式,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
索引(index)
“索引” 這個詞在 ElasticSearch 語境中包含多重意思: 索引(名詞): 類比傳統(tǒng)的關系型數(shù)據(jù)庫領域來說,索引相當于SQL中的一個數(shù)據(jù)庫。索引由其名稱(必須為全小寫字符)進行標識,并通過引用此名稱完成文檔的創(chuàng)建、搜索、更新及刪除操作。
索引(動詞): 索引一個文檔就是存儲一個文檔到一個索引(名詞)中以便它可以被檢索和查詢到。這非常類似于SQL語句中的 INSERT關鍵詞,除了文檔已存在時新文檔會替換舊文檔情況之外。
倒排索引: 關系型數(shù)據(jù)庫通過增加一個“索引”比如一個B樹(B-tree)索引到指定的列上,以便提升數(shù)據(jù)檢索速度。ElasticSearch 和 Lucene 使用了一個叫做 “倒排索引” 的結構來達到相同的目的。
舉個例子,文檔和詞條之間的關系如下圖:
圖1:文檔和詞條的關系
字段值被分析之后,存儲在倒排索引中,倒排索引存儲的是分詞(Term)和文檔(Doc)之間的關系,簡化版的倒排索引如下圖:
圖2:倒排索引
類型(Type)
類型是索引內部的邏輯分區(qū)(category/partition),然而其意義完全取決于用戶需求。因此,一個索引內部可定義一個或多個類型(type)。一般來說,類型就是為那些擁有相同的域的文檔做的預定義。類比傳統(tǒng)的關系型數(shù)據(jù)庫領域來說,類型相當于“表”。
文檔(Document)
文檔類似于一行完整的數(shù)據(jù),在ElasticSearch里面文檔是基于JSON格式進行表示的,文檔是索引和搜索的原子單位,它是包含了一個或多個域(Field)的容器。每個文檔可以存儲不同的域集,但同一類型(Type)下的文檔至少應該有某種程度上的相似之處。
節(jié)點(Node)
一個運行中的 ElasticSearch實例稱為一個節(jié)點,而集群是由一個或者多個擁有相同cluster.name配置的節(jié)點組成, 它們共同承擔數(shù)據(jù)和負載的壓力。
ES集群中的節(jié)點有三種不同的類型:
主節(jié)點:負責管理集群范圍內的所有變更,例如增加、刪除索引,或者增加、刪除節(jié)點等。 主節(jié)點并不需要涉及到文檔級別的變更和搜索等操作。可以通過屬性node.master進行設置。
數(shù)據(jù)節(jié)點:存儲數(shù)據(jù)和其對應的倒排索引。默認每一個節(jié)點都是數(shù)據(jù)節(jié)點(包括主節(jié)點),可以通過node.data屬性進行設置。
協(xié)調節(jié)點:如果node.master和node.data屬性均為false,則此節(jié)點稱為協(xié)調節(jié)點,用來響應客戶請求,均衡每個節(jié)點的負載。
分片(Shard)
一個索引中的數(shù)據(jù)保存在多個分片中,相當于水平分表。一個分片便是一個Lucene 的實例,它本身就是一個完整的搜索引擎。我們的文檔被存儲和索引到分片內,但是應用程序是直接與索引而不是與分片進行交互。
一個分片可以是主分片或者副本分片。 索引內任意一個文檔都歸屬于一個主分片,所以主分片的數(shù)目決定著索引能夠保存的最大數(shù)據(jù)量。一個副本分片只是一個主分片的拷貝。 副本分片作為硬件故障時保護數(shù)據(jù)不丟失的冗余備份,并為搜索和返回文檔等讀操作提供服務。
集群分布式底層實現(xiàn)
以上我們對ElasticSearch的基本概念有了一個初步認識,接下來我們深入這些內部細節(jié)來幫助你更好的理解數(shù)據(jù)是如何在分布式系統(tǒng)中存儲和查詢的。
ES實際上就是利用分片來實現(xiàn)分布式。分片是數(shù)據(jù)的容器,文檔保存在分片內,分片又被分配到集群內的各個節(jié)點里。 當你的集群規(guī)模擴大或者縮小時, ES會自動的在各節(jié)點中遷移分片,使得數(shù)據(jù)仍然均勻分布在集群里。
在索引建立的時候就已經(jīng)確定了主分片數(shù),但是副本分片數(shù)可以隨時修改。默認情況下,一個索引會有5個主分片,而其副本可以有任意數(shù)量。
主分片和副本分片的狀態(tài)決定了集群的健康狀態(tài)。每一個節(jié)點上都只會保存主分片或者其對應的一個副本分片,相同的副本分片不會存在于同一個節(jié)點中。如果集群中只有一個節(jié)點,則副本分片將不會被分配,此時集群健康狀態(tài)為yellow,存在丟失數(shù)據(jù)的風險。
分布式文檔CRUD
索引新文檔(Create)
當用戶向一個節(jié)點提交了一個索引新文檔的請求,節(jié)點會計算新文檔應該加入到哪個分片(shard)中。每個節(jié)點都存儲有每個分片存儲在哪個節(jié)點的信息,因此協(xié)調節(jié)點會將請求發(fā)送給對應的節(jié)點。注意這個請求會發(fā)送給主分片,等主分片完成索引,會并行將請求發(fā)送到其所有副本分片,保證每個分片都持有最新數(shù)據(jù)。
每次寫入新文檔時,都會先寫入內存中,并將這一操作寫入一個translog文件(transaction log)中,此時如果執(zhí)行搜索操作,這個新文檔還不能被索引到。
圖3:新文檔被寫入內存,操作被寫入translog
ES會每隔1秒時間(這個時間可以修改)進行一次刷新操作(refresh),此時在這1秒時間內寫入內存的新文檔都會被寫入一個文件系統(tǒng)緩存(filesystem cache)中,并構成一個分段(segment)。此時這個segment里的文檔可以被搜索到,但是尚未寫入硬盤,即如果此時發(fā)生斷電,則這些文檔可能會丟失。
圖4:在執(zhí)行刷新后清空內存,新文檔寫入文件系統(tǒng)緩存
不斷有新的文檔寫入,則這一過程將不斷重復執(zhí)行。每隔一秒將生成一個新的segment,而translog文件將越來越大。
圖5:translog不斷加入新文檔記錄
每隔30分鐘或者translog文件變得很大,則執(zhí)行一次fsync操作。此時所有在文件系統(tǒng)緩存中的segment將被寫入磁盤,而translog將被刪除(此后會生成新的translog)。
圖6:執(zhí)行fsync后segment寫入磁盤,清空內存和translog
由上面的流程可以看出,在兩次fsync操作之間,存儲在內存和文件系統(tǒng)緩存中的文檔是不安全的,一旦出現(xiàn)斷電這些文檔就會丟失。所以ES引入了translog來記錄兩次fsync之間所有的操作,這樣機器從故障中恢復或者重新啟動,ES便可以根據(jù)translog進行還原。
當然,translog本身也是文件,存在于內存當中,如果發(fā)生斷電一樣會丟失。因此,ES會在每隔5秒時間或是一次寫入請求完成后將translog寫入磁盤??梢哉J為一個對文檔的操作一旦寫入磁盤便是安全的可以復原的,因此只有在當前操作記錄被寫入磁盤,ES才會將操作成功的結果返回發(fā)送此操作請求的客戶端。
此外,由于每一秒就會生成一個新的segment,很快將會有大量的segment。對于一個分片進行查詢請求,將會輪流查詢分片中的所有segment,這將降低搜索的效率。因此ES會自動啟動合并segment的工作,將一部分相似大小的segment合并成一個新的大segment。合并的過程實際上是創(chuàng)建了一個新的segment,當新segment被寫入磁盤,所有被合并的舊segment被清除。
圖7:合并segment
圖8:合并完成后刪除舊segment,新segment可供搜索
更新(Update)和刪除(Delete)文檔
ES的索引是不能修改的,因此更新和刪除操作并不是直接在原索引上直接執(zhí)行。
每一個磁盤上的segment都會維護一個del文件,用來記錄被刪除的文件。每當用戶提出一個刪除請求,文檔并沒有被真正刪除,索引也沒有發(fā)生改變,而是在del文件中標記該文檔已被刪除。因此,被刪除的文檔依然可以被檢索到,只是在返回檢索結果時被過濾掉了。每次在啟動segment合并工作時,那些被標記為刪除的文檔才會被真正刪除。
更新文檔會首先查找原文檔,得到該文檔的版本號。然后將修改后的文檔寫入內存,此過程與寫入一個新文檔相同。同時,舊版本文檔被標記為刪除,同理,該文檔可以被搜索到,只是最終被過濾掉。
讀操作(Read):查詢過程
查詢的過程大體上分為查詢(query)和取回(fetch)兩個階段。這個節(jié)點的任務是廣播查詢請求到所有相關分片,并將它們的響應整合成全局排序后的結果集合,這個結果集合會返回給客戶端。
查詢階段
當一個節(jié)點接收到一個搜索請求,則這個節(jié)點就變成了協(xié)調節(jié)點。
查詢過程分布式搜索
圖9:查詢過程分布式搜索
第一步是廣播請求到索引中每一個節(jié)點的分片拷貝。 查詢請求可以被某個主分片或某個副本分片處理,協(xié)調節(jié)點將在之后的請求中輪詢所有的分片拷貝來分攤負載。
每個分片將會在本地構建一個優(yōu)先級隊列。如果客戶端要求返回結果排序中從第from名開始的數(shù)量為size的結果集,則每個節(jié)點都需要生成一個from+size大小的結果集,因此優(yōu)先級隊列的大小也是from+size。分片僅會返回一個輕量級的結果給協(xié)調節(jié)點,包含結果集中的每一個文檔的ID和進行排序所需要的信息。
協(xié)調節(jié)點會將所有分片的結果匯總,并進行全局排序,得到最終的查詢排序結果。此時查詢階段結束。
取回階段
查詢過程得到的是一個排序結果,標記出哪些文檔是符合搜索要求的,此時仍然需要獲取這些文檔返回客戶端。
協(xié)調節(jié)點會確定實際需要返回的文檔,并向含有該文檔的分片發(fā)送get請求;分片獲取文檔返回給協(xié)調節(jié)點;協(xié)調節(jié)點將結果返回給客戶端
上述內容就是ElasticSearch中怎么實現(xiàn)集群分布式,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。