【ElasticSearch面試】10道不得不會的ElasticSearch面試題


以下是 ElasticSearch 面試題,相信大家都會有種及眼熟又陌生的感覺、看過可能在短暫的面試后又馬上忘記了。JavaPub在這里整理這些容易忘記的重點知識及解答建議收藏,經常溫習查閱

評論區見

關於es的面試,建議使用名詞用官方語言描述會更准確。

@

1. 說說你們公司 es 的集群架構,索引數據大小,分片有多少,以及一些調優手段 。

節點數、分片數、副本數,盡量根據自己公司使用情況回答,當然適當放大也可行。

調優手段是現在很常見的面試題,下面這幾種調優手段一定要了解懂。當然,下面的每一條都可以當做調優的一部分。

設計調優

參考:
https://www.cnblogs.com/sanduzxcvbnm/p/12084012.html

a. 根據業務增量需求,采取基於日期模板創建索引,通過 rollover API 滾動索引;(rollover API我會單獨寫一個代碼案例做講解,公眾號:JavaPub)
b. 使用別名進行索引管理;(es的索引名不能改變,提供的別名機制使用非常廣泛。)
c. 每天凌晨定時對索引做force_merge操作,以釋放空間;
d. 采取冷熱分離機制,熱數據存儲到SSD,提高檢索效率;冷數據定期進行shrink操作,以縮減存儲;
e. 采取curator進行索引的生命周期管理;
f. 僅針對需要分詞的字段,合理的設置分詞器;
g. Mapping階段充分結合各個字段的屬性,是否需要檢索、是否需要存儲等。

進100+原創文章:https://gitee.com/rodert/JavaPub

寫入調優

  1. 寫入前副本數設置為0;
  2. 寫入前關閉refresh_interval設置為-1,禁用刷新機制;
  3. 寫入過程中:采取bulk批量寫入;
  4. 寫入后恢復副本數和刷新間隔;
  5. 盡量使用自動生成的id。

查詢調優

  1. 禁用wildcard;(通配符模式,類似於%like%)
  2. 禁用批量terms(成百上千的場景);
  3. 充分利用倒排索引機制,能keyword類型盡量keyword;
  4. 數據量大時候,可以先基於時間敲定索引再檢索;
  5. 設置合理的路由機制。

2. elasticsearch 的倒排索引是什么

倒排索引也就是單詞到文檔的映射,當然不只是存里文檔id這么簡單。還包括:詞頻(TF,Term Frequency)、偏移量(offset)、位置(Posting)。

3. elasticsearch 是如何實現 master 選舉的

ElasticSearch 的選主是 ZenDiscovery 模塊負責,源碼分析將首發在。 https://gitee.com/rodert/JavaPub

  1. 對所有可以成為 Master 的節點(node.master: true)根據 nodeId 排序,每次選舉每個節點都把自己所知道節點排一次序,然后選出第一個(第0位)節點,暫且認為它是 Master 節點。
  2. 如果對某個節點的投票數達到一定的值(可以成為master節點數n/2+1)並且該節點自己也選舉自己,那這個節點就是master。否則重新選舉。
    (當然也可以自己設定一個值,最小值設定為超過能成為Master節點的n/2+1,否則會出現腦裂問題。discovery.zen.minimum_master_nodes)

4. 描述一下 Elasticsearch 索引文檔的過程

在這里插入圖片描述

  1. 客戶端向 Node 1 發送新建、索引或者刪除請求。
  2. 節點使用文檔的 _id 確定文檔屬於分片 0 。請求會被轉發到 Node 3,因為分片 0 的主分片目前被分配在 Node 3 上。
  3. Node 3 在主分片上面執行請求。如果成功了,它將請求並行轉發到 Node 1 和 Node 2 的副本分片上。一旦所有的副本分片都報告成功, Node 3 將向協調節點報告成功,協調節點向客戶端報告成功。

一圖勝千文,記住這幅圖,上面是文檔在節點間分發的過程,接着說一下文檔從接收到寫入磁盤過程。
協調節點默認使用文檔 ID 參與計算(也支持通過 routing),以便為路由提供合適的分片。

