2021-Java後端工程師面試指南-(Elasticsearch)

2021-02-23 六脈神劍的程序人生
前言

文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/bin392328206/six-finger
種一棵樹最好的時間是十年前,其次是現在

Tips

面試指南系列,很多情況下不會去深挖細節,是小六六以被面試者的角色去回顧知識的一種方式,所以我默認大部分的東西,作為面試官的你,肯定是懂的。

https://www.processon.com/view/link/600ed9e9637689349038b0e4

上面的是腦圖地址

叨絮

今天來看看Elasticsearch然後下面是前面的文章匯總

2021-Java後端工程師面試指南-(Java基礎篇)2021-Java後端工程師面試指南-(並發-多線程)2021-Java後端工程師面試指南-(MySQL)2021-Java後端工程師面試指南-(Redis)

Es其實用的很多,而且如果體量大點的話,基本上都需要使用到它,所以掌握它還是很有必要的,那麼我們來一起看看吧

說說什麼是ElasticsearchElasticsearch,基於lucene.分布式的Restful實時搜索和分析引擎(實時)高擴展性,可擴展至上百臺伺服器,處理PB級結構化或非結構化數據Elasticsearch用於全文檢索,結構化搜索,分析/合併使用聊聊Elasticsearch的特性:Elasticsearch沒有典型意義的事務(無事務性)什麼是全文檢索和Lucene?

全文檢索,倒排索引

全文檢索是指計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現的次數和位置,當用戶查詢時,檢索程序就根據事先建立的索引進行查找,並將查找的結果反饋給用戶的檢索方式。這個過程類似於通過字典中的檢索字表查字的過程。全文搜索搜尋引擎資料庫中的數據。

lucenelucene,就是一個jar包,裡面包含了封裝好的各種建立倒排索引,以及進行搜索的代碼,包括各種算法。我們就用java開發的時候,引入lucene jar,然後基於lucene的api進行去進行開發就可以了。

那你聊聊Elasticsearch的核心概念,就是我們經常用的那些。

近實時近實時,兩個意思,從寫入數據到數據可以被搜索到有一個小延遲(大概1秒);基於es執行搜索和分析可以達到秒級。

Cluster(集群)集群包含多個節點,每個節點屬於哪個集群是通過一個配置(集群名稱,默認是elasticsearch)來決定的,對於中小型應用來說,剛開始一個集群就一個節點很正常

Node(節點)

集群中的一個節點,節點也有一個名稱(默認是隨機分配的),節點名稱很重要(在執行運維管理操作的時候),默認節點會去加入一個名稱為「elasticsearch」的集群,如果直接啟動一堆節點,那麼它們會自動組成一個elasticsearch集群,當然一個節點也可以組成一個elasticsearch集群。

Index(索引-資料庫)索引包含一堆有相似結構的文檔數據,比如可以有一個客戶索引,商品分類索引,訂單索引,索引有一個名稱。一個index包含很多document,一個index就代表了一類類似的或者相同的document。比如說建立一個product     index,商品索引,裡面可能就存放了所有的商品數據,所有的商品document。

Type(類型-表)每個索引裡都可以有一個或多個type,type是index中的一個邏輯數據分類,一個type下的document,都有相同的field,比如博客系統,有一個索引,可以定義用戶數據type,博客數據type,評論數據type。

Document(文檔-行)文檔是es中的最小數據單元,一個document可以是一條客戶數據,一條商品分類數據,一條訂單數據,通常用JSON數據結構表示,每個index下的type中,都可以去存儲多個document。

Field(欄位-列)Field是Elasticsearch的最小單位。一個document裡面有多個field,每個field就是一個數據欄位。

shard單臺機器無法存儲大量數據,es可以將一個索引中的數據切分為多個shard,分布在多臺伺服器上存儲。有了shard就可以橫向擴展,存儲更多數據,讓搜索和分析等操作分布到多臺伺服器上去執行,提升吞吐量和性能。每個shard都是一個lucene index。

