1. 程式人生 > 資訊 >全國抗疫,騰訊向所有人免費送出 QQ 音樂豪華綠鑽和全民 K 歌 VIP 各 7 天

全國抗疫,騰訊向所有人免費送出 QQ 音樂豪華綠鑽和全民 K 歌 VIP 各 7 天

1、Elasticsearch瞭解多少,說說你們公司ES的叢集架構,索引資料大小,分片有多少,以及一些調優手段 。
答:

面試官:想了解應聘者之前公司接觸的ES使用場景、規模,有沒有做過比較大規模的索引設計、規劃、調優。

解答:

如實結合自己的實踐場景回答即可。

比如:ES叢集架構13個節點,索引根據通道不同共20+索引,根據日期,每日遞增20+

索引:10分片,每日遞增1億+資料,每個通道每天索引大小控制:150GB之內。

僅索引層面調優手段:

1.1、設計階段調優

1、根據業務增量需求,採取基於日期模板建立索引,通過roll over API滾動索引;

2、使用別名進行索引管理;

3、每天凌晨定時對索引做force_merge 操作,以釋放空間;

4、採取冷熱分離機制,熱資料儲存到SSD,提高檢索效率;冷資料定期進行 shrink操作,以縮減儲存;

5、採取 curator 進行索引的生命週期管理;

6、僅針對需要分詞的欄位,合理的設定分詞器;

7、Mapping階段充分結合各個欄位的屬性,是否需要檢索、是否需要儲存等。

1、寫入前副本數設定為 0;

2、寫入前關閉refresh_interval設定為-1,禁用重新整理機制;

3、寫入過程中:採取bulk批量寫入;

4、寫入後恢復副本數和重新整理間隔;

5、儘量使用自動生成的id。

1.3、查詢調優

1、禁用wildcard;

2、禁用批量terms(成百上千的場景);

3、充分利用倒排索引機制,能keyword型別儘量keyword;

4、資料量大時候,可以先基於時間敲定索引再檢索;

5、設定合理的路由機制。

1.4、其他調優

部署調優,業務調優等。

上面的提及一部分,面試者就基本對你之前的實踐或者運維經驗有所評估了。

2、Elasticsearch的倒排索引是什麼?
答:

面試官:想了解你對基礎概念的認知。

解答:通俗解釋一下就可以。

傳統的我們的檢索是通過文章,逐個遍歷找到對應關鍵詞的位置。

而倒排索引,是通過分詞策略,形成了詞和文章的對映關係表,這種詞典+對映表即為倒排索引。

有了倒排索引,就能實現o(1)時間複雜度的效率檢索文章了,極大的提高了檢索效率

學術的解答方式:

倒排索引,相反於一篇文章包含了哪些詞,它從詞出發,記載了這個詞在哪些文件中出現過,由兩部分組成——詞典和倒排表。

加分項:倒排索引的底層實現是基於:FST(Finite State Transducer)資料結構。

lucene從4+版本後開始大量使用的資料結構是FST。FST有兩個優點:

1、空間佔用小。通過對詞典中單詞字首和字尾的重複利用,壓縮了儲存空間;

2、查詢速度快。O(len(str))的查詢時間複雜度。

3、Elasticsearch索引資料多了怎麼辦,如何調優,部署?
答:

面試官:想了解大資料量的運維能力。

解答:索引資料的規劃,應在前期做好規劃,正所謂“設計先行,編碼在後”,這樣才能有效的避免突如其來的資料激增導致叢集處理能力不足引發的線上客戶檢索或者其他業務受到影響。

如何調優,正如問題1所說,這裡細化一下:

3.1 動態索引層面

基於模板+時間+rollover api滾動建立索引,舉例:設計階段定義:blog索引的模板格式為:blog_index_時間戳的形式,每天遞增資料。

這樣做的好處:不至於資料量激增導致單個索引資料量非常大,接近於上線2的32次冪-1,索引儲存達到了TB+甚至更大。
一旦單個索引很大,儲存等各種風險也隨之而來,所以要提前考慮+及早避免。

3.2 儲存層面

冷熱資料分離儲存,熱資料(比如最近3天或者一週的資料),其餘為冷資料。對於冷資料不會再寫入新資料,可以考慮定期 force_merge 加 shrink 壓縮操作,節省儲存空間和檢索效率。

3.3 部署層面

一旦之前沒有規劃,這裡就屬於應急策略。結合ES自身的支援動態擴充套件的特點,動態新增機器的方式可以緩解叢集壓力,注意:如果之前主節點等規劃合理,不需要重啟叢集也能完成動態新增的。

