<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ElasticSearch搜索引擎常見面試題總結(jié)

          共 7272字,需瀏覽 15分鐘

           ·

          2021-06-25 01:11

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          一、ElasticSearch基礎(chǔ):

          1、什么是Elasticsearch:

          Elasticsearch 是基于 Lucene 的 Restful 的分布式實(shí)時(shí)全文搜索引擎,每個(gè)字段都被索引并可被搜索,可以快速存儲(chǔ)、搜索、分析海量的數(shù)據(jù)。

          全文檢索是指對(duì)每一個(gè)詞建立一個(gè)索引,指明該詞在文章中出現(xiàn)的次數(shù)和位置。當(dāng)查詢時(shí),根據(jù)事先建立的索引進(jìn)行查找,并將查找的結(jié)果反饋給用戶的檢索方式。這個(gè)過程類似于通過字典中的檢索字表查字的過程。

          2、Elasticsearch 的基本概念:

          (1)index 索引:索引類似于mysql 中的數(shù)據(jù)庫(kù),Elasticesearch 中的索引是存在數(shù)據(jù)的地方,包含了一堆有相似結(jié)構(gòu)的文檔數(shù)據(jù)。

          (2)type 類型:類型是用來定義數(shù)據(jù)結(jié)構(gòu),可以認(rèn)為是 mysql 中的一張表,type 是 index 中的一個(gè)邏輯數(shù)據(jù)分類

          (3)document 文檔:類似于 MySQL 中的一行,不同之處在于 ES 中的每個(gè)文檔可以有不同的字段,但是對(duì)于通用字段應(yīng)該具有相同的數(shù)據(jù)類型,文檔是es中的最小數(shù)據(jù)單元,可以認(rèn)為一個(gè)文檔就是一條記錄。

          (4)Field 字段:Field是Elasticsearch的最小單位,一個(gè)document里面有多個(gè)field

          (5)shard 分片:?jiǎn)闻_(tái)機(jī)器無法存儲(chǔ)大量數(shù)據(jù),es可以將一個(gè)索引中的數(shù)據(jù)切分為多個(gè)shard,分布在多臺(tái)服務(wù)器上存儲(chǔ)。有了shard就可以橫向擴(kuò)展,存儲(chǔ)更多數(shù)據(jù),讓搜索和分析等操作分布到多臺(tái)服務(wù)器上去執(zhí)行,提升吞吐量和性能。

          (6)replica 副本:任何一個(gè)服務(wù)器隨時(shí)可能故障或宕機(jī),此時(shí) shard 可能會(huì)丟失,因此可以為每個(gè) shard 創(chuàng)建多個(gè) replica 副本。replica可以在shard故障時(shí)提供備用服務(wù),保證數(shù)據(jù)不丟失,多個(gè)replica還可以提升搜索操作的吞吐量和性能。primary shard(建立索引時(shí)一次設(shè)置,不能修改,默認(rèn)5個(gè)),replica shard(隨時(shí)修改數(shù)量,默認(rèn)1個(gè)),默認(rèn)每個(gè)索引10個(gè) shard,5個(gè)primary shard,5個(gè)replica shard,最小的高可用配置,是2臺(tái)服務(wù)器。

          3、什么是倒排索引:

          在搜索引擎中,每個(gè)文檔都有一個(gè)對(duì)應(yīng)的文檔 ID,文檔內(nèi)容被表示為一系列關(guān)鍵詞的集合。例如,某個(gè)文檔經(jīng)過分詞,提取了 20 個(gè)關(guān)鍵詞,每個(gè)關(guān)鍵詞都會(huì)記錄它在文檔中出現(xiàn)的次數(shù)和出現(xiàn)位置。那么,倒排索引就是 關(guān)鍵詞到文檔 ID 的映射,每個(gè)關(guān)鍵詞都對(duì)應(yīng)著一系列的文件,這些文件中都出現(xiàn)了該關(guān)鍵詞。有了倒排索引,搜索引擎可以很方便地響應(yīng)用戶的查詢。

          要注意倒排索引的兩個(gè)重要細(xì)節(jié):

          • 倒排索引中的所有詞項(xiàng)對(duì)應(yīng)一個(gè)或多個(gè)文檔

          • 倒排索引中的詞項(xiàng) 根據(jù)字典順序升序排列

          4、DocValues的作用:

          倒排索引也是有缺陷的,假如我們需要對(duì)數(shù)據(jù)做一些聚合操作,比如排序/分組時(shí),lucene內(nèi)部會(huì)遍歷提取所有出現(xiàn)在文檔集合的排序字段,然后再次構(gòu)建一個(gè)最終的排好序的文檔集合list,這個(gè)步驟的過程全部維持在內(nèi)存中操作,而且如果排序數(shù)據(jù)量巨大的話,非常容易就造成solr內(nèi)存溢出和性能緩慢。

          DocValues 就是 es 在構(gòu)建倒排索引的同時(shí),構(gòu)建了正排索引,保存了docId到各個(gè)字段值的映射,可以看作是以文檔為維度,從而實(shí)現(xiàn)根據(jù)指定字段進(jìn)行排序和聚合的功能。另外doc Values 保存在操作系統(tǒng)的磁盤中,當(dāng)docValues大于節(jié)點(diǎn)的可用內(nèi)存,ES可以從操作系統(tǒng)頁(yè)緩存中加載或彈出,從而避免發(fā)生內(nèi)存溢出的異常,docValues遠(yuǎn)小于節(jié)點(diǎn)的可用內(nèi)存,操作系統(tǒng)自然將所有Doc Values存于內(nèi)存中(堆外內(nèi)存),有助于快速訪問。

          5、text 和 keyword類型的區(qū)別:

          兩個(gè)的區(qū)別主要分詞的區(qū)別:keyword 類型是不會(huì)分詞的,直接根據(jù)字符串內(nèi)容建立倒排索引,keyword類型的字段只能通過精確值搜索到;Text 類型在存入 Elasticsearch 的時(shí)候,會(huì)先分詞,然后根據(jù)分詞后的內(nèi)容建立倒排索引

          6、什么是停頓詞過濾:

          停頓詞可以看成是沒有意義的詞,比如“的”、“而”,這類詞沒有必要建立索引

          7、query 和 filter 的區(qū)別?

          (1)query:查詢操作不僅僅會(huì)進(jìn)行查詢,還會(huì)計(jì)算分值,用于確定相關(guān)度;

          (2)filter:查詢操作僅判斷是否滿足查詢條件,不會(huì)計(jì)算任何分值,也不會(huì)關(guān)心返回的排序問題,同時(shí),filter 查詢的結(jié)果可以被緩存,提高性能。

          二、ES的寫入流程:

          1、es 寫數(shù)據(jù)的過程:

          • (1)客戶端選擇一個(gè) node 發(fā)送請(qǐng)求過去,這個(gè) node 就是 coordinating node (協(xié)調(diào)節(jié)點(diǎn))

          • (2)coordinating node 對(duì) document 進(jìn)行路由,將請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的 node(有 primary shard)

          • (3)實(shí)際的 node 上的 primary shard 處理請(qǐng)求,然后將數(shù)據(jù)同步到 replica node 

          • (4)coordinating node 等到 primary node 和所有 replica node 都執(zhí)行成功之后,就返回響應(yīng)結(jié)果給客戶端。

          2、寫數(shù)據(jù)的底層原理:

          (1)數(shù)據(jù)先寫入 memory buffer,然后定時(shí)(默認(rèn)每隔1s)將 memory buffer 中的數(shù)據(jù)寫入一個(gè)新的 segment 文件中,并進(jìn)入 Filesystem cache(同時(shí)清空 memory buffer),這個(gè)過程就叫做 refresh;

          ES 的近實(shí)時(shí)性:數(shù)據(jù)存在 memory buffer 時(shí)是搜索不到的,只有數(shù)據(jù)被 refresh 到  Filesystem cache 之后才能被搜索到,而 refresh 是每秒一次, 所以稱 es 是近實(shí)時(shí)的,可以通過手動(dòng)調(diào)用 es 的 api 觸發(fā)一次 refresh 操作,讓數(shù)據(jù)馬上可以被搜索到;

          (2)由于 memory Buffer 和 Filesystem Cache 都是基于內(nèi)存,假設(shè)服務(wù)器宕機(jī),那么數(shù)據(jù)就會(huì)丟失,所以 ES 通過 translog 日志文件來保證數(shù)據(jù)的可靠性,在數(shù)據(jù)寫入 memory buffer 的同時(shí),將數(shù)據(jù)寫入 translog 日志文件中,在機(jī)器宕機(jī)重啟時(shí),es 會(huì)自動(dòng)讀取 translog 日志文件中的數(shù)據(jù),恢復(fù)到 memory buffer 和 Filesystem cache 中去。

          ES 數(shù)據(jù)丟失的問題:translog 也是先寫入 Filesystem cache,然后默認(rèn)每隔 5 秒刷一次到磁盤中,所以默認(rèn)情況下,可能有 5 秒的數(shù)據(jù)會(huì)僅僅停留在 memory buffer 或者 translog 文件的 Filesystem cache中,而不在磁盤上,如果此時(shí)機(jī)器宕機(jī),會(huì)丟失 5 秒鐘的數(shù)據(jù)。也可以將 translog 設(shè)置成每次寫操作必須是直接 fsync 到磁盤,但是性能會(huì)差很多。

          (3)flush 操作:不斷重復(fù)上面的步驟,translog 會(huì)變得越來越大,當(dāng) translog 文件默認(rèn)每30分鐘或者 閾值超過 512M 時(shí),就會(huì)觸發(fā) commit 操作,即 flush操作。

          • ① 將 buffer 中的數(shù)據(jù) refresh 到 Filesystem Cache 中去,清空 buffer;

          • ② 創(chuàng)建一個(gè)新的 commit point(提交點(diǎn)),同時(shí)強(qiáng)行將 Filesystem Cache 中目前所有的數(shù)據(jù)都 fsync 到磁盤文件中;

          • ③ 刪除舊的 translog 日志文件并創(chuàng)建一個(gè)新的 translog 日志文件,此時(shí) commit 操作完成

          三、ES的更新和刪除流程:

          刪除和更新都是寫操作,但是由于 Elasticsearch 中的文檔是不可變的,因此不能被刪除或者改動(dòng)以展示其變更;所以 ES 利用 .del 文件 標(biāo)記文檔是否被刪除,磁盤上的每個(gè)段都有一個(gè)相應(yīng)的.del 文件

          (1)如果是刪除操作,文檔其實(shí)并沒有真的被刪除,而是在 .del 文件中被標(biāo)記為 deleted 狀態(tài)。該文檔依然能匹配查詢,但是會(huì)在結(jié)果中被過濾掉。

          (2)如果是更新操作,就是將舊的 doc 標(biāo)識(shí)為 deleted 狀態(tài),然后創(chuàng)建一個(gè)新的 doc。

          memory buffer 每 refresh 一次,就會(huì)產(chǎn)生一個(gè) segment 文件 ,所以默認(rèn)情況下是 1s 生成一個(gè) segment 文件,這樣下來 segment 文件會(huì)越來越多,此時(shí)會(huì)定期執(zhí)行 merge。每次 merge 的時(shí)候,會(huì)將多個(gè) segment 文件合并成一個(gè),同時(shí)這里會(huì)將標(biāo)識(shí)為 deleted 的 doc 給物理刪除掉,不寫入到新的 segment 中,然后將新的 segment 文件寫入磁盤,這里會(huì)寫一個(gè) commit point ,標(biāo)識(shí)所有新的 segment 文件,然后打開 segment 文件供搜索使用,同時(shí)刪除舊的 segment 文件

          有關(guān)segment段合并過程,有興趣可以閱讀這個(gè)文章:https://blog.csdn.net/a745233700/article/details/117953198

          四、ES的搜索流程:

          搜索被執(zhí)行成一個(gè)兩階段過程,即 Query Then Fetch:

          1、Query階段:

          客戶端發(fā)送請(qǐng)求到 coordinate node,協(xié)調(diào)節(jié)點(diǎn)將搜索請(qǐng)求廣播到所有的 primary shard 或 replica shard。每個(gè)分片在本地執(zhí)行搜索并構(gòu)建一個(gè)匹配文檔的大小為 from + size 的優(yōu)先隊(duì)列。每個(gè)分片返回各自優(yōu)先隊(duì)列中 所有文檔的 ID 和排序值 給協(xié)調(diào)節(jié)點(diǎn),由協(xié)調(diào)節(jié)點(diǎn)及逆行數(shù)據(jù)的合并、排序、分頁(yè)等操作,產(chǎn)出最終結(jié)果。

          2、Fetch階段:

          協(xié)調(diào)節(jié)點(diǎn)根據(jù) doc id 去各個(gè)節(jié)點(diǎn)上查詢實(shí)際的 document 數(shù)據(jù),由協(xié)調(diào)節(jié)點(diǎn)返回結(jié)果給客戶端。

          • coordinate node 對(duì) doc id 進(jìn)行哈希路由,將請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的 node,此時(shí)會(huì)使用 round-robin 隨機(jī)輪詢算法,在 primary shard 以及其所有 replica 中隨機(jī)選擇一個(gè),讓讀請(qǐng)求負(fù)載均衡。

          • 接收請(qǐng)求的 node 返回 document 給 coordinate node 。

          • coordinate node 返回 document 給客戶端。

          Query Then Fetch 的搜索類型在文檔相關(guān)性打分的時(shí)候參考的是本分片的數(shù)據(jù),這樣在文檔數(shù)量較少的時(shí)候可能不夠準(zhǔn)確,DFS Query Then Fetch 增加了一個(gè)預(yù)查詢的處理,詢問 Term 和 Document frequency,這個(gè)評(píng)分更準(zhǔn)確,但是性能會(huì)變差。 

          五、ES在高并發(fā)下如何保證讀寫一致性?

          (1)對(duì)于更新操作:可以通過版本號(hào)使用樂觀并發(fā)控制,以確保新版本不會(huì)被舊版本覆蓋

          每個(gè)文檔都有一個(gè)_version 版本號(hào),這個(gè)版本號(hào)在文檔被改變時(shí)加一。Elasticsearch使用這個(gè) _version 保證所有修改都被正確排序。當(dāng)一個(gè)舊版本出現(xiàn)在新版本之后,它會(huì)被簡(jiǎn)單的忽略。

          利用_version的這一優(yōu)點(diǎn)確保數(shù)據(jù)不會(huì)因?yàn)樾薷臎_突而丟失。比如指定文檔的version來做更改。如果那個(gè)版本號(hào)不是現(xiàn)在的,我們的請(qǐng)求就失敗了。

          (2)對(duì)于寫操作,一致性級(jí)別支持 quorum/one/all,默認(rèn)為 quorum,即只有當(dāng)大多數(shù)分片可用時(shí)才允許寫操作。但即使大多數(shù)可用,也可能存在因?yàn)榫W(wǎng)絡(luò)等原因?qū)е聦懭敫北臼?,這樣該副本被認(rèn)為故障,分片將會(huì)在一個(gè)不同的節(jié)點(diǎn)上重建。

          • one:要求我們這個(gè)寫操作,只要有一個(gè)primary shard是active活躍可用的,就可以執(zhí)行

          • all:要求我們這個(gè)寫操作,必須所有的primary shard和replica shard都是活躍的,才可以執(zhí)行這個(gè)寫操作

          • quorum:默認(rèn)的值,要求所有的shard中,必須是大部分的shard都是活躍的,可用的,才可以執(zhí)行這個(gè)寫操作

          (3)對(duì)于讀操作,可以設(shè)置 replication 為 sync(默認(rèn)),這使得操作在主分片和副本分片都完成后才會(huì)返回;如果設(shè)置replication 為 async 時(shí),也可以通過設(shè)置搜索請(qǐng)求參數(shù) _preference 為 primary 來查詢主分片,確保文檔是最新版本。 

          六、ES如何選舉Master節(jié)點(diǎn):

          1、Elasticsearch 的分布式原理:

          Elasticsearch 會(huì)對(duì)存儲(chǔ)的數(shù)據(jù)進(jìn)行切分,將數(shù)據(jù)劃分到不同的分片上,同時(shí)每一個(gè)分片會(huì)保存多個(gè)副本,主要是為了保證分布式環(huán)境的高可用。在 Elasticsearch 中,節(jié)點(diǎn)是對(duì)等的,節(jié)點(diǎn)間會(huì)選取集群的 Master,由 Master 會(huì)負(fù)責(zé)集群狀態(tài)信息的改變,并同步給其他節(jié)點(diǎn)。

          Elasticsearch 的性能會(huì)不會(huì)很低:只有建立索引和類型需要經(jīng)過 Master,數(shù)據(jù)的寫入有一個(gè)簡(jiǎn)單的 Routing 規(guī)則,可以路由到集群中的任意節(jié)點(diǎn),所以數(shù)據(jù)寫入壓力是分散在整個(gè)集群的。

          2、Elasticsearch 如何 選舉 Master:

          Elasticsearch 的選主是 ZenDiscovery 模塊負(fù)責(zé)的,主要包含Ping(節(jié)點(diǎn)之間通過這個(gè)RPC來發(fā)現(xiàn)彼此)和 Unicast(單播模塊包含一個(gè)主機(jī)列表以控制哪些節(jié)點(diǎn)需要ping通)這兩部分;

          • (1)確認(rèn)候選主節(jié)點(diǎn)的最少投票通過數(shù)量,elasticsearch.yml 設(shè)置的值 discovery.zen.minimum_master_nodes;

          • (2)對(duì)所有候選 master 的節(jié)點(diǎn)(node.master: true)根據(jù) nodeId 字典排序,每次選舉每個(gè)節(jié)點(diǎn)都把自己所知道節(jié)點(diǎn)排一次序,然后選出第一個(gè)(第0位)節(jié)點(diǎn),暫且認(rèn)為它是master節(jié)點(diǎn)。

          • (3)如果對(duì)某個(gè)節(jié)點(diǎn)的投票數(shù)達(dá)到閾值,并且該節(jié)點(diǎn)自己也選舉自己,那這個(gè)節(jié)點(diǎn)就是master。否則重新選舉一直到滿足上述條件。

          補(bǔ)充:master節(jié)點(diǎn)的職責(zé)主要包括集群、節(jié)點(diǎn)和索引的管理,不負(fù)責(zé)文檔級(jí)別的管理;data節(jié)點(diǎn)可以關(guān)閉http功能。

          3、Elasticsearch是如何避免腦裂現(xiàn)象:

          (1)當(dāng)集群中 master 候選節(jié)點(diǎn)數(shù)量不小于3個(gè)時(shí)(node.master: true),可以通過設(shè)置最少投票通過數(shù)量(discovery.zen.minimum_master_nodes),設(shè)置超過所有候選節(jié)點(diǎn)一半以上來解決腦裂問題,即設(shè)置為 (N/2)+1;

          (2)當(dāng)集群 master 候選節(jié)點(diǎn) 只有兩個(gè)時(shí),這種情況是不合理的,最好把另外一個(gè)node.master改成false。如果我們不改節(jié)點(diǎn)設(shè)置,還是套上面的(N/2)+1公式,此時(shí)discovery.zen.minimum_master_nodes應(yīng)該設(shè)置為2。這就出現(xiàn)一個(gè)問題,兩個(gè)master備選節(jié)點(diǎn),只要有一個(gè)掛,就選不出master了

          七、建立索引階段性能提升方法:

          • (1)使用 SSD 存儲(chǔ)介質(zhì)

          • (2)使用批量請(qǐng)求并調(diào)整其大?。好看闻繑?shù)據(jù) 5–15 MB 大是個(gè)不錯(cuò)的起始點(diǎn)。

          • (3)如果你在做大批量導(dǎo)入,考慮通過設(shè)置 index.number_of_replicas: 0 關(guān)閉副本

          • (4)如果你的搜索結(jié)果不需要近實(shí)時(shí)的準(zhǔn)確度,考慮把每個(gè)索引的 index.refresh_interval 改到30s

          • (5)段和合并:Elasticsearch 默認(rèn)值是 20 MB/s。但如果用的是 SSD,可以考慮提高到 100–200 MB/s。如果你在做批量導(dǎo)入,完全不在意搜索,你可以徹底關(guān)掉合并限流。

          • (6)增加 index.translog.flush_threshold_size 設(shè)置,從默認(rèn)的 512 MB 到更大一些的值,比如 1 GB 

          八、ES的深度分頁(yè)與滾動(dòng)搜索scroll

          (1)深度分頁(yè):

          深度分頁(yè)其實(shí)就是搜索的深淺度,比如第1頁(yè),第2頁(yè),第10頁(yè),第20頁(yè),是比較淺的;第10000頁(yè),第20000頁(yè)就是很深了。搜索得太深,就會(huì)造成性能問題,會(huì)耗費(fèi)內(nèi)存和占用cpu。而且es為了性能,他不支持超過一萬條數(shù)據(jù)以上的分頁(yè)查詢。那么如何解決深度分頁(yè)帶來的問題,我們應(yīng)該避免深度分頁(yè)操作(限制分頁(yè)頁(yè)數(shù)),比如最多只能提供100頁(yè)的展示,從第101頁(yè)開始就沒了,畢竟用戶也不會(huì)搜的那么深。

          (2)滾動(dòng)搜索:

          一次性查詢1萬+數(shù)據(jù),往往會(huì)造成性能影響,因?yàn)閿?shù)據(jù)量太多了。這個(gè)時(shí)候可以使用滾動(dòng)搜索,也就是 scroll。滾動(dòng)搜索可以先查詢出一些數(shù)據(jù),然后再緊接著依次往下查詢。在第一次查詢的時(shí)候會(huì)有一個(gè)滾動(dòng)id,相當(dāng)于一個(gè)錨標(biāo)記 ,隨后再次滾動(dòng)搜索會(huì)需要上一次搜索滾動(dòng)id,根據(jù)這個(gè)進(jìn)行下一次的搜索請(qǐng)求。每次搜索都是基于一個(gè)歷史的數(shù)據(jù)快照,查詢數(shù)據(jù)的期間,如果有數(shù)據(jù)變更,那么和搜索是沒有關(guān)系的。


          版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。

          本文鏈接:

          https://blog.csdn.net/a745233700/article/details/115585342









          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线看一区二区三区四区 | 又大又黄又爽 | 深爱草逼网 | 久久久久三级 | 9.1豆花免费网站亚洲天堂 |