replica任何一個伺服器隨時可能故障或宕機,此時shard可能就會丟失,因此可以為每個shard創建多個replica副本。replica可以在shard故障時提供備用服務,保證數據不丟失,多個replica還可以提升搜索操作的吞吐量和性能。primary shard(建立索引時一次設置,不能修改,默認5個),replica shard(隨時修改數量,默認1個),默認每個索引10個shard,5個primary shard,5個replica shard,最小的高可用配置,是2臺伺服器。

說說Elasticsearch樂觀並發控制

Elasticsearch是分布式的。當文檔被創建、更新或刪除,文檔的新版本會被複製到集群的其它節點。Elasticsearch即是同步的又是異步的,意思是這些複製請求都是平行發送的,並無序(out of sequence)的到達目的地。這就需要一種方法確保老版本的文檔永遠不會覆蓋新的版本。上文我們提到index、get、delete請求時,我們指出每個文檔都有一個_version號碼,這個號碼在文檔被改變時加一。Elasticsearch使用這個_version保證所有修改都被正確排序。當一個舊版本出現在新版本之後,它會被簡單的忽略。我們利用_version的這一優點確保數據不會因為修改衝突而丟失。我們可以指定文檔的version來做想要的更改。如果那個版本號不是現在的,我們的請求就失敗了。用version 來保證並發的順序一致性

聊聊text,keyword類型的區別text:當一個欄位是要被全文搜索的,比如Email內容、產品描述,應該使用text類型。設置text類型以後,欄位內容會被分析,在生成倒排索引以前,字符串會被分析器分成一個一個詞項。text類型的欄位不用於排序,很少用於聚合。keyword:keyword類型適用於索引結構化的欄位,比如email地址、主機名、狀態碼和標籤。如果欄位需要進行過濾(比如查找已發布博客中status屬性為published的文章)、排序、聚合。keyword類型的欄位只能通過精確值搜索到。那你說說查詢api返回的主要包含什麼東西

hits響應中最重要的部分是hits,它包含了total欄位來表示匹配到的文檔總數,hits數組還包含了匹配到的前10條數據。hits數組中的每個結果都包含_index、_type和文檔的_id欄位,被加入到_source欄位中這意味著在搜索結果中我們將可以直接使用全部文檔。這不像其他搜尋引擎只返回文檔ID,需要你單獨去獲取文檔。每個節點都有一個_score欄位,這是相關性得分(relevance score),它衡量了文檔與查詢的匹配程度。默認的,返回的結果中關聯性最大的文檔排在首位;這意味著,它是按照_score降序排列的。這種情況下,我們沒有指定任何查詢,所以所有文檔的相關性是一樣的,因此所有結果的_score都是取得一個中間值1max_score指的是所有文檔匹配查詢中_score的最大值。

tooktook告訴我們整個搜索請求花費的毫秒數。

shards_shards節點告訴我們參與查詢的分片數(total欄位),有多少是成功的(successful欄位),有多少的是失敗的(failed欄位)。通常我們不希望分片失敗,不過這個有可能發生。如果我們遭受一些重大的故障導致主分片和複製分片都故障,那這個分片的數據將無法響應給搜索請求。這種情況下,Elasticsearch將報告分片failed,但仍將繼續返回剩餘分片上的結果。

timeout

time_out值告訴我們查詢超時與否。一般的,搜索請求不會超時。如果響應速度比完整的結果更重要,你可以定義timeout參數為10或者10ms(10毫秒),或者1s(1秒)

聊聊shard&replica機制每個shard都是一個最小工作單元,承載部分數據,lucene實例,完整的建立索引和處理請求的能力增減節點時,shard會自動在nodes中負載均衡primary shard和replica shard,每個document肯定只存在於某一個primary shard以及其對應的replica shard中,不可能存在於多個primary shardreplica shard是primary shard的副本,負責容錯,以及承擔讀請求負載primary shard的數量在創建索引的時候就固定了,replica shard的數量可以隨時修改primary shard的默認數量是5,replica默認是1,默認有10個shard,5個primary shard,5個replica shardprimary shard不能和自己的replica shard放在同一個節點上(否則節點宕機,primary shard和副本都丟失,起不到容錯的作用),但是可以和其他primary shard的replica shard放在同一個節點上ES是如何實現master選舉的?

前置條件:

