搜索引擎面試題
題目和解答來自于中華石杉和自己整理總結(jié)而得,希望能夠有所幫助。
搜索引擎主要考察ElasticSearch 以及對(duì)應(yīng)底層的Lucene技術(shù)。
主要面試題集中于:
- es分布式架構(gòu)原理
- es的插入與查詢
- es在數(shù)據(jù)量很大的情況下如何提高性能
- es在生產(chǎn)集群的部署架構(gòu)是什么,每個(gè)索引有多大的數(shù)據(jù)量,每個(gè)索引有多少分片
1. es分布式架構(gòu)原理
首先需要明白es是如何存儲(chǔ)數(shù)據(jù)的,es把對(duì)應(yīng)的數(shù)據(jù)轉(zhuǎn)換為index。基于倒排索引的方式,每個(gè)index上存儲(chǔ)了多個(gè)type類型,每個(gè)type對(duì)應(yīng)一個(gè)document。而一個(gè)index會(huì)被分成多個(gè)shard(默認(rèn)是5個(gè))。
在分布式部署時(shí),每個(gè)shard會(huì)被復(fù)制,即一個(gè)shard有primary和replica 每個(gè)es進(jìn)程存儲(chǔ)的是不同shard的primary和replica。es集群多個(gè)節(jié)點(diǎn),會(huì)自動(dòng)選舉一個(gè)節(jié)點(diǎn)為master節(jié)點(diǎn),這個(gè)master節(jié)點(diǎn)其實(shí)就是干一些管理的工作的,比如維護(hù)索引元數(shù)據(jù)拉,負(fù)責(zé)切換primary shard和replica shard身份拉,之類的。
2. es的數(shù)據(jù)寫入與讀取
2.1 es數(shù)據(jù)的寫入
2.1.1 es數(shù)據(jù)的寫入過程
注意,客戶端是可以在任意節(jié)點(diǎn)進(jìn)行寫入數(shù)據(jù)的,與Kakfa不同。
1)客戶端選擇一個(gè)node發(fā)送請(qǐng)求過去,這個(gè)node就是coordinating node(協(xié)調(diào)節(jié)點(diǎn))
2)coordinating node,對(duì)document進(jìn)行路由得到對(duì)應(yīng)應(yīng)該存儲(chǔ)到哪個(gè)shard,將請(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,如果發(fā)現(xiàn)primary node和所有replica node都搞定之后,就返回響應(yīng)結(jié)果給客戶端
2.1.2 es數(shù)據(jù)的寫入原理
es數(shù)據(jù)寫入原理主要可以分為4個(gè)操作:
- refresh
- commit
- flush
- merge
操作觸發(fā)條件 | 操作過程 | |
---|---|---|
refresh | 1. 每隔1s進(jìn)行一次refresh操作 2. buffer已滿,則進(jìn)行一次refresh操作 |
1. buffer將數(shù)據(jù)寫入segment file 2. 清空buffer |
commit | 1. 每隔30分鐘執(zhí)行一次translog 2. translog日志已滿 |
1. 會(huì)主動(dòng)進(jìn)行一次refresh操作,把buffer中的數(shù)據(jù)寫入到segment file 2. 生成一個(gè) commit point 文件標(biāo)識(shí)此次操作一件把buffer數(shù)據(jù)執(zhí)行到了哪一個(gè)segment文件 3. 執(zhí)行flush操作 |
flush | commit操作中 | 1. 把file system上的文件全部強(qiáng)制fsync(持久化)到磁盤 2. 清空translog文件 3. 生成一個(gè)新的translog文件 |
merge | 后臺(tái)檢查 | 1. 將多個(gè)segment文件合并為一個(gè)文件,并把.del文件刪除 2. commit log 更新標(biāo)識(shí)目前的segment 3. 打開segmentfile 到file cache 以供快速搜索 4. 刪除舊的segment file |
2.2 es數(shù)據(jù)的讀取
2.2.1 讀取數(shù)據(jù)
使用RestFul API向?qū)?yīng)的node發(fā)送查詢請(qǐng)求,根據(jù)did來判斷在哪個(gè)shard上,返回的是primary和replica的node節(jié)點(diǎn)集合
這樣會(huì)負(fù)載均衡地把查詢發(fā)送到對(duì)應(yīng)節(jié)點(diǎn),之后對(duì)應(yīng)節(jié)點(diǎn)接收到請(qǐng)求,將document數(shù)據(jù)返回協(xié)調(diào)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)把document返回給客戶端
2.2.2 全文檢索
(1) 客戶端使用RestFul API向?qū)?yīng)的node發(fā)送查詢請(qǐng)求
(2)協(xié)調(diào)節(jié)點(diǎn)將請(qǐng)求轉(zhuǎn)發(fā)到所有節(jié)點(diǎn)(primary或者replica)所有節(jié)點(diǎn)將對(duì)應(yīng)的數(shù)據(jù)查詢之后返回對(duì)應(yīng)的doc id 返回給協(xié)調(diào)節(jié)點(diǎn)
(3)協(xié)調(diào)節(jié)點(diǎn)將doc進(jìn)行排序聚合
(4) 協(xié)調(diào)節(jié)點(diǎn)再根據(jù)doc id 把查詢請(qǐng)求發(fā)送到對(duì)應(yīng)shard的node,返回document
3 es在數(shù)據(jù)量很大的情況下如何提高性能
3.1 filesystem
es每次走fileSystem cache查詢速度是最快的
所以將每個(gè)查詢的數(shù)據(jù)50% 容量
= fileSystem cache 容量。
3.2 數(shù)據(jù)預(yù)熱
數(shù)據(jù)預(yù)熱是指,每隔一段時(shí)間,將熱數(shù)據(jù)
手動(dòng)在后臺(tái)查詢一遍,將熱數(shù)據(jù)刷新到fileSystem cache上
3.3 冷熱分離
類似于MySQL的分表分庫
將熱數(shù)據(jù)單獨(dú)建立一個(gè)索引 分配3臺(tái)機(jī)器只保持熱機(jī)器的索引
另外的機(jī)器保持冷數(shù)據(jù)的索引,但有一個(gè)問題,就是事先必須知道哪些是熱數(shù)據(jù) 哪些是冷數(shù)據(jù)
3.4. document設(shè)計(jì)
在使用es時(shí) 避免使用復(fù)雜的查詢語句(Join 、聚合),就是在建立索引時(shí),
就根據(jù)查詢語句建立好對(duì)應(yīng)的元數(shù)據(jù)。
3.5 實(shí)際設(shè)計(jì)
采用elasticSearch + Hbase的架構(gòu)方式。es中只存放少量關(guān)鍵數(shù)據(jù)建立索引,通過es查詢到doc id 再去Hbase中查詢完整的數(shù)據(jù)信息。
4 es在生產(chǎn)集群的部署架構(gòu)是什么,每個(gè)索引有多大的數(shù)據(jù)量,每個(gè)索引有多少分片
生產(chǎn)環(huán)境部署情況
(1)es生產(chǎn)集群我們部署了5臺(tái)機(jī)器,每臺(tái)機(jī)器是6核64G的,集群總內(nèi)存是320G
(2)我們es集群的日增量數(shù)據(jù)大概是2000萬條,每天日增量數(shù)據(jù)大概是500MB,
每月增量數(shù)據(jù)大概是6億,15G。目前系統(tǒng)已經(jīng)運(yùn)行了幾個(gè)月,現(xiàn)在es集群里數(shù)據(jù)總量大概是100G左右。
(3)目前線上有5個(gè)索引(這個(gè)結(jié)合你們自己業(yè)務(wù)來,看看自己有哪些數(shù)據(jù)可以放es的),
每個(gè)索引的數(shù)據(jù)量大概是20G,所以這個(gè)數(shù)據(jù)量之內(nèi),我們每個(gè)索引分配的是8個(gè)shard,比默認(rèn)的5個(gè)shard多了3個(gè)shard。
更多原創(chuàng)內(nèi)容歡迎關(guān)注:
公眾號(hào):木對(duì)林三的成長
v?:lh18708107810