文章目錄
- 1、Elasticsearch 中的倒排索引是什么?
- 2、Elasticsearch 中的集群、節點、索引、檔案、型別是什么?
- 3、什么是近實時搜索?
- 4、如何理解 Elasticsearch 的近實時的性質,并改善它的不足?
- 5、是否了解字典樹?
- 6、Elasticsearch 索引檔案的流程?
- 7、Elasticsearch 搜索的流程?
- 8、并發情況下,Elasticsearch 如果保證讀寫一致?
- 9、Elasticsearch 集群腦裂問題?有哪些解決方法?
- 10、Elasticsearch 的 master 選舉流程?
1、Elasticsearch 中的倒排索引是什么?
倒排索引是搜索引擎的核心,搜索引擎的主要目標是在查找發生搜索條件的檔案時提供快速搜索,區別于傳統的正向索引,倒排索引會再存盤資料時將關鍵詞和資料進行關聯,保存到倒排表中,然后查詢時,將查詢內容進行分詞后在倒排表中進行查詢,最后匹配數
據即可,Elasticsearch 使用一種稱為倒排索引的結構,ES中的倒排索引其實就是 lucene 的倒排索引,它適用于快速的全文搜索,正向索引(forward index),就是搜索引擎會將待搜索的檔案都對應一個檔案 ID,搜索時將這個ID 和搜索關鍵字進行對應,形成 K-V 對,然后對關鍵字進行統計計數,但是互聯網上收錄在搜索引擎中的檔案的數目是個天文數字,這樣的索引結構根本無法滿足實時回傳排名結果的要求,所以,搜索引擎會將正向索引重新構建為反向索引(inverted index,倒排索引),即把檔案ID對應到關鍵詞的映射,轉換為關鍵詞到檔案ID的映射,每個關鍵詞都對應著一系列的檔案,并保存到倒排表中,查詢時會將內容進行分詞后在倒排表中進行查詢,最后匹配資料即可,這些檔案中都出現這個關鍵詞,
2、Elasticsearch 中的集群、節點、索引、檔案、型別是什么?
集群:是一個或多個節點(服務器)的集合,它們共同保存您的整個資料,并提供跨所有節點的聯合索
引和搜索功能,集群由唯一名稱標識,默認情況下為“elasticsearch”,此名稱很重要,因為如果節點設
置為按名稱加入群集,則該節點只能是集群的一部分,
節點:屬于集群一部分的單個服務器,它存盤資料并參與群集索引和搜索功能,
索引:就像關系資料庫中的“資料庫”,它有一個定義多種型別的映射,索引是邏輯名稱空間,映射到一
個或多個主分片,并且可以有零個或多個副本分片, MySQL =>資料庫 Elasticsearch =>索引
檔案:類似于關系資料庫中的一行,不同之處在于索引中的每個檔案可以具有不同的結構(欄位),但
是對于通用欄位應該具有相同的資料型別, MySQL => Databases => Tables => Columns / Rows
Elasticsearch => Indices => Types =>具有屬性的檔案
型別:是索引的邏輯類別/磁區,其語意完全取決于用戶,
3、什么是近實時搜索?
在 Elasticsearch 和磁盤之間是檔案系統快取,在記憶體索引緩沖區中的檔案會被寫入到一個新的段中, 但是這里新段會被先寫入到檔案系統快取,這一步代價會比較低,稍后再被刷寫到磁盤—這一步代價比較高,不過只要檔案已經在快取中,就可以像其它檔案一樣被打開和讀取了,在 Elasticsearch 中,寫入和打開一個新段的輕量的程序叫做 refresh , 默認情況下每個分片會每秒自動重繪一次,即重繪檔案系統快取,這就是為什么我們說 Elasticsearch 是 近實時搜索:檔案的變化并不是立即對搜索可見,但會在一秒之內變為可見,這些行為可能會對新用戶造成困惑:他們索引了一個檔案然后嘗試搜索它,但卻沒有搜到,這個問題的解決辦法是用 refresh API 執行一次手動重繪:/users/_refresh,
4、如何理解 Elasticsearch 的近實時的性質,并改善它的不足?
并不是所有的情況都需要每秒重繪,可能你正在使用 Elasticsearch 索引大量的日志檔案,你可能想優化索引速度而不是近實時搜索, 可以通過設定 refresh_interval , 降低每個索引的重繪頻率,refresh_interval 可以在既存索引上進行動態更新, 在生產環境中,當你正在建立一個大的新索引時,可以先關閉自動重繪,待開始使用該索引時,再把它們調回來,
# 關閉自動重繪
PUT /users/_settings
{ "refresh_interval": -1 }
# 每一秒重繪
PUT /users/_settings
{ "refresh_interval": "1s" }
5、是否了解字典樹?
常用字典資料結構
-
排序串列Array/List:使用二分法查找,不平衡
-
HashMap/TreeMap:性能高,記憶體消耗大,幾乎是原始資料的三倍
-
Skip List 跳躍表:可快速查找詞語,在lucene、redis、Hbase等均有實作,相對于TreeMap等結構,特別
適合高并發場景(Skip List介紹)
-
Trie:適合英文詞典,如果系統中存在大量字串且這些字串基本沒有公共前級,則相應的trie樹將非常消耗記憶體(資料結構之trie樹)
-
Double Array Trie:適合做中文詞典,記憶體占用小,很多分詞工具均采用此種演算法(深入雙陣列Trie)
-
Ternary Search Tree 三叉樹:每一個node有3個節點,兼具省空間和查詢快的優點(Ternary Search Tree)
-
Finite State Transducers(FST) :一種有限狀態轉移機,Lucene4有開源實作,并大量使用
字典樹又稱單詞查找樹,Trie 樹,是一種樹形結構,是一種哈希樹的變種,典型應用是用于統計,排
序和保存大量的字串(但不僅限于字串),所以經常被搜索引擎系統用于文本詞頻統計,它的優點是:
利用字串的公共前綴來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比哈希樹高(空間換時間),
- Trie 的核心思想是空間換時間,利用字串的公共前綴來降低查詢時間的開銷以達到提高效率的目的,
它有 3 個基本性質:- 根節點不包含字符,除根節點外每一個節點都只包含一個字符,
- 從根節點到某一節點,路徑上經過的字符連接起來,為該節點對應的字串,
- 每個節點的所有子節點包含的字符都不相同,
對于中文的字典樹,每個節點的子節點用一個哈希表存盤,這樣就不用浪費太大的空間,而且查詢速度上
可以保留哈希的復雜度 O(1),
6、Elasticsearch 索引檔案的流程?