只有是候選主節點(master:true)的節點才能成為主節點。最小主節點數(min_master_nodes)的目的是防止腦裂。

Elasticsearch 的選主是 ZenDiscovery 模塊負責的,主要包含 Ping(節點之間通過這個RPC來發現彼此)和 Unicast(單播模塊包含一個主機列表以控制哪些節點需要 ping 通)這兩部分;獲取主節點的核心入口為 findMaster,選擇主節點成功返回對應 Master,否則返回 null。

選舉流程大致描述如下:

第一步:確認候選主節點數達標,elasticsearch.yml 設置的值 discovery.zen.minimum_master_nodes;第二步:對所有候選主節點根據nodeId字典排序,每次選舉每個節點都把自己所知道節點排一次序,然後選出第一個(第0位)節點,暫且認為它是master節點。第三步:如果對某個節點的投票數達到一定的值(候選主節點數n/2+1)並且該節點自己也選舉自己,那這個節點就是master。否則重新選舉一直到滿足上述條件。如何解決ES集群的腦裂問題

所謂集群腦裂,是指 Elasticsearch 集群中的節點(比如共 20 個),其中的 10 個選了一個 master,另外 10 個選了另一個 master 的情況。

當集群 master 候選數量不小於 3 個時,可以通過設置最少投票通過數量(discovery.zen.minimum_master_nodes)超過所有候選節點一半以上來解決腦裂問題;當候選數量為兩個時,只能修改為唯一的一個 master 候選,其他作為 data 節點,避免腦裂問題。

聊聊es的寫入流程

Elasticsearch採用多Shard方式,通過配置routing規則將數據分成多個數據子集,每個數據子集提供獨立的索引和搜索功能。當寫入文檔的時候,根據routing規則,將文檔發送給特定Shard中建立索引。這樣就能實現分布式了。

每個Index由多個Shard組成(默認是5個),每個Shard有一個主節點和多個副本節點,副本個數可配。但每次寫入的時候,寫入請求會先根據_routing規則選擇發給哪個Shard,Index Request中可以設置使用哪個Filed的值作為路由參數,如果沒有設置,則使用Mapping中的配置,如果mapping中也沒有配置,則使用_id作為路由參數,然後通過_routing的Hash值選擇出Shard(在OperationRouting類中),最後從集群的Meta中找出出該Shard的Primary節點。

請求接著會發送給Primary Shard,在Primary Shard上執行成功後,再從Primary Shard上將請求同時發送給多個Replica Shard,請求在多個Replica Shard上執行成功並返回給Primary Shard後,寫入請求執行成功,返回結果給客戶端。

那你說說具體在 shard上的寫入流程唄

在每一個Shard中,寫入流程分為兩部分,先寫入Lucene,再寫入TransLog。

寫入請求到達Shard後,先寫Lucene文件,創建好索引,此時索引還在內存裡面,接著去寫TransLog,寫完TransLog後,刷新TransLog數據到磁碟上,寫磁碟成功後,請求返回給用戶。這裡有幾個關鍵點:

和資料庫不同,資料庫是先寫CommitLog,然後再寫內存,而Elasticsearch是先寫內存,最後才寫TransLog,一種可能的原因是Lucene的內存寫入會有很複雜的邏輯,很容易失敗,比如分詞,欄位長度超過限制等,比較重,為了避免TransLog中有大量無效記錄,減少recover的複雜度和提高速度,所以就把寫Lucene放在了最前面。

寫Lucene內存後,並不是可被搜索的,需要通過Refresh把內存的對象轉成完整的Segment後,然後再次reopen後才能被搜索,一般這個時間設置為1秒鐘,導致寫入Elasticsearch的文檔,最快要1秒鐘才可被從搜索到,所以Elasticsearch在搜索方面是NRT(Near Real Time)近實時的系統。

每隔一段比較長的時間,比如30分鐘後,Lucene會把內存中生成的新Segment刷新到磁碟上,刷新後索引文件已經持久化了,歷史的TransLog就沒用了,會清空掉舊的TransLog。

