當前位置:成語大全網 - 漢語詞典 - 分布式搜索引擎彈性搜索的架構原理

分布式搜索引擎彈性搜索的架構原理

分布式搜索引擎:將大量的索引數據分成多個塊,每臺機器放壹部分,然後用多臺機器搜索分散的數據,所有操作分布在多臺機器上,形成壹個完整的分布式架構。

近實時,有兩層意思:

壹個集群包含多個節點,每個節點屬於哪個集群由配置決定。

Node是集群中的壹個節點,節點也有名字,默認是隨機分配的。默認節點將加入壹個名為elasticsearch的集群。如果妳直接啟動壹堆節點,它們會自動形成壹個elasticsearch集群。當然,壹個節點也可以組成壹個elasticsearch集群。

文檔是專家系統中最小的數據單位。壹個單據可以是1客戶數據,1商品分類數據,1訂單數據,通常用json數據結構表示。索引下的每種類型可以存儲多個文檔。

1文檔中有多個字段,每個字段都是1數據字段。

當es集群多個節點時,1個節點會被自動選舉為主節點。這個主節點實際上做壹些管理工作,比如維護索引元數據,切換主碎片和副本碎片的身份。如果主節點關閉,1個節點將被重新選為主節點。如果非主節點發生故障,主節點會將該故障節點上的主碎片的身份轉移到其他機器上的副本碎片。然後,如果修復宕機機器並重啟,主節點將控制缺失副本碎片的分配,同步後續修改的數據等等,讓集群恢復正常。更簡單的說就是1,也就是說如果壹個非主節點宕機,這個節點上的主分片就沒了。好的,master會將主碎片對應的副本碎片(在其他機器上)切換到主碎片。如果當機修復,修復後的節點不再是主分片,而是副本分片。

壹個索引可以分成多個分片,每個分片存儲壹部分數據。分割多個碎片是有益的。首先,它支持橫向擴展。比如妳的數據量是3T,有三個分片,每個分片會有1T的數據。如果現在數據量增加到4T,怎麽擴展就很簡單了。用四個碎片重建1索引,並導入數據。二是提高性能。數據分布在多個shard上,也就是多臺服務器上,所有的操作都會並行執行,分布在多臺機器上,從而提高吞吐量和性能。然後這個分片的數據其實有多個備份,也就是說每個分片有1個主分片,負責寫數據,但是也有多個副本分片。主碎片寫入數據後,會將數據同步到其他幾個副本碎片。

通過這種復制方案,每個碎片的數據都有多個備份。如果壹臺機器壞了,也沒關系。在其他機器上有其他數據副本,因此它是高度可用的。

總結:分布是兩點,1。通過分片切片實現橫向擴展;2.高可用性是通過副本機制實現的。

基本概念

數據寫入過程:客戶端通過hash選擇壹個節點發送請求,這個節點稱為協調節點。協調節點路由docmount並將請求轉發到相應的主碎片,主碎片處理請求並將數據同步到所有副本碎片。此時,協調節點在發現主分片和所有副本分片都已被處理後反饋給客戶端。

客戶端向任意壹個節點發送get請求,那麽這個節點就叫做協調節點。協調節點路由文檔並將請求轉發給相應的節點。此時,將使用隨機輪詢算法隨機選擇主碎片和副本碎片中的壹個,使得讀取請求的負載均衡,接收請求的節點將文檔返回給協調節點,協調節點將文檔返回給客戶端。

es最厲害的就是做全文檢索,也就是比如妳有三條數據。

1.java真好玩。

2.java很難學。

3.j2ee特別棒

妳根據java關鍵字進行搜索,搜索出包含java的文檔。

在更新/刪除數據的過程中,首先是寫和合並操作,然後是刷新過程:

1,寫過程與上面壹致;

2.刷新過程略有不同。

所謂倒排索引,就是先把妳的數據內容分成單詞,把每個句子壹個壹個的分成關鍵詞,然後記錄每個關鍵詞出現在哪個id標記的數據中。

然後妳就可以根據這個id從其他地方找到相應的數據。這是倒排索引的數據格式和查找方式。這種通過倒排索引查找數據的方法也稱為全文檢索。

倒排索引就是我們常見的倒排索引,主要包括兩部分:

有序數據字典(包括單詞$ Term及其出現頻率)。

對應於單詞$ Term(即這個單詞所在的文件)的記錄

我們在搜索的時候,首先對搜索的內容進行分解,然後在字典中找到對應的$ Term,從而找到與搜索相關的文件內容。

本質上,存儲字段是壹個簡單的鍵值對。默認情況下,Stored Fields為false,ElasticSearch存儲整個文件的JSON源代碼。

什麽情況下需要顯式指定store屬性?大多數情況下是不必要的。從_source獲取值快速高效。如果您的文檔很長,並且存儲_source或從_source獲取字段的開銷很大,您可以顯式地將某些字段的store屬性設置為yes。缺點如上所述:假設妳存儲了10個字段,想要獲取這10個字段的值,需要多個io,從存儲的字段中獲取,只需要壹個,而且_source是壓縮的。

