插件学习笔记:搜索引擎ElasticSearch
ElasticSearch介紹
ElasticSearch是一個(gè)實(shí)時(shí)分布式的高拓展全文搜索和分析引擎,是ELK(ElasticSearch, Kibana, Logstach的)技術(shù)的核心。
ElasticSearch的優(yōu)勢(shì)在于模糊與全文查詢,雖然關(guān)系型數(shù)據(jù)庫(kù)也能夠做到like關(guān)鍵字的模糊查詢,但是會(huì)遍歷整個(gè)表數(shù)據(jù),響應(yīng)很慢,因此需要使用搜索更加快捷的ElasticSearch來(lái)進(jìn)行處理。
主流的搜索引擎
ES與Solr的相同點(diǎn)
ElasticSearch和Solr都屬于應(yīng)用很廣的搜索引擎,他們的基礎(chǔ)都是Lucene, 一個(gè)Apache開源的全文搜索的java核心工具包
ES與Solr對(duì)比
- ElasticSearch的安裝比較簡(jiǎn)單,即開即用,Solr則相對(duì)而言比較復(fù)雜
- Solr用Zookeeper進(jìn)行集群管理,而ElasticSearch有內(nèi)置的分布式協(xié)調(diào)管理功能
- Solr指出JSON,XML等多種的數(shù)據(jù)格式,ES支支持Json
- Solr提供的功能更多,而ES更注重核心功能,其他的依賴第三方差價(jià),比如圖形化的管理分析工具Kibana
- Solr查詢更快,更新索引慢,而ElasticSearch更新索引更快,也就是實(shí)時(shí)查詢性能更好,因此像商城這種更適合用Solr,而微博這種更新數(shù)據(jù)量大的更適合用ElasticSearch
Hermes
騰訊的大數(shù)據(jù)搜索引擎,與ES和Solr相比
- ES和Solr更注重全文的搜索,Hermes更注重?cái)?shù)據(jù)的分析
- ES和Solr相對(duì)數(shù)據(jù)量更小,而Hermes可以處理更大量的數(shù)據(jù)
ElasticSearch的數(shù)據(jù)格式
數(shù)據(jù)格式的對(duì)比,Index相當(dāng)于一個(gè)數(shù)據(jù)庫(kù),Type相當(dāng)于一個(gè)表,而Document對(duì)應(yīng)了一行數(shù)據(jù),Field對(duì)應(yīng)了一個(gè)列,不過(guò)在后期的ElasticSearch中已經(jīng)刪除了Type的概念,一個(gè)文檔的數(shù)據(jù)序列化格式為JSON
分片
對(duì)于一個(gè)索引數(shù)據(jù)量過(guò)大的時(shí)候,一個(gè)節(jié)點(diǎn)可能是存儲(chǔ)不下這個(gè)索引里所有的數(shù)據(jù)的,因此這里引入了分片的概念,也就是將所有的數(shù)據(jù)分片存儲(chǔ)在不同的節(jié)點(diǎn)當(dāng)中,查詢的時(shí)候會(huì)查詢整個(gè)集群里面所有屬于同一索引的分片。這樣的好處在于不僅可以突破節(jié)點(diǎn)的數(shù)據(jù)存儲(chǔ)量,還可以并行操作提高效率和吞吐量。這部分對(duì)于用戶而言是透明的,elasticsearch會(huì)自行進(jìn)行管理。
- 值得注意的是,Lucene的索引對(duì)應(yīng)了elasticsearch中的分片,elasticsearch中的索引是lucene中索引的集合
- 分片的內(nèi)容的路由計(jì)算是由master根據(jù)一個(gè)路由公式來(lái)的
副本
允許創(chuàng)建分片的一個(gè)或多個(gè)拷貝,這個(gè)拷貝叫做復(fù)制分片/副本,分片的優(yōu)勢(shì)在于
- 提高了可用性
- 也可以提高搜索量/吞吐量,因?yàn)樗械乃阉鞫伎梢栽诟北旧喜⑿羞\(yùn)行
分片的數(shù)量可以在創(chuàng)建索引的時(shí)候指定,創(chuàng)建索引之后可以動(dòng)態(tài)地改變復(fù)制的數(shù)量,但是分片數(shù)量是不能改變的。默認(rèn)情況下會(huì)有一個(gè)主分片和一個(gè)復(fù)制分片,分片分配給某個(gè)節(jié)點(diǎn)的過(guò)程是由master節(jié)點(diǎn)完成的
ElasticSearch的架構(gòu)
集群Cluster
一個(gè)ES集群有一個(gè)對(duì)應(yīng)的名字,節(jié)點(diǎn)可以通過(guò)這個(gè)名字加入到集群當(dāng)中,默認(rèn)集群名稱為“elasticsearch”
節(jié)點(diǎn)Node
一個(gè)節(jié)點(diǎn)也由一個(gè)對(duì)應(yīng)的名字指定,默認(rèn)是一個(gè)漫威漫畫的名字,服務(wù)器通過(guò)指定節(jié)點(diǎn)名字可以對(duì)節(jié)點(diǎn)進(jìn)行連接。一個(gè)集群內(nèi)部節(jié)點(diǎn)的名稱要唯一
如果沒(méi)有指定集群的名稱,同一網(wǎng)絡(luò)下的若干節(jié)點(diǎn)只要一啟動(dòng),就都會(huì)加入到“elasticsearch”這個(gè)集群當(dāng)中,他們能夠互相發(fā)現(xiàn)彼此。
在節(jié)點(diǎn)1中的數(shù)據(jù)在節(jié)點(diǎn)2里面也是能被查詢到的,當(dāng)一個(gè)節(jié)點(diǎn)被選為主節(jié)點(diǎn)master時(shí),他就會(huì)負(fù)責(zé)集群范圍內(nèi)所有的變更,包括增加、刪除索引或增加刪除節(jié)點(diǎn)等。
ElasticSearch原理
讀寫流程
- 對(duì)于寫數(shù)據(jù),會(huì)首先由協(xié)調(diào)節(jié)點(diǎn)計(jì)算主分片所在位置,寫完主分片后寫備份,而后返回成功消息
- 對(duì)于讀數(shù)據(jù),會(huì)選擇輪詢副本的方式來(lái)達(dá)到負(fù)載平衡的目的,當(dāng)然同步?jīng)]完成的時(shí)候會(huì)報(bào)告副本不存咋,這種情況下就需要主分片返回?cái)?shù)據(jù)了
對(duì)于多條數(shù)據(jù)的操作是可以并行進(jìn)行的
分片原理
分片是ES最小的工作單元
倒排索引
將文檔中的內(nèi)容進(jìn)行分詞,作為索引,索引對(duì)應(yīng)的值是文檔的id,也就是從id對(duì)應(yīng)內(nèi)容反向成了內(nèi)容對(duì)應(yīng)id
動(dòng)態(tài)更新索引
ElasticSearch是基于Luence的,Luence引入了按段搜索的概念,每一個(gè)段就是一個(gè)倒排索引,查詢時(shí)會(huì)采取輪詢每一個(gè)段的方式進(jìn)行,同時(shí)將搜到的內(nèi)容進(jìn)行聚合。以保證所有的內(nèi)容都被正確地計(jì)算。
除了所有的段之外,es還會(huì)存儲(chǔ)一個(gè)提交點(diǎn),即一個(gè)列出了所有已知段的文件。
索引更新流程如下
近實(shí)時(shí)搜索特性
由于從緩存中向磁盤寫入新的段是十分浪費(fèi)事件的,因此elasticSearch采用了一個(gè)存在緩存中的段的方式,將緩存區(qū)的內(nèi)容寫入一個(gè)可以被搜索的段中,這樣緩存區(qū)的內(nèi)容就可以被搜索到了,再將耗費(fèi)時(shí)間長(zhǎng)的磁盤寫入過(guò)程異步進(jìn)行提交就可以了。這個(gè)過(guò)程被成為refresh,每秒(這個(gè)事件是可以修改的)執(zhí)行一次,也就是添加的新段會(huì)在一秒內(nèi)被搜索到,因此是近實(shí)時(shí)搜索的特性。
持久化變更
進(jìn)實(shí)時(shí)搜索的緩存段如果斷電的話就消失了,因此持久化,也就是異步存儲(chǔ)段到磁盤的過(guò)程也是必須被執(zhí)行的。elasticSearch引入了translog日志來(lái)進(jìn)行處理。
在緩存寫入的過(guò)程當(dāng)中,translog也會(huì)記錄相應(yīng)的內(nèi)容,隔一段時(shí)間會(huì)進(jìn)行全量的提交,也就是
也就是說(shuō)通過(guò)translog這一個(gè)存儲(chǔ)了所有沒(méi)有被持久化操作的日志記錄,完成了可靠的數(shù)據(jù)持久化工作
分片每30分鐘或translog過(guò)長(zhǎng)的時(shí)候進(jìn)行一次flush
- 注意:段的持久化是異步的,可以保證數(shù)據(jù)的可靠性,但是前提是translog的數(shù)據(jù)能夠被正確地存儲(chǔ),translog默認(rèn)每5秒刷新一次,或者在請(qǐng)求之后執(zhí)行一次,這就使得translog本身的持久化是同步的,雖然會(huì)損失一定的性能,但是數(shù)據(jù)是可靠的,當(dāng)然在一些數(shù)據(jù)可靠性要求不高的應(yīng)用場(chǎng)景也可以采用異步的方式追求極致的性能。
段合并
采用了分段搜索雖然更新索引的開銷較低,但是隨著段的暴增,數(shù)據(jù)的搜索會(huì)變得緩慢,因此在elasticSearch當(dāng)中引入了段合并的后臺(tái)過(guò)程,小的段被合并到了大的段當(dāng)中。段合并的過(guò)程如下
refresh的過(guò)程中啟用了緩存的段并可以被搜索到
產(chǎn)生一個(gè)大的緩存段
選擇大小相似的小段,將其寫入大的緩存段當(dāng)中(這一步并不影響原先小段被搜索)
新段flush到磁盤,提交點(diǎn)也被刷新
新段打開用于搜索
老段刪除
合并過(guò)程占用了大量的CPU資源,因此elasticSearch對(duì)合并過(guò)程進(jìn)行了資源的限制,保證搜索過(guò)程能被很好地執(zhí)行
文檔分析
文檔分析器的作用在于將一整塊內(nèi)容劃分為獨(dú)立的詞條并進(jìn)行一些相關(guān)的處理保證“可搜索性”,一次文檔的分析過(guò)程被分成了三步
當(dāng)然分詞器是用在查詢?nèi)挠虻?#xff0c;當(dāng)進(jìn)行精確查詢的時(shí)候,比如使用+關(guān)鍵字,是不會(huì)用分析器進(jìn)行處理的
內(nèi)置分析器
有標(biāo)準(zhǔn)分析器,簡(jiǎn)單分析器,空格分析器,語(yǔ)言分析器等,它們根據(jù)不同的規(guī)則進(jìn)行了詞條的劃分
IK中文分詞器
進(jìn)行常見(jiàn)的中文分詞并支持進(jìn)行自定義拓展詞典(遠(yuǎn)程的或者本地的都可以)
除了這些之外ES也是支持自定義分詞器的
ElasticSearch文檔沖突
Web1做了-1操作,Web2也做了-1操作,但是二者引發(fā)了并發(fā)所帶來(lái)的沖突,這就是文檔沖突現(xiàn)象,其實(shí)就是一個(gè)并發(fā)問(wèn)題
文檔沖突現(xiàn)象有兩種處理方式,一是悲觀并發(fā)控制,二是樂(lè)觀并發(fā)控制
- 悲觀并發(fā)控制:比如mysql的行級(jí)鎖,只允許一個(gè)線程進(jìn)行數(shù)據(jù)的處理
- 樂(lè)觀并發(fā)控制:請(qǐng)求會(huì)攜帶版本號(hào),舊的版本號(hào)不會(huì)覆蓋新的版本號(hào),以保證數(shù)據(jù)不會(huì)丟失,ES采用的就是這種方式
ElasticSearch索引庫(kù)的操作
HttpUrl操作
采用RESTful風(fēng)格進(jìn)行處理,相信的條件封裝在請(qǐng)求體的JSON格式數(shù)據(jù)當(dāng)中
RESTful風(fēng)格簡(jiǎn)而言之就是
- URL就代表了資源
- HTTP的操作類型就代表了對(duì)資源進(jìn)行怎樣的處理
- 返回的狀態(tài)碼就能知道操作取得的效果如何
支持以下幾種操作:
- 索引
- 文檔
- 映射(相當(dāng)于關(guān)系型數(shù)據(jù)庫(kù)當(dāng)中的表結(jié)構(gòu))
DSL語(yǔ)句操作
同樣支持上述的操作,包括排序、過(guò)濾、分頁(yè)等等相關(guān)的操作
SpringData ElasticSearch
SpringDataElasticSearch對(duì)ES的相應(yīng)API進(jìn)行了封裝,能夠更方便地構(gòu)建所需的代碼
引入依賴
配置文件
spring:data:elasticsearch:cluster-name: my-applicationcluster-nodes: 192.168.211.132:9300配置說(shuō)明
connection-timeout:服務(wù)連接超時(shí)時(shí)間 socket-connect:HTTP請(qǐng)求超時(shí)時(shí)間 ribbon.ReadTimeout: Feign請(qǐng)求讀取數(shù)據(jù)超時(shí)時(shí)間 timeoutInMilliseconds:feign連接超時(shí)時(shí)間 cluster-name:Elasticsearch的集群節(jié)點(diǎn)名稱,這里需要和Elasticsearch集群節(jié)點(diǎn)名稱保持一致 cluster-nodes:Elasticsearch節(jié)點(diǎn)通信地址啟動(dòng)類
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class}) @EnableEurekaClient public class SearchApplication {public static void main(String[] args) {/*** Springboot整合Elasticsearch 在項(xiàng)目啟動(dòng)前設(shè)置一下的屬性,防止報(bào)錯(cuò)* 解決netty沖突后初始化client時(shí)還會(huì)拋出異常* availableProcessors is already set to [12], rejecting [12]***/System.setProperty("es.set.netty.runtime.available.processors", "false");SpringApplication.run(SearchApplication.class,args);} }對(duì)于POJO,設(shè)置Document和Feild注解設(shè)置,需要與elasticSearch中的設(shè)置一致
@Document(indexName = "skuinfo",type = "docs") public class SkuInfo implements Serializable {//商品id,同時(shí)也是商品編號(hào)@Idprivate Long id;//SKU名稱@Field(type = FieldType.Text, analyzer = "ik_smart")private String name;//商品價(jià)格,單位為:元@Field(type = FieldType.Double)private Long price; }DAO層的設(shè)置也比較簡(jiǎn)單,實(shí)現(xiàn)相應(yīng)的類即可
@Repository public interface SkuEsMapper extends ElasticsearchRepository<Sku,Long> { }許多簡(jiǎn)單查詢、分頁(yè)查詢、聚合查詢、高亮查詢都是可以用類中封裝的方法進(jìn)行實(shí)現(xiàn)的
ElasticSearch面試題
為什么使用ElasticSearch
系統(tǒng)中的數(shù)據(jù),隨著業(yè)務(wù)的發(fā)展,時(shí)間的推移,將會(huì)非常多,而業(yè)務(wù)中往往采用模糊查詢進(jìn)行數(shù)據(jù)的搜索,而模糊查詢會(huì)導(dǎo)致查詢引擎放棄索引,導(dǎo)致系統(tǒng)查詢數(shù)據(jù)時(shí)都是全表掃描,在百萬(wàn)級(jí)別的數(shù)據(jù)庫(kù)中,查詢效率是非常低下的,而我們使用 ES 做一個(gè)全文索引,將經(jīng)常查詢的系統(tǒng)功能的某些字段,比如說(shuō)電商系統(tǒng)的商品表中商品名,描述、價(jià)格還有 id 這些字段我們放入 ES 索引庫(kù)里,可以提高查詢速度。
- 關(guān)鍵字: 模糊查詢效率低,倒排索引,提高速度
master 選舉流程
- 關(guān)鍵詞:ping,排序,選取第一個(gè)
關(guān)于腦裂
概念
簡(jiǎn)而言之,因?yàn)槟承┰虺霈F(xiàn)了多個(gè)master,比如兩個(gè)機(jī)房分別存放了三個(gè)節(jié)點(diǎn),機(jī)房間的網(wǎng)絡(luò)中斷導(dǎo)致機(jī)房2中的節(jié)點(diǎn)無(wú)法訪問(wèn)機(jī)房1中的節(jié)點(diǎn),于是選取了兩個(gè)master,就造成了腦裂
腦裂成因
- 網(wǎng)絡(luò)延遲原因,集群間的網(wǎng)絡(luò)通信出現(xiàn)問(wèn)題
- 節(jié)點(diǎn)負(fù)載,master作為data節(jié)點(diǎn)訪問(wèn)壓力過(guò)大導(dǎo)致造成大面積延遲
- data上的垃圾回收導(dǎo)致內(nèi)存占用較大,使得ES進(jìn)程失去響應(yīng)
腦裂解決
- 增加響應(yīng)失效時(shí)間的閾值,減少誤判
- 參考zookeeper的過(guò)半數(shù)選舉,這也是ES官方推薦的模式,即選舉必須超過(guò)半數(shù)才能成為新的master
- 角色分離:master不擔(dān)任data節(jié)點(diǎn)(配置文件中是可以進(jìn)行配置的)
底層流程
索引文檔流程
- 關(guān)鍵詞: 分片路由、緩存區(qū)與translog、refresh開發(fā)臨時(shí)段、flush持久化、合并段
更新和刪除文檔流程
其變更;
- 關(guān)鍵詞: 提交點(diǎn)邏輯刪除、結(jié)果過(guò)濾
搜索流程
搜索被執(zhí)行成一個(gè)兩階段過(guò)程,我們稱之為 Query Then Fetch;
列中來(lái)產(chǎn)生一個(gè)全局排序后的結(jié)果列表。
- 關(guān)鍵詞: : 并行查詢,協(xié)調(diào)節(jié)點(diǎn)合并,評(píng)分與過(guò)濾
如何實(shí)現(xiàn)大數(shù)據(jù)聚合
通過(guò)HLL算法基于概率進(jìn)行估算所得到的,精度是可控的
如何保證讀寫一致
- 可以通過(guò)版本號(hào)使用樂(lè)觀并發(fā)控制,以確保新版本不會(huì)被舊版本覆蓋,由應(yīng)用層來(lái)處理具體的沖突;
- 另外對(duì)于寫操作,一致性級(jí)別支持 quorum/one/all,默認(rèn)為 quorum,即只有當(dāng)大多數(shù)分片可用時(shí)才允許寫操作。但即使大多數(shù)可用,也可能存在因?yàn)榫W(wǎng)絡(luò)等原因?qū)е聦懭敫北臼?#xff0c;這樣該副本被認(rèn)為故障,分片將會(huì)在一個(gè)不同的節(jié)點(diǎn)上重建。
- 對(duì)于讀操作,可以設(shè)置 replication 為 sync(默認(rèn)),這使得操作在主分片和副本分片都完成后才會(huì)返回;如果設(shè)置 replication 為 async 時(shí),也可以通過(guò)設(shè)置搜索請(qǐng)求參數(shù)_preference 為 primary 來(lái)查詢主分片,確保文檔是最新版本。
- 關(guān)鍵詞 :樂(lè)觀鎖并發(fā)控制、多數(shù)分片可用才寫,主副分片都完成后才返回
如何監(jiān)控集群狀態(tài)
elasticSearch-Head插件(丑的一批)
Kibana(屬實(shí)好看)
字典樹
字典樹又稱單詞查找樹,Trie 樹,是一種樹形結(jié)構(gòu),是一種哈希樹的變種。典型應(yīng)用是用于統(tǒng)計(jì),排
序和保存大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)。它的優(yōu)點(diǎn)是:利用字符串的公共前綴來(lái)減少查詢時(shí)間,最大限度地減少無(wú)謂的字符串比較,查詢效率比哈希樹高。
Trie 的核心思想是空間換時(shí)間,利用字符串的公共前綴來(lái)降低查詢時(shí)間的開銷以達(dá)到提高效率的目的。
它有 3 個(gè)基本性質(zhì):
- 根節(jié)點(diǎn)不包含字符,除根節(jié)點(diǎn)外每一個(gè)節(jié)點(diǎn)都只包含一個(gè)字符。
- 從根節(jié)點(diǎn)到某一節(jié)點(diǎn),路徑上經(jīng)過(guò)的字符連接起來(lái),為該節(jié)點(diǎn)對(duì)應(yīng)的字符串。
- 每個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)包含的字符都不相同。
對(duì)于中文的字典樹,每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)用一個(gè)哈希表存儲(chǔ),這樣就不用浪費(fèi)太大的空間,而且查詢速度上可以保留哈希的復(fù)雜度 O(1)。
名詞解釋
集群
集群是一個(gè)或多個(gè)節(jié)點(diǎn)(服務(wù)器)的集合,它們共同保存您的整個(gè)數(shù)據(jù),并提供跨所有節(jié)點(diǎn)的聯(lián)合索
引和搜索功能。群集由唯一名稱標(biāo)識(shí),默認(rèn)情況下為“elasticsearch”。此名稱很重要,因?yàn)槿绻?jié)點(diǎn)設(shè)
置為按名稱加入群集,則該節(jié)點(diǎn)只能是群集的一部分。
節(jié)點(diǎn)
節(jié)點(diǎn)是屬于集群一部分的單個(gè)服務(wù)器。它存儲(chǔ)數(shù)據(jù)并參與群集索引和搜索功能。
索引
索引就像關(guān)系數(shù)據(jù)庫(kù)中的“數(shù)據(jù)庫(kù)”。它有一個(gè)定義多種類型的映射。索引是邏輯名稱空間,映射到一個(gè)或多個(gè)主分片,并且可以有零個(gè)或多個(gè)副本分片。 MySQL =>數(shù)據(jù)庫(kù) Elasticsearch =>索引
文檔
文檔類似于關(guān)系數(shù)據(jù)庫(kù)中的一行。不同之處在于索引中的每個(gè)文檔可以具有不同的結(jié)構(gòu)(字段),但
是對(duì)于通用字段應(yīng)該具有相同的數(shù)據(jù)類型。 MySQL => Databases => Tables => Columns / Rows Elasticsearch => Indices => Types =>具有屬性的文檔
類型
類型是索引的邏輯類別/分區(qū),其語(yǔ)義完全取決于用戶。
倒排文檔
倒排索引是搜索引擎的核心。搜索引擎的主要目標(biāo)是在查找發(fā)生搜索條件的文檔時(shí)提供快速搜索。ES中的倒排索引其實(shí)就是 lucene 的倒排索引,區(qū)別于傳統(tǒng)的正向索引,倒排索引會(huì)再存儲(chǔ)數(shù)據(jù)時(shí)將關(guān)鍵詞和數(shù)據(jù)進(jìn)行關(guān)聯(lián),保存到倒排表中,然后查詢時(shí),將查詢內(nèi)容進(jìn)行分詞后在倒排表中進(jìn)行查詢,最后匹配數(shù)據(jù)即可
總結(jié)
以上是生活随笔為你收集整理的插件学习笔记:搜索引擎ElasticSearch的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数字化项目建设管理难点分析与对策
- 下一篇: 高等数学复盘 | 第七册上册第一章——第