Lucene緩存中的數據默認1秒之後才生成segment文件,即使是生成了segment文件,這個segment是寫到頁面緩存中的,並不是實時的寫到磁碟,只有達到一定時間或者達到一定的量才會強制flush磁碟。如果這期間機器宕掉,內存中的數據就丟了。如果發生這種情況,內存中的數據是可以從TransLog中進行恢復的,TransLog默認是每5秒都會刷新一次磁碟。但這依然不能保證數據安全,因為仍然有可能最多丟失TransLog中5秒的數據。這裡可以通過配置增加TransLog刷磁碟的頻率來增加數據可靠性,最小可配置100ms,但不建議這麼做,因為這會對性能有非常大的影響。一般情況下,Elasticsearch是通過副本機制來解決這一問題的。即使主分片所在節點宕機,丟失了5秒數據,依然是可以通過副本來進行恢復的。

總結一下,數據先寫入內存 buffer,然後每隔 1s,將數據 refresh 到 os cache,到了 os cache 數據就能被搜索到(所以我們才說 es 從寫入到能被搜索到,中間有 1s 的延遲)。每隔 5s,將數據寫入 translog 文件(這樣如果機器宕機,內存數據全沒,最多會有 5s 的數據丟失),translog 大到一定程度,或者默認每隔 30mins,會觸發 commit 操作,將緩衝區的數據都 flush 到 segment file 磁碟文件中。

說說es的更新流程吧

Lucene中不支持部分欄位的Update,所以需要在Elasticsearch中實現該功能,具體流程如下:

到Update請求後,從Segment或者TransLog中讀取同id的完整Doc,記錄版本號為V1。將版本V1的全量Doc和請求中的部分欄位Doc合併為一個完整的Doc,同時更新內存中的VersionMap。獲取到完整Doc後,Update請求就變成了Index請求。再次從versionMap中讀取該id的最大版本號V2,如果versionMap中沒有,則從Segment或者TransLog中讀取,這裡基本都會從versionMap中獲取到。檢查版本是否衝突(V1==V2),如果衝突,則回退到開始的「Update doc」階段,重新執行。如果不衝突,則執行最新的Add請求。在Index Doc階段,首先將Version + 1得到V3,再將Doc加入到Lucene中去,Lucene中會先刪同id下的已存在doc id,然後再增加新Doc。寫入Lucene成功後,將當前V3更新到versionMap中。詳細描述一下ES搜索的過程?

搜索被執行成一個兩階段過程,即 Query Then Fetch;

Query階段:查詢會廣播到索引中每一個分片拷貝(主分片或者副本分片)。每個分片在本地執行搜索並構建一個匹配文檔的大小為 from + size 的優先隊列。PS:在搜索的時候是會查詢Filesystem Cache的,但是有部分數據還在Memory Buffer,所以搜索是近實時的。每個分片返回各自優先隊列中 所有文檔的 ID 和排序值 給協調節點,它合併這些值到自己的優先隊列中來產生一個全局排序後的結果列表。Fetch階段:協調節點辨別出哪些文檔需要被取回並向相關的分片提交多個 GET 請求。每個分片加載並 豐富 文檔,如果有需要的話,接著返回文檔給協調節點。一旦所有的文檔都被取回了,協調節點返回結果給客戶端。

說說es的寫一致性

我們在發送任何一個增刪改操作的時候,比如說put /index/type/id,都可以帶上一個consistency參數,指明我們想要的寫一致性是什麼?put /index/type/id?consistency=quorum

one:要求我們這個寫操作,只要有一個primary shard是active活躍可用的,就可以執行all:要求我們這個寫操作,必須所有的primary shard和replica shard都是活躍的,才可以執行這個寫操作quorum:默認的值,要求所有的shard中,必須是大部分的shard都是活躍的,可用的,才可以執行這個寫操作聊聊 elasticsearch 深度分頁以及scroll 滾動搜索

深度分頁深度分頁其實就是搜索的深淺度,比如第1頁,第2頁,第10頁,第20頁,是比較淺的;第10000頁,第20000頁就是很深了。搜索得太深,就會造成性能問題,會耗費內存和佔用cpu。而且es為了性能,他不支持超過一萬條數據以上的分頁查詢。那麼如何解決深度分頁帶來的問題,我們應該避免深度分頁操作(限制分頁頁數),比如最多只能提供100頁的展示,從第101頁開始就沒了,畢竟用戶也不會搜的那麼深,我們平時搜索淘寶或者京東也就看個10來頁就頂多了。