4、Elasticsearch是如何實現master選舉的?
答:

面試官:想了解ES叢集的底層原理,不再只關注業務層面了。

解答:

前置前提:

1、只有候選主節點(master:true)的節點才能成為主節點。

2、最小主節點數(min_master_nodes)的目的是防止腦裂。

這個我看了各種網上分析的版本和原始碼分析的書籍,雲裡霧裡。

核對了一下程式碼,核心入口為findMaster,選擇主節點成功返回對應Master,否則返回null。選舉流程大致描述如下:

第一步:確認候選主節點數達標,elasticsearch.yml設定的值

discovery.zen.minimum_master_nodes;

第二步:比較:先判定是否具備master資格,具備候選主節點資格的優先返回;若兩節點都為候選主節點,則id小的值會主節點。注意這裡的id為string型別。

題外話:獲取節點id的方法。

1GET /_cat/nodes?v&h=ip,port,heapPercent,heapMax,id,name

2ip port heapPercent heapMax id name

5、詳細描述一下Elasticsearch索引文件的過程。
答:

面試官:想了解ES的底層原理,不再只關注業務層面了。

解答:

這裡的索引文件應該理解為文件寫入ES,建立索引的過程。

文件寫入包含:單文件寫入和批量bulk 寫入,這裡只解釋一下:單文件寫入流程。

記住官方文件中的這個圖。

第一步:客戶寫叢集某節點寫入資料,傳送請求。(如果沒有指定路由/協調節點,請求的節點扮演路由節點的角色。)

第二步:節點1接受到請求後,使用文件_id來確定文件屬於分片0。請求會被轉到另外的節點,假定節點3。因此分片0的主分片分配到節點3上。

第三步:節點3在主分片上執行寫操作,如果成功,則將請求並行轉發到節點1和節點2的副本分片上,等待結果返回。所有的副本分片都報告成功,節點3將向協調節點(節點 1)報告成功,節點1向請求客戶端報告寫入成功。

如果面試官再問:第二步中的文件獲取分片的過程?

回答:藉助路由演算法獲取,路由演算法就是根據路由和文件id計算目標的分片id的過程。

1shard = hash(_routing) % (num_of_primary_shards)
1
6、詳細描述一下Elasticsearch搜尋的過程?
答:

面試官:想了解ES搜尋的底層原理,不再只關注業務層面了。

解答:

搜尋拆解為“query then fetch” 兩個階段。

query階段的目的:定位到位置,但不取。

步驟拆解如下:

1、假設一個索引資料有5主+1 副本共10分片,一次請求會命中(主或者副本分片中)的一個。

2、每個分片在本地進行查詢,結果返回到本地有序的優先佇列中。

3、第2步驟的結果傳送到協調節點,協調節點產生一個全域性的排序列表。fetch階段的目的:取資料。

路由節點獲取所有文件,返回給客戶端。

7、Elasticsearch在部署時,對Linux的設定有哪些優化方法?
答:

面試官:想了解對ES叢集的運維能力。

解答:

1、關閉快取swap

2、堆記憶體設定為:Min(節點記憶體/2, 32GB)

3、設定最大檔案控制代碼數

4、執行緒池+佇列大小根據業務需要做調整

5、磁碟儲存raid方式——儲存有條件使用RAID10,增加單節點效能以及避免單節點儲存故障

8、lucence內部結構是什麼?
答:

面試官:想了解你的知識面的廣度和深度。

解答:

Lucene是有索引和搜尋的兩個過程,包含索引建立,索引,搜尋三個要點。可以基於這個脈絡展開一些。

最近面試一些公司,被問到的關於Elasticsearch和搜尋引擎相關的問題,以及自己總結的回答。

9、Elasticsearch是如何實現Master選舉的?
答:

1、Elasticsearch的選主是ZenDiscovery 模組負責的,主要包含Ping(節點之間通過這個RPC來發現彼此)和Unicast(單播模組包含一個主機列表以控制哪些節點需要ping通)這兩部分;

2、對所有可以成為master的節點(node.master:true)根據nodeId字典排序,每次選舉每個節點都把自己所知道節點排一次序,然後選出第一個(第0位)節點,暫且認為它是master節點。

3、如果對某個節點的投票數達到一定的值(可以成為master節點數n/2+1)並且該節點自己也選舉自己,那這個節點就是 master。否則重新選舉一直到滿足上述條件。