shard = hash(document_id) % (num_of_primary_shards)

  1. 當分片所在的節點接收到來自協調節點的請求后,會將請求寫入到 MemoryBuffer,然后定時(默認是每隔 1 秒)寫入到 Filesystem Cache,這個從 MomeryBuffer 到 Filesystem Cache 的過程就叫做 refresh;
  2. 當然在某些情況下,存在 Momery Buffer 和 Filesystem Cache 的數據可能會丟失,ES 是通過 translog 的機制來保證數據的可靠性的。其實現機制是接收到請求后,同時也會寫入到 translog 中,當 Filesystem cache 中的數據寫入到磁盤中時,才會清除掉,這個過程叫做 flush;
  3. 在 flush 過程中,內存中的緩沖將被清除,內容被寫入一個新段,段的 fsync將創建一個新的提交點,並將內容刷新到磁盤,舊的 translog 將被刪除並開始一個新的 translog。
  4. flush 觸發的時機是定時觸發(默認 30 分鍾)或者 translog 變得太大(默認為 512M)時;
1. translog 可以理解為就是一個文件,一直追加。
2. MemoryBuffer 應用緩存。
3. Filesystem Cache 系統緩沖區。

延伸閱讀:Lucene 的 Segement:

  1. Lucene 索引是由多個段組成,段本身是一個功能齊全的倒排索引。
  2. 段是不可變的,允許 Lucene 將新的文檔增量地添加到索引中,而不用從頭重建索引。
  3. 對於每一個搜索請求而言,索引中的所有段都會被搜索,並且每個段會消耗CPU 的時鍾周、文件句柄和內存。這意味着段的數量越多,搜索性能會越低。
  4. 為了解決這個問題,Elasticsearch 會合並小段到一個較大的段,提交新的合並段到磁盤,並刪除那些舊的小段。

5. 詳細描述一下 Elasticsearch 搜索的過程?

es作為一個分布式的存儲和檢索系統,每個文檔根據 _id 字段做路由分發被轉發到對應的shard上。

搜索執行階段過程分倆個部分,我們稱之為 Query Then Fetch。

5.1 query-查詢階段

當一個search請求發出的時候,這個query會被廣播到索引里面的每一個shard(主shard或副本shard),每個shard會在本地執行查詢請求后會生成一個命中文檔的優先級隊列。

這個隊列是一個排序好的top N數據的列表,它的size等於from+size的和,也就是說如果你的from是10,size是10,那么這個隊列的size就是20,所以這也是為什么深度分頁不能用from+size這種方式,因為from越大,性能就越低。

es里面分布式search的查詢流程如下:
es里面分布式search的查詢流程
查詢階段包含以下三個步驟:

  1. 客戶端發送一個 search 請求到 Node 3 , Node 3 會創建一個大小為 from + size 的空優先隊列。
  2. Node 3 將查詢請求轉發到索引的每個主分片或副本分片中。每個分片在本地執行查詢並添加結果到大小為 from + size 的本地有序優先隊列中。
  3. 每個分片返回各自優先隊列中所有文檔的 ID 和排序值給協調節點,也就是 Node 3 ,它合並這些值到自己的優先隊列中來產生一個全局排序后的結果列表。

5.2 fetch - 讀取階段 / 取回階段

在這里插入圖片描述
分布式階段由以下步驟構成:

  1. 協調節點辨別出哪些文檔需要被取回並向相關的分片提交多個 GET 請求。
  2. 每個分片加載並 豐富 文檔,如果有需要的話,接着返回文檔給協調節點。
  3. 一旦所有的文檔都被取回了,協調節點返回結果給客戶端。

協調節點首先決定哪些文檔 確實 需要被取回。例如,如果我們的查詢指定了 { "from": 90, "size": 10 } ,最初的90個結果會被丟棄,只有從第91個開始的10個結果需要被取回。這些文檔可能來自和最初搜索請求有關的一個、多個甚至全部分片。

協調節點給持有相關文檔的每個分片創建一個 multi-get request ,並發送請求給同樣處理查詢階段的分片副本。