滾動搜索一次性查詢1萬+數據,往往會造成性能影響,因為數據量太多了。這個時候可以使用滾動搜索,也就是 scroll 。滾動搜索可以先查詢出一些數據,然後再緊接著依次往下查詢。在第一次查詢的時候會有一個滾動id,相當於一個錨標記 ,隨後再次滾動搜索會需要上一次搜索滾動id,根據這個進行下一次的搜索請求。每次搜索都是基於一個歷史的數據快照,查詢數據的期間,如果有數據變更,那麼和搜索是沒有關係的。

es在數據量很大的情況下如何提高性能

filesystem

es每次走fileSystem cache查詢速度是最快的所以將每個查詢的數據50% 容量= fileSystem cache 容量。

數據預熱數據預熱是指,每隔一段時間,將熱數據手動在後臺查詢一遍,將熱數據刷新到fileSystem cache上

冷熱分離類似於MySQL的分表分庫將熱數據單獨建立一個索引 分配3臺機器只保持熱機器的索引另外的機器保持冷數據的索引,但有一個問題,就是事先必須知道哪些是熱數據 哪些是冷數據

不可以深度分頁

跟產品經理說,你系統不允許翻那麼深的頁,默認翻的越深,性能就越差。

類似於 app 裡的推薦商品不斷下拉出來一頁一頁的類似於微博中,下拉刷微博,刷出來一頁一頁的,你可以用 scroll api

結束

es可能我自己用的也比較少,就用來做一些搜索,沒有用來做bi,所以呢?也不是那麼深入吧,希望對大家有幫助,接下來複習下隊列

日常求贊

好了各位,以上就是這篇文章的全部內容了,能看到這裡的人呀,都是真粉

創作不易,各位的支持和認可,就是我創作的最大動力,我們下篇文章見

微信 搜 "六脈神劍的程序人生" 回復888 有我找的許多的資料送給大家