4、補充:master節點的職責主要包括叢集、節點和索引的管理,不負責文件級別的管理;data節點可以關閉http 功能*。

10、Elasticsearch中的節點(比如共20個),其中的10個選了一個master,另外10個選了另一個master,怎麼辦?
答:

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

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

11、客戶端在和叢集連線時,如何選擇特定的節點執行請求的?
答:

1、TransportClient利用transport模組遠端連線一個elasticsearch叢集。它並不加入到叢集中,只是簡單的獲得一個或者多個初始化的transport地址,並以 輪詢 的方式與這些地址進行通訊。

12、詳細描述一下Elasticsearch索引文件的過程。
答:

協調節點預設使用文件ID參與計算(也支援通過routing),以便為路由提供合適的分片。

shard = hash(document_id) % (num_of_primary_shards)
1
1、當分片所在的節點接收到來自協調節點的請求後,會將請求寫入到Memory Buffer,然後定時(預設是每隔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)時

補充:關於Lucene 的 Segement:

1、Lucene索引是由多個段組成,段本身是一個功能齊全的倒排索引。

2、段是不可變的,允許Lucene將新的文件增量地新增到索引中,而不用從頭重建索引。

3、對於每一個搜尋請求而言,索引中的所有段都會被搜尋,並且每個段會消耗CPU的時鐘周、檔案控制代碼和記憶體。這意味著段的數量越多,搜尋效能會越低。

4、為了解決這個問題,Elasticsearch會合並小段到一個較大的段,提交新的合併段到磁碟,並刪除那些舊的小段。

13、詳細描述一下Elasticsearch更新和刪除文件的過程。
答:

1、刪除和更新也都是寫操作,但是Elasticsearch 中的文件是不可變的,因此不能被刪除或者改動以展示其變更;

2、磁碟上的每個段都有一個相應的del檔案。當刪除請求傳送後,文件並沒有真的被刪除,而是在del檔案中被標記為刪除。該文件依然能匹配查詢,但是會在結果中被過濾掉。當段合併時,在del檔案中被標記為刪除的文件將不會被寫入新段。

3、在新的文件被建立時,Elasticsearch會為該文件指定一個版本號,當執行更新時,舊版本的文件在del檔案中被標記為刪除,新版本的文件被索引到一個新段。舊版本的文件依然能匹配查詢,但是會在結果中被過濾掉。

14、詳細描述一下Elasticsearch搜尋的過程。
答:

1、搜尋被執行成一個兩階段過程,我們稱之為Query Then Fetch;

2、在初始查詢階段時,查詢會廣播到索引中每一個分片拷貝(主分片或者副本分片)。 每個分片在本地執行搜尋並構建一個匹配文件的大小為from + size的優先佇列。

PS:在搜尋的時候是會查詢Filesystem Cache的,但是有部分資料還在MemoryBuffer,所以搜尋是近實時的。

3、每個分片返回各自優先佇列中 所有文件的ID和排序值 給協調節點,它合併這些值到自己的優先佇列中來產生一個全域性排序後的結果列表。

4、接下來就是 取回階段,協調節點辨別出哪些文件需要被取回並向相關的分片提交多個GET請求。每個分片載入並 豐富 文件,如果有需要的話,接著返回文件給協調節點。一旦所有的文件都被取回了,協調節點返回結果給客戶端。

5、補充:Query Then Fetch的搜尋型別在文件相關性打分的時候參考的是本分片的資料,這樣在文件數量較少的時候可能不夠準確,DFS Query Then Fetch增加了一個預查詢的處理,詢問Term 和 Document frequency,這個評分更準確,但是效能會變差。


15、在Elasticsearch中,是怎麼根據一個詞找到對應的倒排索引的?
答:

SEE:

Lucene 的索引檔案格式(1)

Lucene 的索引檔案格式(2)

16、Elasticsearch在部署時,對Linux的設定有哪些優化方法?
答:

1、64GB記憶體的機器是非常理想的, 但是32GB和16GB機器也是很常見的。少於8GB會適得其反。

2、如果你要在更快的CPUs和更多的核心之間選擇,選擇更多的核心更好。多個核心提供的額外併發遠勝過稍微快一點點的時鐘頻率。

3、如果你負擔得起SSD,它將遠遠超出任何旋轉介質。 基於SSD的節點,查詢和索引效能都有提升。如果你負擔得起,SSD 是一個好的選擇。

4、即使資料中心們近在咫尺,也要避免叢集跨越多個數據中心。絕對要避免叢集跨越大的地理距離。