首先客戶端向集群發出索引檔案的請求,它會選擇任何一個節點,這個節點當接收到請求后會根據路由演算法找到應該放的那個主分片的位置,從而索引資料,之后為了保證資料的完整性,它會將它的副本資料進行同步,同步完成后客戶端就可以進行訪問了,細節方面:

用戶的索引請求發過來之后,首先協調結點默認使用檔案ID參與哈希計算(也支持通過routing),shard = hash(document_id) % (num_of_primary_shards),即分片位置索引 = 將檔案ID或路由ID進行哈希計算后的值 % 所有分片總數,隨后會在記憶體(memory)中建立一個索引(Index),這個Index會在記憶體中形成一個分段物件(Segment),為了防止資料出現問題,會同時在索引資料之后寫入到日志(Translog)當中,在此程序中,每隔1秒鐘,會向Segment會將資料重繪到系統檔案快取區(OS Cache),以方便接收用戶的查詢,因為如果讓用戶查詢直接訪問記憶體或磁盤,會使速度變慢,當過了30分鐘或者Translog中的資料超過了512M,Os Cache中的Segment會將資料刷寫(flush)到磁盤當中,刷寫后記憶體中的緩沖將被清除,此時一旦刷寫的資料比較多了的話(磁盤中有多個Segment),磁盤就會將這些分段進行合并,
7、Elasticsearch 搜索的流程?