相關焦點

  • 2021-Java後端工程師面試指南-(SpringBoot+SpringCloud)
    前言「文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/bin392328206/six-finger種一棵樹最好的時間是十年前,其次是現在」Tips面試指南系列,很多情況下不會去深挖細節,是小六六以被面試者的角色去回顧知識的一種方式,所以我默認大部分的東西,作為面試官的你,肯定是懂的
  • 《Elasticsearch 權威指南》中文版
    在幾十位社區同學的共同努力下,《Elasticsearch 權威指南》的翻譯工作接近尾聲,在線訪問連結如下:
  • 深入淺出 spring-data-elasticsearch 之 ElasticSearch 架構初探(一)
    1.2 集群(Cluster)、節點(Node)、分片(Shard)分布式三要素二、Elasticsearch 工作原理2.1 文檔存儲的路由2.2 如何健康檢查2.3 如何水平擴容三、小結一、Elasticsearch 基本術語1.1 文檔(Document)、索引(Index)、類型(Type)文檔三要素文檔
  • 一周拿下 Elastic 認證工程師考試?!你也可以
    2021 年春招臨近,企業肯定提前做足了準備,大廠的 Offer 就在哪裡,作為 Elastic 愛好者、從業者的你,準備好了嗎?!2018年 Elastic 官方推出了Elastic 認證考試,Elastic 官方對 Elastic 認證工程師的定位是:Elastic 認證工程師擁有構建完整的 Elasticsearch 解決方案的技能。
  • ElasticSearch
    - ES 7.x以後,將逐步移除type這個概念,現在的操作已經不再使用,默認_doc1.6 ik分詞器 • 分詞器(Analyzer):將一段文本,按照一定邏輯,分析成多個詞語的一種工具,ElasticSearch 內置分詞器對中文很不友好,處理方式為:一個字一個詞 • IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包,是一個基於Maven構建的項目
  • 全文搜尋引擎ElasticSearch入門教程
    $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip  $ unzip elasticsearch-5.5.1.zip  $ cd elasticsearch-5.5.1/  接著,進入解壓後的目錄,運行下面的命令,啟動 Elastic。
  • Elasticsearch Analyzer
    Elasticsearch內置了40+種分詞過濾器,這裡不再一一贅述。3 Specify the analyzer for a text fieldmapping analyzer參數可以為特定欄位設定分析器。一旦設定完畢,那麼在index或search階段將會使用該分析器進行文本分析。
  • Elasticsearch官方文檔離線訪問實操指南
    直接上個圖:不能讓 Elasticsearch 文檔限制了你我的學習熱情!2、直接開幹步驟1:訪問:https://zealdocs.org/步驟3:輸入elasticsearch 搜索下載官方文檔到本地。
  • Elastic 認證工程師考試最常被問到 Top10 +問題集錦
    參見官方:https://www.elastic.co/cn/training/elastic-certified-engineer-exam未來可能會改版,以官方公布為準。截止:2020年6月27日, Elastic 認證工程師(Elastic Certified Engineer)的考試版本是:7.2 。最新推出的 Elastic 分析工程師(Elastic Certified Analyst:)的考試版本是:7.6。
  • 淺談後端面試指南
    (點擊上方公眾號,可快速關注)來源:koala bear ,wsfdl.com/編程隨想/2016/09/09/淺談後端技術面試
  • Open Distro for Elasticsearch 1.1.0 發布,Elasticsearch 發行版
    Open Distro for Elasticsearch 是 AWS 開源的 Elasticsearch 發行版。可以 GitHub 存儲庫中的發行說明中找到有關增強、bug 修復和更多信息的詳細信息:https://github.com/opendistro-for-elasticsearch新特性此版本中提供一些新的插件,以便集成到開發者的應用程式中,雖然這些插件屬於 alpha 版本。
  • 搜尋引擎 Elasticsearch 中文擴展分詞器使用,更快更準確!
    Elasticsearch是一個基於Lucene,Lucene是開源的Java索引檢索組件。它提供了一個分布式多用戶能力的全文搜尋引擎,基於RESTful web接口。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜尋引擎。
  • ElasticSearch 億級數據檢索案例實戰!
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫來源:https://www.cnblogs.com/mikevictor07/p/10006553.html一、前言
  • Hadoop 讀寫 Elasticsearch
    使用Hadoop操作Elasticsearch的方法,關鍵是指定InputFormatClass : EsInputFormat.classOutputFormatClass: EsOutputFormat.class,這個好像是ES官方提供的集成包。網上查了相關資料貌似挺少的。
  • elasticsearch 八、重要的配置更改
    集群名稱改成elasticsearch_production,這麼一個簡單的修改可以避免很多的痛心。Elasticseach by default starts a cluster named elasticsearch.
  • 在elasticsearch中使用function_score查詢
    一、先看語法_search{  "query":{  "function_score":{  "query":{        "match_all":{}   },       "functions":[               {        "gauss":{
  • ElasticSearch-hard插件及IK分詞器安裝
    當然有了:elasticSeard-head這個插件就可以實現這個功能。我們先來看看使用插件後的效果:ElasticSearch-head是什麼?ElasticSearch-head:是集群管理、數據可視化、增刪改查、查詢語句可視化工具。
  • 這篇實戰攻略,帶你輕鬆入門Elastic search
    什麼是Elasticsearch,為什麼要使用它?Elasticsearch 是一個分布式、RESTful 風格的搜索和數據分析引擎。它基於Lunece實現,使用java語言編寫。Lunece是一個優秀的搜尋引擎庫,但它使用起來非常複雜。
  • 一次有趣的Elasticsearch+矩陣變換聚合實踐
    數據同步到Elasticsearch中,一個月一個索引,也只要更新最近的2個索引。Elasticsearch更新索引也很方便,採用別名切換方式,可在毫秒間完成,ES這個優點有效的避免了業務系統查詢停頓空白問題。
  • elasticsearch Discovery 發現模塊學習
    一、基於單播的方式發現可以在 elasticsearch.yml 配置文件中使用discovery.zen.ping.unicast.hosts靜態設置設置主機列表。discovery.zen.ping.unicast.hosts: ["host1", "host2"]具體的值是一個主機數組或逗號分隔的字符串。