5、請確保執行你應用程式的JVM和伺服器的JVM是完全一樣的。 在Elasticsearch的幾個地方,使用Java的本地序列化。

6、通過設定 gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time 可以在叢集重啟的時候避免過多的分片交換,這可能會讓資料恢復從數個小時縮短為幾秒鐘。

7、Elasticsearch 預設被配置為使用單播發現,以防止節點無意中加入叢集。只有在同一臺機器上執行的節點才會自動組成叢集。最好使用單播代替組播。

8、不要隨意修改垃圾回收器(CMS)和各個執行緒池的大小。

9、把你的記憶體的(少於)一半給Lucene(但不要超過32GB!),通過ES_HEAP_SIZE 環境變數設定。

10、記憶體交換到磁碟對伺服器效能來說是致命的。如果記憶體交換到磁碟上,一個100微秒的操作可能變成10毫秒。 再想想那麼多10微秒的操作時延累加起來。 不難看出swapping對於效能是多麼可怕。

11、Lucene使用了大量的檔案。同時,Elasticsearch在節點和HTTP客戶端之間進行通訊也使用了大量的套接字。 所有這一切都需要足夠的檔案描述符。你應該增加你的檔案描述符,設定一個很大的值,如64,000。

補充:索引階段效能提升方法

1、使用批量請求並調整其大小:每次批量資料5–15 MB大是個不錯的起始點。

2、儲存:使用 SSD

3、段和合並:Elasticsearch 預設值是20MB/s,對機械磁碟應該是個不錯的設定。如果你用的是SSD,可以考慮提高到 100–200 MB/s。

如果你在做批量匯入,完全不在意搜尋,你可以徹底關掉合併限流。另外還可以增加index.translog.flush_threshold_size設定,從預設的512MB到更大一些的值,比如1GB,這可以在一次清空觸發的時候在事務日誌裡積累出更大的段。

4、如果你的搜尋結果不需要近實時的準確度,考慮把每個索引的index.refresh_interval 改到30s。

5、如果你在做大批量匯入,考慮通過設定 index.number_of_replicas: 0 關閉副本。

17、對於GC方面,在使用Elasticsearch時要注意什麼?
答:

1、SEE:https://elasticsearch.cn/article/32

2、倒排詞典的索引需要常駐記憶體,無法GC,需要監控data node 上segmentmemory增長趨勢。

3、各類快取,field cache, filter cache, indexing cache, bulk queue 等等,要設定合理的大小,並且要應該根據最壞的情況來看heap是否夠用,也就是各類快取全部佔滿的時候,還有heap空間可以分配給其他任務嗎?避免採用clear cache等“自欺欺人”的方式來釋放記憶體。

4、避免返回大量結果集的搜尋與聚合。確實需要大量拉取資料的場景,可以採用scan & scroll api來實現。

5、cluster stats駐留記憶體並無法水平擴充套件,超大規模叢集可以考慮分拆成多個叢集通過tribe node連線。

6、想知道heap夠不夠,必須結合實際應用場景,並對叢集的heap使用情況做持續的監控。

18、Elasticsearch對於大資料量(上億量級)的聚合如何實現?
答:

Elasticsearch提供的首個近似聚合是cardinality度量。它提供一個欄位的基數,即該欄位的distinct或者unique值的數目。它是基於HLL演算法的。HLL會先對我們的輸入作雜湊運算,然後根據雜湊運算的結果中的bits做概率估算從而得到基數。其特點是:可配置的精度,用來控制記憶體的使用(更精確 = 更多記憶體);

小的資料集精度是非常高的;我們可以通過配置引數,來設定去重需要的固定記憶體使用量。無論數千還是數十億的唯一值,記憶體使用量只與你配置的精確度相關。

19、在併發情況下,Elasticsearch如果保證讀寫一致?
答:

1、可以通過版本號使用樂觀併發控制,以確保新版本不會被舊版本覆蓋,由應用層來處理具體的衝突;

2、另外對於寫操作,一致性級別支援quorum/one/all,預設為quorum,即只有當大多數分片可用時才允許寫操作。但即使大多數可用,也可能存在因為網路等原因導致寫入副本失敗,這樣該副本被認為故障,分片將會在一個不同的節點上重建。

3、對於讀操作,可以設定replication為sync(預設),這使得操作在主分片和副本分片都完成後才會返回;如果設定replication 為async時,也可以通過設定搜尋請求引數_preference 為 primary來查詢主分片,確保文件是最新版本。