分片加載文檔體-- _source 字段—​如果有需要,用元數據和 search snippet highlighting 豐富結果文檔。 一旦協調節點接收到所有的結果文檔,它就組裝這些結果為單個響應返回給客戶端。

拓展閱讀:
深翻頁(Deep Pagination)
---
先查后取的過程支持用 from 和 size 參數分頁,但是這是 有限制的 。 要記住需要傳遞信息給協調節點的每個分片必須先創建一個 from + size 長度的隊列,協調節點需要根據 number_of_shards * (from + size) 排序文檔,來找到被包含在 size 里的文檔。

取決於你的文檔的大小,分片的數量和你使用的硬件,給 10,000 到 50,000 的結果文檔深分頁( 1,000 到 5,000 頁)是完全可行的。但是使用足夠大的 from 值,排序過程可能會變得非常沉重,使用大量的CPU、內存和帶寬。因為這個原因,我們強烈建議你不要使用深分頁。

實際上, “深分頁” 很少符合人的行為。當2到3頁過去以后,人會停止翻頁,並且改變搜索標准。會不知疲倦地一頁一頁的獲取網頁直到你的服務崩潰的罪魁禍首一般是機器人或者web spider。

如果你 確實 需要從你的集群取回大量的文檔,你可以通過用 scroll 查詢禁用排序使這個取回行為更有效率,我們會在 later in this chapter 進行討論。
注:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html

6. Elasticsearch 在部署時,對 Linux 的設置有哪些優化方法

  1. 關閉緩存swap;

原因:大多數操作系統會將內存使用到文件系統緩存,會將應用程序未用到的內存交換出去。會導致jvm的堆內存交換到磁盤上。交換會導致性能問題。會導致內存垃圾回收延長。會導致集群節點響應時間變慢,或者從集群中斷開。

  1. 堆內存設置為:Min(節點內存/2, 32GB);

  2. 設置最大文件句柄數;

后倆點不懂可以先說有一定了解,關注JavaPub會做詳細講解。

  1. 調整線程池和隊列大小

  2. 磁盤存儲 raid 方式——存儲有條件使用 RAID6,增加單節點性能以及避免單節點存儲故障。

https://www.elastic.co/cn/blog/how-to-design-your-elasticsearch-data-storage-architecture-for-scale#raid56

7. Elasticsearch 中的節點(比如共 20 個),其中的 10 個選了一個 master,另外 10 個選了另一個 master,怎么辦?

  1. 當集群 master 候選數量不小於 3 個時,可以通過設置最少投票通過數量(discovery.zen.minimum_master_nodes)超過所有候選節點一半以上來解決腦裂問題;

  2. 當候選數量為兩個時,只能修改為唯一的一個 master 候選,其他作為 data節點,避免腦裂問題。

8. 客戶端在和集群連接時,如何選擇特定的節點執行請求的?

client 遠程連接連接一個 elasticsearch 集群。它並不加入到集群中,只是獲得一個或者多個初始化的地址,並以輪詢的方式與這些地址進行通信。

9. 詳細描述一下 Elasticsearch 更新和刪除文檔的過程。

  1. 刪除和更新也都是寫操作,但是 Elasticsearch 中的文檔是不可變的,因此不能被刪除或者改動以展示其變更;(根本原因是底層lucene的segment段文件不可更新刪除)
  2. 磁盤上的每個段都有一個相應的 .del 文件。當刪除請求發送后,文檔並沒有真 的被刪除,而是在 .del 文件中被標記為刪除。該文檔依然能匹配查詢,但是會在 結果中被過濾掉。當段合並時,在.del 文件中被標記為刪除的文檔將不會被寫入 新段。
  3. 在新的文檔被創建時,Elasticsearch 會為該文檔指定一個版本號,當執行更新 時,舊版本的文檔在.del 文件中被標記為刪除,新版本的文檔被索引到一個新段。

舊版本的文檔依然能匹配查詢,但是會在結果中被過濾掉。

10. Elasticsearch 對於大數據量(上億量級)的聚合如何實現?

這道題目較難,相信大家看到很多類似這種回答

