<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 面試 4 連炮,你頂?shù)米∶矗?/h1>

          共 4713字,需瀏覽 10分鐘

           ·

          2021-01-29 11:24


          作者 |?kevin0016

          來源 |?https://www.jianshu.com/p/d6fd7e8cf220

          面試題

          es 寫入數(shù)據(jù)的工作原理是什么啊?es 查詢數(shù)據(jù)的工作原理是什么???底層的 lucene 介紹一下唄?倒排索引了解嗎?

          面試官心理分析

          問這個(gè),其實(shí)面試官就是要看看你了解不了解 es 的一些基本原理,因?yàn)橛?es 無非就是寫入數(shù)據(jù),搜索數(shù)據(jù)。你要是不明白你發(fā)起一個(gè)寫入和搜索請(qǐng)求的時(shí)候,es 在干什么,那你真的是......

          對(duì) es 基本就是個(gè)黑盒,你還能干啥?你唯一能干的就是用 es 的 api 讀寫數(shù)據(jù)了。要是出點(diǎn)什么問題,你啥都不知道,那還能指望你什么呢?

          面試題剖析

          es 寫數(shù)據(jù)過程

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

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

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

          • coordinating node?如果發(fā)現(xiàn)?primary node?和所有?replica node?都搞定之后,就返回響應(yīng)結(jié)果給客戶端。

          因女友的一句話,他做了個(gè)10億美元的App!網(wǎng)友評(píng):萬事俱備,就差個(gè)女友了~

          es 讀數(shù)據(jù)過程

          可以通過?doc id?來查詢,會(huì)根據(jù)?doc id?進(jìn)行 hash,判斷出來當(dāng)時(shí)把?doc id?分配到了哪個(gè) shard 上面去,從那個(gè) shard 去查詢。

          • 客戶端發(fā)送請(qǐng)求到任意一個(gè) node,成為?coordinate node。
          • 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 給客戶端。

          es 搜索數(shù)據(jù)過程

          es 最強(qiáng)大的是做全文檢索,就是比如你有三條數(shù)據(jù):

          java真好玩兒啊
          java好難學(xué)啊
          j2ee特別牛

          你根據(jù)?java?關(guān)鍵詞來搜索,將包含?java的?document?給搜索出來。es 就會(huì)給你返回:java真好玩兒啊,java好難學(xué)啊。

          • 客戶端發(fā)送請(qǐng)求到一個(gè)?coordinate node。
          • 協(xié)調(diào)節(jié)點(diǎn)將搜索請(qǐng)求轉(zhuǎn)發(fā)到所有的 shard 對(duì)應(yīng)的?primary shard?或?replica shard,都可以。
          • query phase:每個(gè) shard 將自己的搜索結(jié)果(其實(shí)就是一些?doc id)返回給協(xié)調(diào)節(jié)點(diǎn),由協(xié)調(diào)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)的合并、排序、分頁等操作,產(chǎn)出最終結(jié)果。
          • fetch phase:接著由協(xié)調(diào)節(jié)點(diǎn)根據(jù)?doc id?去各個(gè)節(jié)點(diǎn)上拉取實(shí)際的?document?數(shù)據(jù),最終返回給客戶端。

          寫數(shù)據(jù)底層原理

          曾經(jīng)風(fēng)光無限的鐵飯碗沒了...網(wǎng)友評(píng)論:996卷走了955的他們...

          先寫入內(nèi)存 buffer,在 buffer 里的時(shí)候數(shù)據(jù)是搜索不到的;同時(shí)將數(shù)據(jù)寫入 translog 日志文件。

          如果 buffer 快滿了,或者到一定時(shí)間,就會(huì)將內(nèi)存 buffer 數(shù)據(jù)?refresh?到一個(gè)新的?segment file?中,但是此時(shí)數(shù)據(jù)不是直接進(jìn)入?segment file?磁盤文件,而是先進(jìn)入?os cache?。這個(gè)過程就是?refresh。

          每隔 1 秒鐘,es 將 buffer 中的數(shù)據(jù)寫入一個(gè)新的?segment file,每秒鐘會(huì)產(chǎn)生一個(gè)新的磁盤文件?segment file,這個(gè)?segment file?中就存儲(chǔ)最近 1 秒內(nèi) buffer 中寫入的數(shù)據(jù)。

          但是如果 buffer 里面此時(shí)沒有數(shù)據(jù),那當(dāng)然不會(huì)執(zhí)行 refresh 操作,如果buffer里面有數(shù)據(jù),默認(rèn) 1 秒鐘執(zhí)行一次 refresh 操作,刷入一個(gè)新的 segment file 中。

          操作系統(tǒng)里面,磁盤文件其實(shí)都有一個(gè)東西,叫做?os cache,即操作系統(tǒng)緩存,就是說數(shù)據(jù)寫入磁盤文件之前,會(huì)先進(jìn)入?os cache,先進(jìn)入操作系統(tǒng)級(jí)別的一個(gè)內(nèi)存緩存中去。只要?buffer?中的數(shù)據(jù)被 refresh 操作刷入?os cache中,這個(gè)數(shù)據(jù)就可以被搜索到了。

          為什么叫 es 是準(zhǔn)實(shí)時(shí)的??NRT,全稱?near real-time。默認(rèn)是每隔 1 秒 refresh 一次的,所以 es 是準(zhǔn)實(shí)時(shí)的,因?yàn)閷懭氲臄?shù)據(jù) 1 秒之后才能被看到。可以通過 es 的?restful api?或者?java api,手動(dòng)執(zhí)行一次 refresh 操作,就是手動(dòng)將 buffer 中的數(shù)據(jù)刷入?os cache中,讓數(shù)據(jù)立馬就可以被搜索到。只要數(shù)據(jù)被輸入?os cache?中,buffer 就會(huì)被清空了,因?yàn)椴恍枰A?buffer 了,數(shù)據(jù)在 translog 里面已經(jīng)持久化到磁盤去一份了。

          重復(fù)上面的步驟,新的數(shù)據(jù)不斷進(jìn)入 buffer 和 translog,不斷將?buffer?數(shù)據(jù)寫入一個(gè)又一個(gè)新的?segment file?中去,每次?refresh?完 buffer 清空,translog保留。隨著這個(gè)過程推進(jìn),translog 會(huì)變得越來越大。當(dāng) translog 達(dá)到一定長度的時(shí)候,就會(huì)觸發(fā)?commit?操作。

          commit 操作發(fā)生第一步,就是將 buffer 中現(xiàn)有數(shù)據(jù)?refresh?到?os cache?中去,清空 buffer。然后,將一個(gè)?commit point?寫入磁盤文件,里面標(biāo)識(shí)著這個(gè)?commit point?對(duì)應(yīng)的所有?segment file,同時(shí)強(qiáng)行將?os cache?中目前所有的數(shù)據(jù)都?fsync?到磁盤文件中去。最后清空?現(xiàn)有 translog 日志文件,重啟一個(gè) translog,此時(shí) commit 操作完成。

          這個(gè) commit 操作叫做?flush。默認(rèn) 30 分鐘自動(dòng)執(zhí)行一次?flush,但如果 translog 過大,也會(huì)觸發(fā)?flush。flush 操作就對(duì)應(yīng)著 commit 的全過程,我們可以通過 es api,手動(dòng)執(zhí)行 flush 操作,手動(dòng)將 os cache 中的數(shù)據(jù) fsync 強(qiáng)刷到磁盤上去。

          translog 日志文件的作用是什么?你執(zhí)行 commit 操作之前,數(shù)據(jù)要么是停留在 buffer 中,要么是停留在 os cache 中,無論是 buffer 還是 os cache 都是內(nèi)存,一旦這臺(tái)機(jī)器死了,內(nèi)存中的數(shù)據(jù)就全丟了。所以需要將數(shù)據(jù)對(duì)應(yīng)的操作寫入一個(gè)專門的日志文件?translog?中,一旦此時(shí)機(jī)器宕機(jī),再次重啟的時(shí)候,es 會(huì)自動(dòng)讀取 translog 日志文件中的數(shù)據(jù),恢復(fù)到內(nèi)存 buffer 和 os cache 中去。

          translog 其實(shí)也是先寫入 os cache 的,默認(rèn)每隔 5 秒刷一次到磁盤中去,所以默認(rèn)情況下,可能有 5 秒的數(shù)據(jù)會(huì)僅僅停留在 buffer 或者 translog 文件的 os cache 中,如果此時(shí)機(jī)器掛了,會(huì)丟失?5 秒鐘的數(shù)據(jù)。但是這樣性能比較好,最多丟 5 秒的數(shù)據(jù)。也可以將 translog 設(shè)置成每次寫操作必須是直接?fsync?到磁盤,但是性能會(huì)差很多。

          實(shí)際上你在這里,如果面試官?zèng)]有問你 es 丟數(shù)據(jù)的問題,你可以在這里給面試官炫一把,你說,其實(shí) es 第一是準(zhǔn)實(shí)時(shí)的,數(shù)據(jù)寫入 1 秒后可以搜索到;可能會(huì)丟失數(shù)據(jù)的。有 5 秒的數(shù)據(jù),停留在 buffer、translog os cache、segment file os cache 中,而不在磁盤上,此時(shí)如果宕機(jī),會(huì)導(dǎo)致 5 秒的數(shù)據(jù)丟失。

          數(shù)據(jù)寫入 segment file 之后,同時(shí)就建立好了倒排索引。

          刪除/更新數(shù)據(jù)底層原理

          如果是刪除操作,commit 的時(shí)候會(huì)生成一個(gè)?.del?文件,里面將某個(gè) doc 標(biāo)識(shí)為?deleted?狀態(tài),那么搜索的時(shí)候根據(jù)?.del?文件就知道這個(gè) doc 是否被刪除了。

          如果是更新操作,就是將原來的 doc 標(biāo)識(shí)為?deleted?狀態(tài),然后新寫入一條數(shù)據(jù)。

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

          底層 lucene

          簡單來說,lucene 就是一個(gè) jar 包,里面包含了封裝好的各種建立倒排索引的算法代碼。我們用 Java 開發(fā)的時(shí)候,引入 lucene jar,然后基于 lucene 的 api 去開發(fā)就可以了。

          通過 lucene,我們可以將已有的數(shù)據(jù)建立索引,lucene 會(huì)在本地磁盤上面,給我們組織索引的數(shù)據(jù)結(jié)構(gòu)。

          倒排索引

          在搜索引擎中,每個(gè)文檔都有一個(gè)對(duì)應(yīng)的文檔 ID,文檔內(nèi)容被表示為一系列關(guān)鍵詞的集合。例如,文檔 1 經(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)鍵詞。

          舉個(gè)栗子。

          有以下文檔:

          DocIdDoc
          1谷歌地圖之父跳槽 Facebook
          2谷歌地圖之父加盟 Facebook
          3谷歌地圖創(chuàng)始人拉斯離開谷歌加盟 Facebook
          4谷歌地圖之父跳槽 Facebook 與 Wave 項(xiàng)目取消有關(guān)
          5谷歌地圖之父拉斯加盟社交網(wǎng)站 Facebook

          對(duì)文檔進(jìn)行分詞之后,得到以下倒排索引

          WordIdWordDocIds
          1谷歌1,2,3,4,5
          2地圖1,2,3,4,5
          3之父1,2,4,5
          4跳槽1,4
          5Facebook1,2,3,4,5
          6加盟2,3,5
          7創(chuàng)始人3
          8拉斯3,5
          9離開3
          104
          ......

          另外,實(shí)用的倒排索引還可以記錄更多的信息,比如文檔頻率信息,表示在文檔集合中有多少個(gè)文檔包含某個(gè)單詞。

          那么,有了倒排索引,搜索引擎可以很方便地響應(yīng)用戶的查詢。比如用戶輸入查詢?Facebook,搜索系統(tǒng)查找倒排索引,從中讀出包含這個(gè)單詞的文檔,這些文檔就是提供給用戶的搜索結(jié)果。

          往期推薦

          因女友的一句話,他做了個(gè)10億美元的App!網(wǎng)友評(píng):萬事俱備,就差個(gè)女友了~

          曾經(jīng)風(fēng)光無限的鐵飯碗沒了...網(wǎng)友評(píng)論:996卷走了955的他們...

          為什么漢字不能當(dāng)密碼,假如用漢字做密碼,又會(huì)怎樣?

          日本政府用AI分配對(duì)象了!給你分一個(gè)的話,敢不敢要?

          AWS回應(yīng)Elastic修改開源協(xié)議:創(chuàng)建“真正”開源的Elasticsearch分支



          瀏覽 65
          點(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>
                  搞黄视频网站无码动漫 | 国产精品久久久久夜色 | 久久久91精品国产一区苍井空 | 青娱乐青青草视频在线观看 | 一级A片免费视频 |