elasticsearch內部原理自我總結

2021-08-07 12:36:03 字數 3390 閱讀 2907

elasticsearch:5.5

對於elasticsearch我自己也是新手,只是想做點筆記,記錄下自己的理解。

我一直想明白當乙個文件被索引進elasticsearch時,其內部幹什麼了?

本人結合網上的教程,記錄下

乙個新文件要使其可見,需要使用倒排索引,其長相如下:

詞項文件1

文件2文件3…中國

xx…小公尺

***…

華為xx…

南昌xx…

有了倒排索引之後,新進的文件就可以被搜尋到了。

注意:倒排索引被寫入磁碟後是 不可改變 的:它永遠不會修改。 不變性有重要的價值

①不需要鎖。如果你從來不更新索引,你就不需要擔心多程序同時修改資料的問題。

② 一旦索引被讀入核心的檔案系統快取,便會留在**,由於其不變性。只要檔案系統快取中還有足夠的空間,那麼大部分讀請求會直接請求記憶體,而不會命中磁碟。這提供了很大的效能提公升。

③其它快取(像filter快取),在索引的生命週期內始終有效。它們不需要在每次資料改變時被重建,因為資料不會變化。

④寫入單個大的倒排索引允許資料被壓縮,減少磁碟 i/o 和 需要被快取到記憶體的索引的使用量。

當然,乙個不變的索引也有不好的地方。主要事實是它是不可變的! 你不能修改它。如果你需要讓乙個新的文件 可被搜尋,你需要重建整個索引。這要麼對乙個索引所能包含的資料量造成了很大的限制,要麼對索引可被更新的頻率造成了很大的限制。

由於倒排索引具有不變性(一旦被寫入磁碟就不能再改變),那麼我們如何來實現更新倒排索引呢?官方的做法就是用更多的倒排索引。通過增加新的倒排索引來反應新近的修改,而不是重寫整個倒排索引,畢竟重寫整個倒排索引,要消耗巨大資源;每乙個倒排索引都會被輪流查詢到–從最早的開始–查詢完後再對結果進行合併。

如果乙個新文件立馬就寫入磁碟也會影響效能,所以新的文件首先被新增到記憶體索引快取中,然後寫入基於磁碟的段中,接著包含這個新段的提交點也會被寫入磁碟,接著磁碟同步,把檔案系統快取中的文件重新整理到磁碟,接著新段被開啟,使其可以被搜尋到,接著記憶體索引快取被清空,等待接受新的文件。

注意

段其實就是倒排索引,其不能被改變。當文件發生改變時,每個提交點會包含乙個.del檔案,檔案中會列出這些被刪除文件的段資訊。所以文件被刪除時,並不會立馬被刪除,只是被標記了,其依然可以被搜尋到,只不過在結果集返回前就已經移除了。

這裡有乙個新的問題就是磁碟同步是一件很消耗資源的事情,如果每次插入乙個文件都去執行的話,就會造成很大的效能問題。這意味著我們再插入新文件時,不能立馬就進行同步。

我們要知道在elasticsearch和磁碟之間是檔案系統快取。

新文件 寫入記憶體索引快取中,接著會寫入到新段上,重點來了,這個新段不會直接寫入磁碟而是先寫入到檔案系統快取中,稍後才會寫入到磁碟。只要檔案已經在快取中,就可以像其他檔案一樣被開啟和讀取了。

elasticsearch中,寫入和開啟乙個新段(倒排索引)的輕量的過程叫做refresh。也就是把記憶體索引快取中的資料寫到新段的乙個過程。由於elasticsearch預設每個分片是每秒自動重新整理一次。這就造成其索引是近實時搜尋而不是實時搜尋。最長需要等待1秒。

目前處於效能考慮,我們文件還放在檔案系統快取中,如果不進行同步到磁碟的話,假設斷電了,資料就丟失了。而由於上面也說明,同步不是實時的,是每個一段時間同步一次,預設是30分鐘一次。假設elasticsearch9點同步過了,下次需要在9點半同步,而此時剛好斷電了,這時記憶體裡的資料就全部丟失了。但是我們又不想丟失掉。所以elasticsearch引入了translog或者叫事務日誌。

那麼其最終的流程就變成了:

translog提供所有還沒有被刷到磁碟的操作的乙個持久化紀錄。當 elasticsearch 啟動的時候, 它會從磁碟中使用最後乙個提交點去恢復已知的段,並且會重放translog中所有在最後一次提交後發生的變更操作。

translog也被用來提供實時crud。當你試著通過id查詢、更新、刪除乙個文件,它會在嘗試從相應的段中檢索之前, 首先檢查 translog 任何最近的變更。這意味著它總是能夠實時地獲取到文件的最新版本。

translog進行截斷並進行提交的行為在elasticsearch中稱作flush。分片每30分鐘被自動重新整理(flush),或者在translog太大的時候也會重新整理。請檢視translog文件 來設定,它可以用來 控制這些閾值。

這時其實還有個小問題,要是translog在斷電之前還沒有寫入磁碟,這時,資料照樣還是會丟失。預設情況下translog是每5秒fsync到磁碟或者在每次寫請求完成之後。對於這種情況,官方說明:但是對於一些大容量的偶爾丟失幾秒資料問題也並不嚴重的集群,使用非同步的 fsync 還是比較有益的。

由於自動重新整理refresh每秒建立乙個段,這樣就會造成短時間內,段數量暴增。而段數目太多會帶來較大的麻煩。 每乙個段都會消耗檔案控制代碼、記憶體和cpu執行週期。更重要的是,每個搜尋請求都必須輪流檢查每個段;所以段越多,搜尋也就越慢。

elasticsearch通過在後台進行段合併來解決這個問題。小的段被合併到大的段,然後這些大的段再被合併到更大的段。

段合併的時候會將那些舊的已刪除文件 從檔案系統中清除。 被刪除的文件(或被更新文件的舊版本)不會被拷貝到新的大段中。

啟動段合併不需要你做任何事。進行索引和搜尋時會自動進行。

1、 當索引的時候,重新整理(refresh)操作會建立新的段並將段開啟以供搜尋使用。

2、 合併程序選擇一小部分大小相似的段,並且在後台將它們合併到更大的段中。這並不會中斷索引和搜尋。

合併完成時的活動:

合併大的段需要消耗大量的i/o和cpu資源,如果任其發展會影響搜尋效能。elasticsearch在預設情況下會對合併流程進行資源限制,所以搜尋仍然 有足夠的資源很好地執行。

ElasticSearch集群內部原理

分布式系統的集群方式可以分為主從和無主模式。主從模式通過將mater作為權威節點,將操作分工,維護集群元資訊簡化系統設計,但是存在單點故障的問題。主節點管理集群層面相關的相關操作。一般不作為資料節點,盡量做少量的工作。為避免出現腦裂問題 網路分割槽時出現多主 的情況,配置discovery.zen....

Elasticsearch 內部資料結構深度解讀

正如 elastic 官方文件所說 elasticsearch 特點之一是 分布式文件儲存。elasticsearch不會將資訊儲存為類似列資料庫的行 row 而是儲存為已序列化為json文件的複雜資料結構。當集群中有多個elasticsearch節點時,儲存的文件會分布在整個集群中,並且可以從任何...

內部類 成員內部類 區域性內部類 匿名內部類

public class 外部類 private int num 0 外部類如果要訪問內部類的成員,則需要通過內部類的物件訪問 使用方式 1.外部類使用內部類,主函式再使用外部類 2.通過new的方式 外部類.內部類 物件名 new 外部類 new 內部類 定義在方法內部的類,就是區域性內部類,只有...