20、如何監控Elasticsearch叢集狀態?
答:

Marvel讓你可以很簡單的通過Kibana監控Elasticsearch。你可以實時檢視你的叢集健康狀態和效能,也可以分析過去的叢集、索引和節點指標。

21、介紹下你們電商搜尋的整體技術架構。
答:


22、介紹一下你們的個性化搜尋方案?
答:

SEE基於word2vec和Elasticsearch實現個性化搜尋。

23、是否瞭解字典樹?
答:

常用字典資料結構如下所示

Trie的核心思想是空間換時間,利用字串的公共字首來降低查詢時間的開銷以達到提高效率的目的。它有3個基本性質:

1、根節點不包含字元,除根節點外每一個節點都只包含一個字元。

2、從根節點到某一節點,路徑上經過的字元連線起來,為該節點對應的字串。

3、每個節點的所有子節點包含的字元都不相同。

1、可以看到,trie樹每一層的節點數是26^i 級別的。所以為了節省空間,我們還可以用動態連結串列,或者用陣列來模擬動態。而空間的花費,不會超過單詞數×單詞長度。

2、實現:對每個結點開一個字母集大小的陣列,每個結點掛一個連結串列,使用左兒子右兄弟表示法記錄這棵樹;

3、對於中文的字典樹,每個節點的子節點用一個雜湊表儲存,這樣就不用浪費太大的空間,而且查詢速度上可以保留雜湊的複雜度O(1)

24、拼寫糾錯是如何實現的?
答:

1、拼寫糾錯是基於編輯距離來實現;編輯距離是一種標準的方法,它用來表示經過插入、刪除和替換操作從一個字串轉換到另外一個字串的最小操作步數;

2、編輯距離的計算過程:比如要計算 batyu 和 beauty 的編輯距離,先建立一個7×8 的表(batyu長度為5,coffee長度為6,各加2),接著,在如下位置填入黑色數字。其他格的計算過程是取以下三個值的最小值:

如果最上方的字元等於最左方的字元,則為左上方的數字。否則為左上方的數字+1。

(對於3,3 來說為 0)

左方數字+1(對於3,3格來說為2)

上方數字+1(對於3,3格來說為2)

最終取右下角的值即為編輯距離的值3。

對於拼寫糾錯,我們考慮構造一個度量空間(Metric Space),該空間內任何關係滿足以下三條基本條件:

d(x,y) = 0 – 假如 x 與 y 的距離為 0,則 x=y

d(x,y) = d(y,x) – x 到 y 的距離等同於 y 到 x 的距離

d(x,y) + d(y,z) >= d(x,z) – 三角不等式

1、根據三角不等式,則滿足與query距離在n範圍內的另一個字元轉B,其與A的距離最大為d+n,最小為d-n。

2、BK樹的構造就過程如下:

每個節點有任意個子節點,每條邊有個值表示編輯距離。所有子節點到父節點的邊上標註n表示編輯距離恰好為n。
比如,我們有棵樹父節點是”book”和兩個子節點”cake”和”books”,”book”到”books”的邊標號1,”book”到”cake”的邊上標號4。

從字典裡構造好樹後,無論何時你想插入新單詞時,計算該單詞與根節點的編輯距離,並且查詢數值為d(neweord, root)的邊。遞迴得與各子節點進行比較,直到沒有子節點,你就可以建立新的子節點並將新單詞儲存在那。

比如,插入”boo”到剛才上述例子的樹中,我們先檢查根節點,查詢 d(“book”, “boo”) =1的邊,然後檢查標號為1的邊的子節點,得到單詞”books”。我們再計算距離 d(“books”, “boo”)=2,則將新單詞插在”books”之後,邊標號為2。

3、查詢相似詞如下:計算單詞與根節點的編輯距離d,然後遞迴查詢每個子節點標號為d-n到d+n(包含)的邊。假如被檢查的節點與搜尋單詞的距離d小於n,則返回該節點並繼續查詢。

比如輸入cape且最大容忍距離為1,則先計算和根的編輯距離 d(“book”, “cape”)=4,然後接著找和根節點之間編輯距離為3到5 的,這個就找到了cake這個節點,計算d(“cake”,“cape”)=1,滿足條件所以返回cake,然後再找和cake節點編輯距離是0到2 的,分別找到cape和cart節點,這樣就得到cape這個滿足條件的結果。
————————————————
版權宣告:本文為CSDN博主「Java小叮噹」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/m0_48795607/article/details/116656094