這時可以指定某些字段store為true,也就是說這個字段的數據會分開存儲(實際上有兩個副本,源和存儲字段都有壹個副本)。此時,如果請求返回field1 (store: Yes),es會識別出field1已經被存儲,所以不會從_source加載,而是從field1的存儲塊加載。

Doc_values本質上是壹種序列化的列存儲,這種結構非常適合聚合、排序和腳本訪問字段等操作。而且這種存儲方式對於壓縮也非常方便,尤其是對於數字類型。這樣可以減少磁盤空間,提高訪問速度。ElasticSearch可以將索引中的所有文檔值讀入內存進行操作。

Doc_values存在於磁盤上。

在es中,文本類型字段默認只會建立倒排索引,其他幾種類型在建立倒排索引時也會建立正排索引。當然,es支持定制。在這裏,這個正交索引實際上是Doc值。

即上述的動態指數。

寫入es的數據實際上是寫入磁盤文件。查詢時,操作系統會自動將磁盤文件中的數據緩存到文件系統緩存中。

es的搜索引擎非常依賴底層文件系統緩存。如果妳給文件系統緩存更多的內存,盡量讓內存放得下所有的idx段文件索引數據文件,那麽妳搜索的時候基本都會占用內存,性能會很高。性能差距能有多大?在我們之前的很多測試和壓力測試中,如果拿盤的話,肯定是秒,搜索性能絕對是秒,1秒,5秒,10秒。但如果拿文件系統緩存和純內存來說,性能壹般比磁盤高壹個數量級,基本都是毫秒級,從幾毫秒到幾百毫秒不等。

那麽如何才能節省文件系統緩存的空間呢?

在向ES寫入數據時,要考慮數據的最小化。當壹行數據超過30個字段時,沒有必要將所有數據都寫入ES,只需檢索需要的鍵列即可。可以緩存的數據越多。因此,最好將每臺機器寫入的數據控制在小於或等於或略大於文件系統緩存空間。如果想搜索海量數據,可以考慮使用ES+Hbase架構。使用Hbase存儲海量數據,然後ES搜索到單據id後,根據單據id去Hbase查詢指定的行數據。

當每臺機器寫入的數據比緩存os大太多,以至於太多數據無法放入緩存時,那麽就可以把壹些熱數據刷入緩存。

對於那些妳認為比較熱,經常被訪問的數據,最好做壹個專門的緩存預熱系統,即每隔壹段時間提前訪問熱數據,讓數據進入文件系統緩存。所以下次有人來訪,表現肯定會好很多。

將熱數據和冷數據分開,寫入不同的索引,然後壹定要將熱索引數據刷到緩存中。

在ES中,最好不要使用復雜的關聯表操作。當需要這樣的場景時,可以在創建索引時關聯數據。比如在mysql中,需要根據相關ID查詢兩個表的相關數據:從壹個join b中選擇a.name,b.age其中a.id = b.id,寫es時直接把相關數據放在壹個文檔中就可以了。

es的分頁比較坑。為什麽?舉個例子,如果妳每頁有10條數據,現在妳想查詢第100頁,妳會發現實際上每個分片上存儲的前1000條數據到1個協調節點。如果妳有五個碎片,那麽就會有5000條數據,然後協調節點會對這5000條數據做壹些工作。

分布式的,妳要在100頁上檢查10條數據。不可能說從五個分片開始,每個分片會檢查2條數據,最後在協調節點合並成10條數據吧?妳要從每個分片中查找1000條數據,然後根據妳的需要進行排序、篩選等等,最後再次分頁得到100頁的數據。翻頁的時候越翻越深,每個分片返回的數據越多,協調節點處理的時間越長,很有欺騙性。所以妳用es做分頁的時候會發現越往後翻越慢。

我們以前遇到過這個問題。使用es分頁時,前幾頁需要幾十毫秒,轉到10或幾十頁時,基本上需要5~10秒才能找出壹頁數據。

壹個解決方案?

1)無深度分頁:告訴產品經理妳的系統不允許翻頁那麽深,默認越深性能越差;

2)在APP或微信官方賬號中,通過下拉實現分頁,即下拉時獲取最新頁面,可通過scroll api實現;

Scroll會在1次為妳生成1次所有數據的快照,然後妳每滑回壹頁,就會通過光標scroll_id移動得到下壹頁。性能會比上面說的分頁性能高很多,基本以毫秒為單位。但只有1的缺點是適用於類似微博下拉翻頁的場景,不能隨意跳轉到任何頁面。換句話說,妳不能前進到10頁,然後到120頁,再回到58頁。不能隨意在頁面上跳來跳去。所以現在很多APP產品都不允許妳隨意翻頁,也有壹些網站妳只能下拉壹頁壹頁的翻。

初始化時,您必須指定scroll參數來告訴es保存該搜索的上下文多長時間。妳需要確保用戶不會連續幾個小時不停地翻頁,否則他們可能會因為超時而失敗。

除了使用scroll api,還可以使用search_after。search_after的思路是利用上壹頁的結果來幫助檢索下壹頁的數據。很明顯,這種方法不允許妳隨意翻頁,壹次只能向後翻壹頁。初始化時,需要使用只有1值的字段作為排序字段。