- 搜索被執行成一個兩階段程序,我們稱之為 Query Then Fetch(查詢后取回);
- 在初始查詢階段時,查詢會廣播到索引中每一個分片拷貝(主分片或者副本分片), 每個分片在本
地執行搜索并構建一個匹配檔案的大小為 from + size 的優先佇列,PS:在搜索的時候是會查詢
Filesystem Cache 的,但是有部分資料還在 Memory Buffer,所以搜索是近實時的, - 每個分片回傳各自優先佇列中 所有檔案的 ID 和排序值 給 協調節點,它合并這些值到自己的優先隊
列中來產生一個全域排序后的結果串列, - 接下來就是取回階段,協調節點辨別出哪些檔案需要被取回,并向相關的分片提交多個 GET 請求,每
個分片加載并豐富檔案,如果有需要的話,接著回傳檔案給協調節點,一旦所有的檔案都被取回了,
協調節點回傳結果給客戶端, - Query Then Fetch 的搜索型別在檔案相關性打分的時候參考的是本分片的資料,這樣在檔案數量較少
的時候可能不夠準確,DFS Query Then Fetch 增加了一個預查詢的處理,詢問 Term 和 Document
frequency,這個評分更準確,但是性能會變差,
8、并發情況下,Elasticsearch 如果保證讀寫一致?
- 可以通過版本號使用樂觀鎖并發控制,以確保新版本不會被舊版本覆寫,由應用層來處理具體的沖突;
- 對于寫操作:一致性級別支持 quorum/one/all,默認為 quorum,
- quorum:即只有當大多數(一半以上)分片可用時才允許寫操作,但即使大多數可用,也可能存在因為網路等原因導致寫入副本失敗,這樣該副本被認為故障,分片將會在一個不同的節點上重建,
- one:即只要主分片資料保存成功,那么客戶端就可以進行查詢操作了,
- all:是最高的一致性級別,要求所有分片的資料要全部保存成功,才可以繼續進行,
- 對于讀操作:可以設定 replication 為 sync(默認為同步),這使得操作在主分片和副本分片都完成后才會回傳;設定 replication 為 async(異步)時,也可以通過設定搜索請求引數_preference 為 primary 來查詢主分片,確保檔案是最新版本,
9、Elasticsearch 集群腦裂問題?有哪些解決方法?
“腦裂”問題可能的成因:(有兩個master)
- 網路問題:集群間的網路延遲導致一些節點訪問不到 master,認為 master 掛掉了從而選舉出新的
master,并對 master 上的分片和副本標紅,分配新的主分片 - 節點負載:主節點的角色既為 master 又為 data,訪問量較大時可能會導致 ES 停止回應造成大面積延
遲,此時其他節點得不到主節點的回應認為主節點掛掉了,會重新選取主節點, - 記憶體回收:data 節點上的 ES 行程占用的記憶體較大,引發 JVM 的大規模記憶體回收,造成 ES 行程失去
回應,
腦裂問題解決方案
- 減少誤判:discovery.zen.ping_timeout 節點狀態的回應時間(超過這個時間就會重新選舉master),默認為 3s,可以適當調大,如果 master在該回應時間的范圍內沒有做出回應應答,判斷該節點已經掛掉了,調大引數(如 6s,discovery.zen.ping_timeout:6),可適當減少誤判,
- 選舉觸發:discovery.zen.minimum_master_nodes:1
該引數是用于控制選舉行為發生的最小集群主節點數量,當備選主節點的個數大于等于該引數的值,
且備選主節點中有該引數個節點認為主節點掛了,進行選舉,官方建議為(n/2)+1,n 為主節點個數
(即有資格成為主節點的節點個數)
- 角色分離:即 master 節點與 data 節點分離,限制角色
主節點配置為:node.master: true node.data: false
從節點配置為:node.master: false node.data: true
10、Elasticsearch 的 master 選舉流程?
- Elasticsearch 的選主是 ZenDiscovery 模塊負責的,主要包含 Ping(節點之間通過這個 RPC 來發現彼此)和 Unicast(單播模塊包含一個主機串列以控制哪些節點需要 ping 通)這兩部分
- 對所有可以成為 master 的節點(node.master: true)根據 nodeId 字典排序,每次選舉每個節點都把自
己所知道節點排一次序,然后選出第一個(第 0 位)節點,暫且認為它是 master 節點, - 如果對某個節點的投票數達到一定的值**(可以成為 master 節點數 n/2+1)并且該節點自己也選舉自己**,
那這個節點就是 master,否則重新選舉一直到滿足上述條件, - master 節點的職責主要包括集群、節點和索引的管理,不負責檔案級別的管理;data 節點可以關閉 http
功能,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/421437.html
標籤:其他
上一篇:大資料能做什么?
下一篇:將@microsoft/fetch-event-source用于服務器發送事件時,Vuedata()在事件中不可用
