Elastic Search常見面試題
1. 為什么要使用ElasticSearch?
系統中的數據,隨着業務的發展,時間的推移,將會非常多。而業務中常采用模糊查詢進行數據的搜索,而模糊查詢會導致查詢引擎放棄索引,導致系統查詢數據時都是全表掃描。在百萬級別的數據庫中,查詢效率是非常低下的。如果使用ES做一個全文索引,將經常查詢的系統功能的某些字段,比如電商系統的商品表中商品名,描述、價格還有 id 這些字段我們放入 ES 索引庫里,可以提高查詢速度。
2. Elastic Search的Master選舉流程?
- Elastic Search的選主是ZenDIscovery模塊負責的,主要包含Ping(節點之間通過這個RPC來發現彼此)和Unicast(單播模塊包含一個主機列表以控制哪些節點需要Ping通)這兩部分。
- 對所有可以成為master的節點(node.master:true)根據nodeId字段排序,每次選舉每個節點都把自己所知道節點排一次序,然后選出第一個(第0位)節點,暫且認為它是master節點。
- 如果對某個節點的投票數達到一定值(可以成為master節點數n/2+1)並且該節點也自己選舉自己,那這個節點就是master。否則重新選舉一直到滿足上述條件。
- master節點的職責主要包括集群、節點和索引的管理,不負責文檔級別的管理;data節點可以關閉http功能。
3. Elastic Search集群腦裂問題?
腦裂問題可能產生的原因:
- 網絡問題:集群間的網絡延遲可能導致一些節點訪問不到master,認為master掛掉從而選舉出新的master,並對master上的分片和副本標紅,分配新的主分片。
- 節點負載:主節點的角色既為master又為data,訪問量較大時可能會導致ES停止響應造成大面積延 遲,此時其他節點得不到主節點的響應認為主節點掛掉了,會重新選取主節點。
- 內存回收:data節點上的ES進程占用的內存較大,引發JVM的大規模內存回收,造成ES進程失去響應。
腦裂問題解決方案:
-
減少誤判:discovery.zen.ping_timeout 節點狀態的響應時間,默認為 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
4. Elastic Search更新和刪除文檔的流程?
- 刪除和更新都是寫操作,但是Elastic Search中的文檔是不可變的,因此不能被刪除或者改動以展示其變更;
- 磁盤上的每個段都有一個相應的.del文件。當刪除請求發送后,文檔並沒有被真正的被刪除,而是在.del文件中被標記為刪除。該文檔依舊能夠匹配查詢,但是會在結果中被過濾掉。當段合並時,在.del文件中被標記為刪除的文檔將不會被寫入新段。
- 在新的文檔被創建時,Elastic Search會為該文檔指定一個版本號。當執行更新時,舊版本的文檔在.del文件中被標記為刪除,新版本的文檔被索引到一個新段。舊版本的文檔依然能夠匹配查詢,但是會在結果中被過濾掉。
5. 在GC方面,Elastic Search需要注意哪些點?
- 倒排詞典的索引需要常駐內存,無法GC,需要監控data node上segment memory增長趨勢。
- 各類緩存(比如 field cache,filter cache,indexing cache,bulk queue等),要設置合理的大小,並且要根據最壞的情況來看heap是否夠用,也就是各類緩存全部占滿的時候,還有head空間可以分配給其他任務。
- 避免返回大量結果集的搜索和與聚合,確實需要大量拉取數據的場景,可以采用scan & scroll api來實現。
- cluster stats駐留內存並無法水平擴展,超大規模集群可以考慮分拆成多個集群通過tribenode連接。
- 想知道 heap 夠不夠,必須結合實際應用場景,並對集群的 heap 使用情況做持續的監控。
6. 在並發情況下,Elastic Search如何保證讀寫一致?
- 可以通過版本號使用樂觀並發控制,以確保新版本不會被舊版本覆蓋,由應用層來處理具體的沖突;
- 對於寫操作,一致性級別支持quorum/one/all,默認為quorum,即只有當大多數分片可用時才允許寫操作。但即使大多數可用,也可能存在因為網絡等原因導致寫入副本失敗,這樣該副本被認為故障,分片將會在一個不同的節點上重建。
- 對於讀操作,可以設置replication為sync(默認),這使得操作在主分片和副本分片都完成后才會返回;如果設置 replication 為 async 時,也可以通過設置搜索請求參數_preference 為 primary 來查詢主分片, 確保文檔是最新版本。
7. Elastic Search中的集群、節點、索引、文檔和類型是什么?
-
集群是一個或多個節點(服務器)的集合,它們共同保存您的整個數據,並提供跨所有節點的聯合索引和搜索功能。群集由唯一名稱標識,默認情況下為“elasticsearch”。
-
節點是屬於集群一部分的單個服務器。它存儲數據並參與群集索引和搜索功能。
-
索引就像關系數據庫中的“數據庫”。它有一個定義多種類型的映射。索引是邏輯名稱空間,映射到一個或多個主分片,並且可以有零個或多個副本分片。 MySQL=>數據庫 Elasticsearch=>索引
-
文檔類似於關系數據庫中的一行。不同之處在於索引中的每個文檔可以具有不同的結構(字段),但是對於通用字段應該具有相同的數據類型。 MySQL => Databases => Tables => Columns / Rows
Elasticsearch => Indices => Types =>具有屬性的文檔。
-
類型是索引的邏輯類別/分區,其語義完全取決於用戶。
8. Elastic Search 中的倒排索引是什么?
倒排索引是搜索引擎的核心。搜索引擎的主要目標是在查找發生搜索條件的文檔時提供快速搜索。ES中的倒排索引其實就是 lucene 的倒排索引,區別於傳統的正向索引,倒排索引會再存儲數據時將關鍵詞和數據進行關聯,保存到倒排表中,然后查詢時,將查詢內容進行分詞后在倒排表中進行查詢,最后匹配數據即可。