您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Elasticsearch有哪些面試題”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Elasticsearch有哪些面試題”這篇文章吧。
面試官:想了解應(yīng)聘者之前公司接觸的 ES 使用場景、規(guī)模,有沒有做過比較大 規(guī)模的索引設(shè)計、規(guī)劃、調(diào)優(yōu)。
解答: 如實結(jié)合自己的實踐場景回答即可。 比如:ES 集群架構(gòu) 13 個節(jié)點,索引根據(jù)通道不同共 20+索引,根據(jù)日期,每日 遞增 20+,索引:10 分片,每日遞增 1 億+數(shù)據(jù), 每個通道每天索引大小控制:150GB 之內(nèi)。
僅索引層面調(diào)優(yōu)手段:
1、根據(jù)業(yè)務(wù)增量需求,采取基于日期模板創(chuàng)建索引,通過 roll over API 滾動索引;
2、使用別名進行索引管理;
3、每天凌晨定時對索引做 force_merge 操作,以釋放空間;
4、采取冷熱分離機制,熱數(shù)據(jù)存儲到 SSD,提高檢索效率;冷數(shù)據(jù)定期進行 shrink操作,以縮減存儲;
5、采取 curator 進行索引的生命周期管理;
6、僅針對需要分詞的字段,合理的設(shè)置分詞器;
7、Mapping 階段充分結(jié)合各個字段的屬性,是否需要檢索、是否需要存儲等?!?.
1、寫入前副本數(shù)設(shè)置為 0;
2、寫入前關(guān)閉 refresh_interval 設(shè)置為-1,禁用刷新機制;
3、寫入過程中:采取 bulk 批量寫入;
4、寫入后恢復(fù)副本數(shù)和刷新間隔;
5、盡量使用自動生成的 id。
1、禁用 wildcard;
2、禁用批量 terms(成百上千的場景);
3、充分利用倒排索引機制,能 keyword 類型盡量 keyword;
4、數(shù)據(jù)量大時候,可以先基于時間敲定索引再檢索;
5、設(shè)置合理的路由機制。
部署調(diào)優(yōu),業(yè)務(wù)調(diào)優(yōu)等。
上面的提及一部分,面試者就基本對你之前的實踐或者運維經(jīng)驗有所評估了。
面試官:想了解你對基礎(chǔ)概念的認(rèn)知。
解答:通俗解釋一下就可以。
傳統(tǒng)的我們的檢索是通過文章,逐個遍歷找到對應(yīng)關(guān)鍵詞的位置。
而倒排索引,是通過分詞策略,形成了詞和文章的映射關(guān)系表,這種詞典+映射表即為倒排索引。
有了倒排索引,就能實現(xiàn) o(1)時間復(fù)雜度的效率檢索文章了,極大的提高了檢索
倒排索引,相反于一篇文章包含了哪些詞,它從詞出發(fā),記載了這個詞在哪些文檔中出現(xiàn)過,由兩部分組成——詞典和倒排表。
加分項:倒排索引的底層實現(xiàn)是基于:FST(Finite State Transducer)數(shù)據(jù)結(jié)構(gòu)。
lucene 從 4+版本后開始大量使用的數(shù)據(jù)結(jié)構(gòu)是 FST。FST 有兩個優(yōu)點:
1、空間占用小。通過對詞典中單詞前綴和后綴的重復(fù)利用,壓縮了存儲空間;
2、查詢速度快。O(len(str))的查詢時間復(fù)雜度。
面試官:想了解大數(shù)據(jù)量的運維能力。
解答:索引數(shù)據(jù)的規(guī)劃,應(yīng)在前期做好規(guī)劃,正所謂“設(shè)計先行,編碼在后”, 這樣才能有效的避免突如其來的數(shù)據(jù)激增導(dǎo)致集群處理能力不足引發(fā)的線上客戶 檢索或者其他業(yè)務(wù)受到影響。 如何調(diào)優(yōu),正如問題 1 所說,這里細化一下:
基于模板+時間+rollover api 滾動創(chuàng)建索引,舉例:設(shè)計階段定義:blog 索 引的模板格式為:blog_index_時間戳的形式,每天遞增數(shù)據(jù)。
這樣做的好處:不至于數(shù)據(jù)量激增導(dǎo)致單個索引數(shù)據(jù)量非常大,接近于上線 2 的 32 次冪-1,索引存儲達到了 TB+甚至更大。
一旦單個索引很大,存儲等各種風(fēng)險也隨之而來,所以要提前考慮+及早避免。
冷熱數(shù)據(jù)分離存儲,熱數(shù)據(jù)(比如最近 3 天或者一周的數(shù)據(jù)),其余為冷數(shù)據(jù)。 對于冷數(shù)據(jù)不會再寫入新數(shù)據(jù),可以考慮定期 force_merge 加 shrink 壓縮操作, 節(jié)省存儲空間和檢索效率。
一旦之前沒有規(guī)劃,這里就屬于應(yīng)急策略。 結(jié)合 ES 自身的支持動態(tài)擴展的特點,動態(tài)新增機器的方式可以緩解集群壓力,注 意:如果之前主節(jié)點等規(guī)劃合理,不需要重啟集群也能完成動態(tài)新增的。
面試官:想了解 ES 集群的底層原理,不再只關(guān)注業(yè)務(wù)層面了。
解答: 前置前提:
1、只有候選主節(jié)點(master:true)的節(jié)點才能成為主節(jié)點。
2、最小主節(jié)點數(shù)(min_master_nodes)的目的是防止腦裂。 這個我看了各種網(wǎng)上分析的版本和源碼分析的書籍,云里霧里。 核對了一下代碼,核心入口為 findMaster,選擇主節(jié)點成功返回對應(yīng) Master,否 則返回 null。選舉流程大致描述如下:
第一步:確認(rèn)候選主節(jié)點數(shù)達標(biāo),elasticsearch.yml 設(shè)置的值 discovery.zen.minimum_master_nodes;
第二步:比較:先判定是否具備 master 資格,具備候選主節(jié)點資格的優(yōu)先返回; 若兩節(jié)點都為候選主節(jié)點,則 id 小的值會主節(jié)點。注意這里的 id 為 string 類型。
題外話:獲取節(jié)點 id 的方法。
1GET /_cat/nodes?v&h=ip,port,heapPercent,heapMax,id,name 2ip port heapPercent heapMax id name
面試官:想了解 ES 的底層原理,不再只關(guān)注業(yè)務(wù)層面了。
解答: 這里的索引文檔應(yīng)該理解為文檔寫入 ES,創(chuàng)建索引的過程。 文檔寫入包含:單文檔寫入和批量 bulk 寫入,這里只解釋一下:單文檔寫入流程。
第一步:客戶寫集群某節(jié)點寫入數(shù)據(jù),發(fā)送請求。(如果沒有指定路由/協(xié)調(diào)節(jié)點,請求的節(jié)點扮演路由節(jié)點的角色。)
第二步:節(jié)點 1 接受到請求后,使用文檔_id 來確定文檔屬于分片 0。請求會被轉(zhuǎn) 到另外的節(jié)點,假定節(jié)點 3。因此分片 0 的主分片分配到節(jié)點 3 上。
第三步:節(jié)點 3 在主分片上執(zhí)行寫操作,如果成功,則將請求并行轉(zhuǎn)發(fā)到節(jié)點 1 和節(jié)點 2 的副本分片上,等待結(jié)果返回。所有的副本分片都報告成功,節(jié)點 3 將 向協(xié)調(diào)節(jié)點(節(jié)點 1)報告成功,節(jié)點 1 向請求客戶端報告寫入成功。
如果面試官再問:第二步中的文檔獲取分片的過程? 回答:借助路由算法獲取,路由算法就是根據(jù)路由和文檔 id 計算目標(biāo)的分片 id 的 過程。
shard = hash(_routing) % (num_of_primary_shards)
面試官:想了解 ES 搜索的底層原理,不再只關(guān)注業(yè)務(wù)層面了。
解答: 搜索拆解為“query then fetch” 兩個階段。 query 階段的目的: 定位到位置,但不取。 步驟拆解如下: 1、假設(shè)一個索引數(shù)據(jù)有 5 主+1 副本 共 10 分片,一次請求會命中(主或者副本 分片中)的一個。
2、每個分片在本地進行查詢,結(jié)果返回到本地有序的優(yōu)先隊列中。
3、第 2)步驟的結(jié)果發(fā)送到協(xié)調(diào)節(jié)點,協(xié)調(diào)節(jié)點產(chǎn)生一個全局的排序列表。 fetch 階段的目的: 取數(shù)據(jù)。 路由節(jié)點獲取所有文檔,返回給客戶端。
面試官:想了解對 ES 集群的運維能力。
解答:
1、關(guān)閉緩存 swap;
2、堆內(nèi)存設(shè)置為:Min(節(jié)點內(nèi)存/2, 32GB);\
3、設(shè)置最大文件句柄數(shù);
4、線程池+隊列大小根據(jù)業(yè)務(wù)需要做調(diào)整;
5、磁盤存儲 raid 方式——存儲有條件使用 RAID10,增加單節(jié)點性能以及避免單節(jié)點存儲故障。
面試官:想了解你的知識面的廣度和深度。
解答:Lucene 是有索引和搜索的兩個過程,包含索引創(chuàng)建,索引,搜索三個要點??梢曰谶@個脈絡(luò)展開一些。
1、Elasticsearch 的選主是 ZenDiscovery 模塊負責(zé)的,主要包含 Ping(節(jié)點之 間通過這個 RPC 來發(fā)現(xiàn)彼此)和 Unicast(單播模塊包含一個主機列表以控制哪 些節(jié)點需要 ping 通)這兩部分;
2、對所有可以成為 master 的節(jié)點(node.master: true)根據(jù) nodeId 字典排 序,每次選舉每個節(jié)點都把自己所知道節(jié)點排一次序,然后選出第一個(第 0 位) 節(jié)點,暫且認(rèn)為它是 master 節(jié)點。
3、如果對某個節(jié)點的投票數(shù)達到一定的值(可以成為 master 節(jié)點數(shù) n/2+1)并 且該節(jié)點自己也選舉自己,那這個節(jié)點就是 master。否則重新選舉一直到滿足上 述條件。
4、補充:master 節(jié)點的職責(zé)主要包括集群、節(jié)點和索引的管理,不負責(zé)文檔級 別的管理;data 節(jié)點可以關(guān)閉 http 功能*。
1、當(dāng)集群 master 候選數(shù)量不小于 3 個時,可以通過設(shè)置最少投票通過數(shù)量 (discovery.zen.minimum_master_nodes)超過所有候選節(jié)點一半以上來解 決腦裂問題;
2、當(dāng)候選數(shù)量為兩個時,只能修改為唯一的一個 master 候選,其他作為 data 節(jié)點,避免腦裂問題。
1、TransportClient 利用 transport 模塊遠程連接一個 elasticsearch 集群。它并 不加入到集群中,只是簡單的獲得一個或者多個初始化的 transport 地址,并以 輪 詢 的方式與這些地址進行通信。
協(xié)調(diào)節(jié)點默認(rèn)使用文檔 ID 參與計算(也支持通過 routing),以便為路由提供合 適的分片。
shard = hash(document_id) % (num_of_primary_shards)
1、當(dāng)分片所在的節(jié)點接收到來自協(xié)調(diào)節(jié)點的請求后,會將請求寫入到 Memory Buffer,然后定時(默認(rèn)是每隔 1 秒)寫入到 Filesystem Cache,這個從 Momery Buffer 到 Filesystem Cache 的過程就叫做 refresh;
2、當(dāng)然在某些情況下,存在 Momery Buffer 和 Filesystem Cache 的數(shù)據(jù)可能會 丟失,ES 是通過 translog 的機制來保證數(shù)據(jù)的可靠性的。其實現(xiàn)機制是接收到請 求后,同時也會寫入到 translog 中,當(dāng) Filesystem cache 中的數(shù)據(jù)寫入到磁盤中 時,才會清除掉,這個過程叫做 flush;
3、在 flush 過程中,內(nèi)存中的緩沖將被清除,內(nèi)容被寫入一個新段,段的 fsync 將創(chuàng)建一個新的提交點,并將內(nèi)容刷新到磁盤,舊的 translog 將被刪除并開始一 個新的 translog。
4、flush 觸發(fā)的時機是定時觸發(fā)(默認(rèn) 30 分鐘)或者 translog 變得太大(默認(rèn) 為 512M)時;
1、Lucene 索引是由多個段組成,段本身是一個功能齊全的倒排索引。
2、段是不可變的,允許 Lucene 將新的文檔增量地添加到索引中,而不用從頭重 建索引。
3、對于每一個搜索請求而言,索引中的所有段都會被搜索,并且每個段會消耗 CPU 的時鐘周、文件句柄和內(nèi)存。這意味著段的數(shù)量越多,搜索性能會越低。
4、為了解決這個問題,Elasticsearch 會合并小段到一個較大的段,提交新的合并 段到磁盤,并刪除那些舊的小段。
1、刪除和更新也都是寫操作,但是 Elasticsearch 中的文檔是不可變的,因此不能被刪除或者改動以展示其變更;
2、磁盤上的每個段都有一個相應(yīng)的.del 文件。當(dāng)刪除請求發(fā)送后,文檔并沒有真的被刪除,而是在.del 文件中被標(biāo)記為刪除。該文檔依然能匹配查詢,但是會在結(jié)果中被過濾掉。當(dāng)段合并時,在.del 文件中被標(biāo)記為刪除的文檔將不會被寫入新段。
3、在新的文檔被創(chuàng)建時,Elasticsearch 會為該文檔指定一個版本號,當(dāng)執(zhí)行更新時,舊版本的文檔在.del 文件中被標(biāo)記為刪除,新版本的文檔被索引到一個新段。舊版本的文檔依然能匹配查詢,但是會在結(jié)果中被過濾掉。
1、搜索被執(zhí)行成一個兩階段過程,我們稱之為 Query Then Fetch;
2、在初始 查詢階段 時,查詢會廣播到索引中每一個分片拷貝(主分片或者副本分片)。 每個分片在本地執(zhí)行搜索并構(gòu)建一個匹配文檔的大小為 from + size 的優(yōu)先隊列。PS:在搜索的時候是會查詢 Filesystem Cache 的,但是有部分?jǐn)?shù)據(jù)還在 MemoryBuffer,所以搜索是近實時的。
3、每個分片返回各自優(yōu)先隊列中 所有文檔的 ID 和排序值 給協(xié)調(diào)節(jié)點,它合并這些值到自己的優(yōu)先隊列中來產(chǎn)生一個全局排序后的結(jié)果列表。
4、接下來就是 取回階段,協(xié)調(diào)節(jié)點辨別出哪些文檔需要被取回并向相關(guān)的分片提交多個 GET 請求。每個分片加載并 豐富 文檔,如果有需要的話,接著返回文檔給協(xié)調(diào)節(jié)點。一旦所有的文檔都被取回了,協(xié)調(diào)節(jié)點返回結(jié)果給客戶端。
5、補充:Query Then Fetch 的搜索類型在文檔相關(guān)性打分的時候參考的是本分片的數(shù)據(jù),這樣在文檔數(shù)量較少的時候可能不夠準(zhǔn)確,DFS Query Then Fetch 增加了一個預(yù)查詢的處理,詢問 Term 和 Document frequency,這個評分更準(zhǔn)確,但是性能會變差
Lucene 的索引文件格式(1)
Lucene 的索引文件格式(2)
1、64 GB 內(nèi)存的機器是非常理想的, 但是 32 GB 和 16 GB 機器也是很常見的。少于 8 GB 會適得其反。
2、如果你要在更快的 CPUs 和更多的核心之間選擇,選擇更多的核心更好。多個內(nèi)核提供的額外并發(fā)遠勝過稍微快一點點的時鐘頻率。
3、如果你負擔(dān)得起 SSD,它將遠遠超出任何旋轉(zhuǎn)介質(zhì)。 基于 SSD 的節(jié)點,查詢和索引性能都有提升。如果你負擔(dān)得起,SSD 是一個好的選擇。
4、即使數(shù)據(jù)中心們近在咫尺,也要避免集群跨越多個數(shù)據(jù)中心。絕對要避免集群跨越大的地理距離。
5、請確保運行你應(yīng)用程序的 JVM 和服務(wù)器的 JVM 是完全一樣的。 在Elasticsearch 的幾個地方,使用 Java 的本地序列化。
6、通過設(shè)置 gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time 可以在集群重啟的時候避免過多的分片交換,這可能會讓數(shù)據(jù)恢復(fù)從數(shù)個小時縮短為幾秒鐘。
7、Elasticsearch 默認(rèn)被配置為使用單播發(fā)現(xiàn),以防止節(jié)點無意中加入集群。只有在同一臺機器上運行的節(jié)點才會自動組成集群。最好使用單播代替組播。
8、不要隨意修改垃圾回收器(CMS)和各個線程池的大小
9、把你的內(nèi)存的(少于)一半給 Lucene(但不要超過 32 GB?。ㄟ^ES_HEAP_SIZE 環(huán)境變量設(shè)置。
10、內(nèi)存交換到磁盤對服務(wù)器性能來說是致命的。如果內(nèi)存交換到磁盤上,一個100 微秒的操作可能變成 10 毫秒。 再想想那么多 10 微秒的操作時延累加起來。 不難看出 swapping 對于性能是多么可怕。
11、Lucene 使用了大量的文件。同時,Elasticsearch 在節(jié)點和 HTTP 客戶端之間進行通信也使用了大量的套接字。 所有這一切都需要足夠的文件描述符。你應(yīng)該增加你的文件描述符,設(shè)置一個很大的值,如 64,000。
1、使用批量請求并調(diào)整其大?。好看闻繑?shù)據(jù) 5–15 MB 大是個不錯的起始點。
2、存儲:使用 SSD
3、段和合并:Elasticsearch 默認(rèn)值是 20 MB/s,對機械磁盤應(yīng)該是個不錯的設(shè) 置。如果你用的是 SSD,可以考慮提高到 100–200 MB/s。如果你在做批量導(dǎo)入, 完全不在意搜索,你可以徹底關(guān)掉合并限流。另外還可以增加
index.translog.flush_threshold_size 設(shè)置,從默認(rèn)的 512 MB 到更大一些的 值,比如 1 GB,這可以在一次清空觸發(fā)的時候在事務(wù)日志里積累出更大的段。
4、如果你的搜索結(jié)果不需要近實時的準(zhǔn)確度,考慮把每個索引的 index.refresh_interval 改到 30s。
5、如果你在做大批量導(dǎo)入,考慮通過設(shè)置 index.number_of_replicas: 0 關(guān)閉副 本。
1、SEE:https://elasticsearch.cn/article/32
2、倒排詞典的索引需要常駐內(nèi)存,無法 GC,需要監(jiān)控 data node 上 segmentmemory 增長趨勢。
3、各類緩存,field cache, filter cache, indexing cache, bulk queue 等等,要設(shè)置合理的大小,并且要應(yīng)該根據(jù)最壞的情況來看 heap 是否夠用,也就是各類緩存全部占滿的時候,還有 heap 空間可以分配給其他任務(wù)嗎?避免采用 clear cache等“自欺欺人”的方式來釋放內(nèi)存。
4、避免返回大量結(jié)果集的搜索與聚合。確實需要大量拉取數(shù)據(jù)的場景,可以采用scan & scroll api 來實現(xiàn)。
5、cluster stats 駐留內(nèi)存并無法水平擴展,超大規(guī)模集群可以考慮分拆成多個集群通過 tribe node 連接。
6、想知道 heap 夠不夠,必須結(jié)合實際應(yīng)用場景,并對集群的 heap 使用情況做持續(xù)的監(jiān)控。
Elasticsearch 提供的首個近似聚合是 cardinality 度量。它提供一個字段的基數(shù), 即該字段的 distinct 或者 unique 值的數(shù)目。它是基于 HLL 算法的。HLL 會先對 我們的輸入作哈希運算,然后根據(jù)哈希運算的結(jié)果中的 bits 做概率估算從而得到 基數(shù)。其特點是:可配置的精度,用來控制內(nèi)存的使用(更精確 = 更多內(nèi)存); 小的數(shù)據(jù)集精度是非常高的;我們可以通過配置參數(shù),來設(shè)置去重需要的固定內(nèi) 存使用量。無論數(shù)千還是數(shù)十億的唯一值,內(nèi)存使用量只與你配置的精確度相關(guān)。
1、可以通過版本號使用樂觀并發(fā)控制,以確保新版本不會被舊版本覆蓋,由應(yīng)用 層來處理具體的沖突;
2、另外對于寫操作,一致性級別支持 quorum/one/all,默認(rèn)為 quorum,即只 有當(dāng)大多數(shù)分片可用時才允許寫操作。但即使大多數(shù)可用,也可能存在因為網(wǎng)絡(luò) 等原因?qū)е聦懭敫北臼?,這樣該副本被認(rèn)為故障,分片將會在一個不同的節(jié)點 上重建。
3、對于讀操作,可以設(shè)置 replication 為 sync(默認(rèn)),這使得操作在主分片和副 本分片都完成后才會返回;如果設(shè)置 replication 為 async 時,也可以通過設(shè)置搜 索請求參數(shù)_preference 為 primary 來查詢主分片,確保文檔是最新版本。
Marvel 讓你可以很簡單的通過 Kibana 監(jiān)控 Elasticsearch。你可以實時查看你 的集群健康狀態(tài)和性能,也可以分析過去的集群、索引和節(jié)點指標(biāo)。
以上是“Elasticsearch有哪些面試題”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。