Elasticsearch 提供的首個近似聚合是cardinality 度量。它提供一個字段的基數,即該字段的distinct或者unique值的數目。它是基於HLL算法的。HLL 會先對我們的輸入作哈希運算,然后根據哈希運算的結果中的 bits 做概率估算從而得到基數。其特點是:可配置的精度,用來控制內存的使用(更精確 = 更多內存);小的數據集精度是非常高的;我們可以通過配置參數,來設置去重需要的固定內存使用量。無論數千還是數十億的唯一值,內存使用量只與你配置的精確度相關。

科普&拓展

HyperLogLog:
下面簡稱為HLL,它是 LogLog 算法的升級版,作用是能夠提供不精確的去重計數。存在以下的特點:
1. 能夠使用極少的內存來統計巨量的數據,在 Redis 中實現的 HyperLogLog,只需要12K內存就能統計2^64個數據。
2. 計數存在一定的誤差,誤差率整體較低。標准誤差為 0.81% 。
3. 誤差可以被設置輔助計算因子進行降低。
---
應用場景:
1. 基數不大,數據量不大就用不上,會有點大材小用浪費空間
2. 有局限性,就是只能統計基數數量,而沒辦法去知道具體的內容是什么
3. 和bitmap相比,屬於兩種特定統計情況,簡單來說,HyperLogLog 去重比 bitmap 方便很多
4. 一般可以bitmap和hyperloglog配合使用,bitmap標識哪些用戶活躍,hyperloglog計數
---
應用場景:
1. 基數不大,數據量不大就用不上,會有點大材小用浪費空間
2. 有局限性,就是只能統計基數數量,而沒辦法去知道具體的內容是什么
3. 和bitmap相比,屬於兩種特定統計情況,簡單來說,HyperLogLog 去重比 bitmap 方便很多
4. 一般可以bitmap和hyperloglog配合使用,bitmap標識哪些用戶活躍,hyperloglog計數
來源:刷刷面試

11. 在並發情況下,Elasticsearch 如果保證讀寫一致?

首先要了解什么是一致性,在分布式系統中,我們一般通過CPA理論分析。

分布式系統不可能同時滿足一致性(C:Consistency)、可用性(A:Availability)和分區容忍性(P:Partition Tolerance),最多只能同時滿足其中兩項。
分布式系統不可能同時滿足一致性(C:Consistency)、可用性(A:Availability)和分區容忍性(P:Partition Tolerance),最多只能同時滿足其中兩項。

  1. 可以通過版本號使用樂觀並發控制,以確保新版本不會被舊版本覆蓋,由應用層來處理具體的沖突;
  2. 另外對於寫操作,一致性級別支持 quorum/one/all,默認為 quorum,即只有當大多數分片可用時才允許寫操作。但即使大多數可用,也可能存在因為網絡等原因導致寫入副本失敗,這樣該副本被認為故障,分片將會在一個不同的節點上重建。
  3. 對於讀操作,可以設置 replication 為 sync(默認),這使得操作在主分片和副本分片都完成后才會返回;如果設置 replication 為 async 時,也可以通過設置搜索請求參數_preference 為 primary 來查詢主分片,確保文檔是最新版本。

12. 介紹一下你們的個性化搜索方案?

如果你沒有很多實戰經驗,可以基於 word2vec 做一些練習,我的博客提供了 word2vec Java版的一些Demo。

基於 word2vec 和 Elasticsearch 實現個性化搜索,它有以下優點:

  1. 基於word2vec的商品向量還有一個可用之處,就是可以用來實現相似商品的推薦;

推薦閱讀:

【Java並發面試】10道不得不會的Java並發基礎面試題
https://blog.csdn.net/qq_40374604/article/details/122159231

【Java基礎面試】10道不得不會的Java基礎面試題
https://blog.csdn.net/qq_40374604/article/details/122011870

【MySQL面試】10道不得不會的MySQL基礎面試題
https://javapub.blog.csdn.net/article/details/122087243

【ElasticSearch面試】10道不得不會的ElasticSearch面試題
https://javapub.blog.csdn.net/article/details/123761794

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM