基本概念和原理
es是實(shí)時(shí)的分布式搜索分析引擎:
- 實(shí)時(shí)表現(xiàn)在新增到ES中的數(shù)據(jù)1s中就可以被檢索到,這種新增數(shù)據(jù)對(duì)搜索的可見(jiàn)性成為“準(zhǔn)實(shí)時(shí)搜索”。
- 分布式意味著可以動(dòng)態(tài)調(diào)整集群規(guī)模,彈性擴(kuò)容,支持上百個(gè)節(jié)點(diǎn),相比 HDFS 等上千臺(tái)的集群,更適合中等數(shù)據(jù)量的業(yè)務(wù),不適合存儲(chǔ)海量數(shù)據(jù)
- 分析表現(xiàn)在,ES除了搜索,還提供聚合功能,可以進(jìn)行數(shù)據(jù)分析,統(tǒng)計(jì),生成指標(biāo)數(shù)據(jù)等
Luence是java編寫(xiě)的全文搜索框架,用于處理純文本的數(shù)據(jù),但它只是個(gè)庫(kù),只提供建立索引,執(zhí)行搜索等接口,不包含分布式服務(wù)
全文:對(duì)全部的文本內(nèi)容進(jìn)行分析,建立索引,使之可以被搜索,成為全文
索引結(jié)構(gòu):
- 各種文本內(nèi)容存儲(chǔ)在文檔中,一般使用JSON作為文檔的序列化格式,在創(chuàng)建索引時(shí),需要描述文檔中每個(gè)字段的數(shù)據(jù)類(lèi)型,并且可能需要指定不同的分析器
- 在存儲(chǔ)結(jié)構(gòu)上,由_index,_type和_id唯一標(biāo)志一個(gè)文檔
- _index指向一個(gè)或多個(gè)物理分片的邏輯命名空間
- _type類(lèi)型用于區(qū)分同一個(gè)集合中的不同細(xì)分,在不同的細(xì)分中,數(shù)據(jù)的整體模式是相同或相似的,不適合完全不同類(lèi)型的數(shù)據(jù),多個(gè)_type可以在相同的索引中存在,只要他們的字段不沖突,
- _id文檔標(biāo)記符由系統(tǒng)自動(dòng)生成或使用者提供
注意:很多人會(huì)將_index理解為數(shù)據(jù)庫(kù),將_type理解為表,實(shí)際上這是完全不同的概念,不用的type下的字段不能沖突,刪除整個(gè)_type也不會(huì)釋放空間,在實(shí)際應(yīng)用中,數(shù)據(jù)模型不同,有不同_type 需求的時(shí)候,我們應(yīng)該建立單獨(dú)的索引,而不是在 索引下使用不同的 type。刪除過(guò)期老化的數(shù)據(jù)時(shí),最好以索引為單位,而不是_type和_id
在 ES 6.x 版本中, 1個(gè)索引只允許存在 type ,未來(lái)的7.x 本將完全刪除一type 概念
分片:
分布式思想:
- 在分布式系統(tǒng)中,單機(jī)無(wú)法存儲(chǔ)規(guī)模巨大的數(shù)據(jù),要依靠大規(guī)模集群處理和存儲(chǔ)這些數(shù)據(jù),一般通過(guò)增加機(jī)器數(shù)量來(lái)提高系統(tǒng)水平擴(kuò)展能力,因此,需要將數(shù)據(jù)分成若干小塊分配到各個(gè)機(jī)器上,然后再通過(guò)某種路由策略找到某個(gè)數(shù)據(jù)塊所在的位置。
- 除了將數(shù)據(jù)分片以提高水平擴(kuò)展能力,分布式存儲(chǔ)還會(huì)把數(shù)據(jù)復(fù)制成多個(gè)副本,放置到不同的機(jī)器中,來(lái)增加系統(tǒng)可用性,同時(shí)數(shù)據(jù)副本還可以是讀操作并發(fā)執(zhí)行,分擔(dān)集群壓力,但是多數(shù)據(jù)副本也會(huì)帶來(lái)一致性的問(wèn)題
- 分布式的集群方式大致可以分為主從(Master-Slave)模式和無(wú)主模式,主從模式可以簡(jiǎn)化系統(tǒng)設(shè)計(jì),部分操作僅由Master執(zhí)行,并負(fù)責(zé)維護(hù)集群元信息,缺點(diǎn)是Master節(jié)點(diǎn)存在單點(diǎn)故障,需要解決災(zāi)備問(wèn)題,并且集群規(guī)模會(huì)受限于Master節(jié)點(diǎn)的管理能力。
ES數(shù)據(jù)分片和數(shù)據(jù)副本的關(guān)系如下:
分片是底層的基本讀寫(xiě)單位,分片的目的,是分割巨大索引,讓讀寫(xiě)可以并行操作,由多臺(tái)機(jī)器共同完成,讀寫(xiě)請(qǐng)求最終落到某個(gè)分片上,分片可以獨(dú)立執(zhí)行讀寫(xiě)工作。ES利用分片將數(shù)據(jù)分發(fā)到集群內(nèi)各處,分片是數(shù)據(jù)的容器,文檔保存在分片內(nèi),不會(huì)跨分片存儲(chǔ)。分片又被分配到集群內(nèi)的各個(gè)節(jié)點(diǎn)力,當(dāng)集群規(guī)模擴(kuò)大或縮小時(shí),es會(huì)自動(dòng)在各節(jié)點(diǎn)中遷移分片,使數(shù)據(jù)仍然均勻分布在集群里。
索引與分片的關(guān)系如下:
- 一個(gè)ES索引包含很多分片
- 一個(gè)分片是一個(gè)Lucene的索引,本身就是一個(gè)完成的搜索引擎,可以獨(dú)立執(zhí)行建立索引和搜索任務(wù)。
- Lucene索引又由很多分段組成,每個(gè)分段都是一個(gè)倒排索引,ES每次refresh都會(huì)生成一個(gè)新的分段
- 一個(gè)分段segment包含若干文檔的數(shù)據(jù),在每個(gè)分段內(nèi)部,文檔的不同字段被單獨(dú)建立索引
- 每個(gè)字段的值由若干詞(Term)組成,Term是原文本內(nèi)容經(jīng)過(guò)分詞器處理和語(yǔ)言處理后的最終結(jié)果
主分片數(shù)量不可以修改,副本分片數(shù)可以隨時(shí)修改,5.x~6.x版本之后,ES支持在一定條件的限制下,對(duì)某個(gè)索引的主分片進(jìn)行拆分(Split)或縮?。⊿hrink),但是我們?nèi)匀灰谝婚_(kāi)始就盡量規(guī)劃好主分片的數(shù)量:
- 先依據(jù)硬件情況訂好單個(gè)分片容量
- 再依據(jù)業(yè)務(wù)場(chǎng)景預(yù)估數(shù)據(jù)量和增長(zhǎng)量,再除以單個(gè)分片容量
分片數(shù)不夠時(shí),可以考慮新建索引,搜索 個(gè)有 50 個(gè)分片的索引與搜索 50 個(gè)每個(gè)都有1個(gè)分片的索引完全等價(jià),或者使用_splitAPI 來(lái)拆分索引
注意:在實(shí)際應(yīng)用中,我們不應(yīng)該向當(dāng)個(gè)索引持續(xù)寫(xiě)數(shù)據(jù),知道分片巨大無(wú)比,否則會(huì)在數(shù)據(jù)老化后難以刪除,另外,以_id為單位刪除文檔不會(huì)立刻釋放空間,刪除的doc只在lucene分段合并時(shí)才會(huì)真正從磁盤(pán)中刪除
即使手動(dòng)觸發(fā)分段合并,可能也會(huì)因?yàn)榉侄尉薮蠖鴮?dǎo)致再合并過(guò)程中磁盤(pán)空間不足,因此建議周期性創(chuàng)建索引,例如每天創(chuàng)建一個(gè),例如website_20230710,然后創(chuàng)建一個(gè)名為website的索引別名來(lái)關(guān)聯(lián)這些索引,這樣對(duì)于業(yè)務(wù)方來(lái)說(shuō),讀取時(shí)使用的名稱(chēng)不變,當(dāng)需要?jiǎng)h除數(shù)據(jù)的時(shí)候,可以直接刪除整個(gè)索引。
索引別名:就像一個(gè)快捷方式或者軟鏈接,不同的是它可以指向一個(gè)或者多個(gè)索引,可以用于實(shí)現(xiàn)索引分組,或者索引見(jiàn)的無(wú)縫切換
動(dòng)態(tài)更新索引
為文檔建立索引,使其每個(gè)字段都可以被搜索,通過(guò)關(guān)鍵詞檢索文檔內(nèi)容,會(huì)使用倒排索引的數(shù)據(jù)結(jié)構(gòu)。倒排索引一旦被寫(xiě)入文件后就具有不變性,不變性具有許多好處:對(duì)文件的訪(fǎng)問(wèn)不需要加鎖, 讀取索引 才可以被文件系統(tǒng)緩存等
索引如何更新?讓新添加的文檔可以被搜索到
新增的內(nèi)容寫(xiě)到一個(gè)新的倒排索引中,查詢(xún)時(shí),每個(gè)倒排索引(segment)都被輪流查詢(xún),查詢(xún)完再對(duì)結(jié)果進(jìn)行合并
標(biāo)記刪除:由于分段的不變性,更新,刪除等操作實(shí)際上是將數(shù)據(jù)標(biāo)記為刪除,記錄到單獨(dú)的位置,因此刪除部分?jǐn)?shù)據(jù)不會(huì)釋放磁盤(pán)空間
近實(shí)時(shí)搜索:
寫(xiě)數(shù)據(jù)原理:
- 先寫(xiě)入內(nèi)存buffer,此時(shí)buffer里面的數(shù)據(jù)是搜索不到的,同時(shí)記錄事務(wù)日志translog。如果buffer快滿(mǎn)了,或者默認(rèn)每隔1s,同時(shí)buffer里面有數(shù)據(jù),就會(huì)把內(nèi)存buffer數(shù)據(jù)refresh到一個(gè)新的segment file中,清空buffer,但是此時(shí)數(shù)據(jù)不是直接進(jìn)入segment file 磁盤(pán)文件,而是先進(jìn)入操作系統(tǒng)緩存,這個(gè)segment file中就存儲(chǔ)最近1秒內(nèi) buffer中寫(xiě)入的數(shù)據(jù)??晒┎樵?xún)。以此來(lái)實(shí)現(xiàn)近實(shí)時(shí)搜索
- 重復(fù)1寫(xiě)入數(shù)據(jù),translog會(huì)不斷變大,當(dāng)translog達(dá)到一定長(zhǎng)度,就會(huì)觸發(fā)commit操作
- commit操作第一步就是將buffer中現(xiàn)有的數(shù)據(jù)refresh到操作系統(tǒng)緩存中,清空buffer,然后將一個(gè)commit point寫(xiě)入磁盤(pán)文件,里面標(biāo)志著這個(gè)commit point對(duì)應(yīng)的所有segment file,同時(shí)強(qiáng)行將操作系統(tǒng)緩存目前所有的數(shù)據(jù)都fsync到磁盤(pán)文件中去,最后清空現(xiàn)有translog日志文件,重啟一個(gè)新的translog
- 這個(gè)commit操作叫做flush。默認(rèn)30分鐘自動(dòng)執(zhí)行一次flush,但如果translog過(guò)大,也會(huì)觸發(fā)flush。flush操作就對(duì)應(yīng)著commit的全過(guò)程,我們可以通過(guò)es api,手動(dòng)執(zhí)行flush操作,手動(dòng)將os? cache中數(shù)據(jù)fsync強(qiáng)刷到磁盤(pán)上去
- translog其實(shí)也是先寫(xiě)入os cache的,默認(rèn)每隔5秒刷一次到磁盤(pán)中去,所以默認(rèn)情況下,可能有5s的數(shù)據(jù)會(huì)僅僅停留在buffer或者translog文件的os cache中,如果此時(shí)機(jī)器掛了,會(huì)丟失5秒鐘的數(shù)據(jù)。但是這樣性能比較好,最多丟5秒的數(shù)據(jù)。也可以將translog設(shè)置成每次寫(xiě)操作必須是直接fsync到磁盤(pán),但是性能會(huì)差很多
translog:每次對(duì)ES進(jìn)行操作時(shí),都會(huì)記錄事務(wù)日志,當(dāng)ES啟動(dòng)時(shí),重放translog中所有在最后一次提交后發(fā)生的變更操作
段合并
每次refresh都會(huì)創(chuàng)建一個(gè)segment,這會(huì)導(dǎo)致分段數(shù)量太多,從而導(dǎo)致:1消耗文件句柄內(nèi)存,2 每個(gè)搜索請(qǐng)求都需要輪流檢查每個(gè)段,查詢(xún)完再對(duì)結(jié)果進(jìn)行合并,所以搜索會(huì)比較慢
策略:常用方案是選擇大小相似的分段進(jìn)行合并,在合并過(guò)程中,標(biāo)記為刪除的數(shù)據(jù)不會(huì)寫(xiě)入新分段,當(dāng)合并過(guò)程結(jié)束,舊的分段數(shù)據(jù)被刪除,標(biāo)記刪除的數(shù)據(jù)才從磁盤(pán)刪除
問(wèn)題:當(dāng)段文件大小沒(méi)有上限,巨大的段達(dá)到磁盤(pán)空間的一半時(shí),剩余空間不足以進(jìn)行新的的段合并過(guò)程,如果段文件設(shè)置一定上限不再合并,則對(duì)部分?jǐn)?shù)據(jù)無(wú)法實(shí)現(xiàn)真正的物理刪除操作
集群內(nèi)部原理
ES集群使用的分布式的主從模式,從集群節(jié)點(diǎn)角色的角度劃分,至少存在:主節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn), 預(yù)處理節(jié)點(diǎn),部落節(jié)點(diǎn)
集群節(jié)點(diǎn)角色
主節(jié)點(diǎn) (master node)
職責(zé):負(fù)責(zé)集群層面的相關(guān)操作,管理集群變更
配置:配置了node.master:true(默認(rèn))的節(jié)點(diǎn),才具有被選舉為Master的資格,主節(jié)點(diǎn)是唯一的,將從有資格成為master的節(jié)點(diǎn)中進(jìn)行選舉
主節(jié)點(diǎn)也可以配置為數(shù)據(jù)節(jié)點(diǎn),通過(guò)node.data : false/true控制,生產(chǎn)環(huán)境應(yīng)盡量分離主節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)
為了防止數(shù)據(jù)丟失,每個(gè)主節(jié)點(diǎn)應(yīng)該知道有資格成為主節(jié)點(diǎn)的數(shù)量,默認(rèn)為1,通過(guò)discovery.zen.minimum master nodes配置,原則上最小值為:(master eligible nodes I 2) + 1
數(shù)據(jù)節(jié)點(diǎn)(data node)
職責(zé):負(fù)責(zé)保存數(shù)據(jù),執(zhí)CRUD,搜索,聚合等
一般情況下,數(shù)據(jù)讀寫(xiě)流程只和數(shù)據(jù)節(jié)點(diǎn)交互,不會(huì)和主節(jié)點(diǎn)打交道(異常情況除外)
預(yù)處理節(jié)點(diǎn) (Ingest node)
職責(zé):預(yù)處理操作允許在索引文檔之前,即寫(xiě)入數(shù)據(jù)之前,通過(guò)事先定義好的一系列processors(處理器)和管道(pipeline),對(duì)數(shù)據(jù)進(jìn)行某種轉(zhuǎn)換和富化,processors和pipeline攔截bulk和index請(qǐng)求,在應(yīng)用相關(guān)操作后,將文檔傳回給index或bulk API
配置:默認(rèn)在所有節(jié)點(diǎn)啟用ingest,如果想要禁用ingest,可添加node.ingest:false,也可以通過(guò)配置
node.master : false
node . data : false
node.ingest : true
創(chuàng)建一個(gè)僅用于預(yù)處理的節(jié)點(diǎn)
協(xié)調(diào)節(jié)點(diǎn) (Coordinating node)
作用:客戶(hù)端請(qǐng)求可以發(fā)送到集群的任意節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都知道任意文檔所處的位置,然后轉(zhuǎn)發(fā)這些請(qǐng)求,收集數(shù)據(jù)并返回給客戶(hù)端,處理客戶(hù)端請(qǐng)求的節(jié)點(diǎn)成為協(xié)調(diào)節(jié)點(diǎn)
協(xié)調(diào)節(jié)點(diǎn)將請(qǐng)求轉(zhuǎn)發(fā)給保存數(shù)據(jù)的數(shù)據(jù)節(jié)點(diǎn),每個(gè)數(shù)據(jù)節(jié)點(diǎn)在本地執(zhí)行請(qǐng)求,并將結(jié)果返回給協(xié)調(diào)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)收集完數(shù)據(jù)后,合并為單個(gè)全局結(jié)果,對(duì)結(jié)果收集和排序的過(guò)程可能需要很多CPU和內(nèi)存資源
部落節(jié)點(diǎn)(Tribe node)
職責(zé):部落功能允許部落節(jié)點(diǎn)在多個(gè)集群之間充當(dāng)聯(lián)合客戶(hù)端
集群狀態(tài)
集群狀態(tài)元數(shù)據(jù)是全局信息,元數(shù)據(jù)包括:路由信息,配置信息
集群狀態(tài)由主節(jié)點(diǎn)負(fù)責(zé)維護(hù),如果主節(jié)點(diǎn)從數(shù)據(jù)節(jié)點(diǎn)接收更新,則將這些更新廣播到集群的其他節(jié)點(diǎn),讓每個(gè)節(jié)點(diǎn)上的集群狀態(tài)保持最新
集群擴(kuò)容
當(dāng)擴(kuò)容集群,添加節(jié)點(diǎn)時(shí),分片會(huì)均衡的分配到集群的各個(gè)節(jié)點(diǎn),從而對(duì)索引和搜索過(guò)程進(jìn)行負(fù)載均衡
主要內(nèi)部模塊簡(jiǎn)介
Cluster
cluster模塊是主節(jié)點(diǎn)執(zhí)行集群管理的封裝實(shí)現(xiàn),管理集群狀態(tài),維護(hù)集群層面的配置信息
功能:
- 管理集群狀態(tài),將新生成的集群狀態(tài)發(fā)布到集群所有節(jié)點(diǎn)
- 調(diào)用allocation模塊執(zhí)行分片分配,決策哪些分片應(yīng)該分配到哪個(gè)節(jié)點(diǎn)
- 在集群個(gè)節(jié)點(diǎn)中直接遷移分片,保持?jǐn)?shù)據(jù)平衡
allocation
封裝了分片分配相關(guān)的功能和策略,包括主分片的分配和副本分片的分配,創(chuàng)建新索引,集群完全重啟都需要分片分配的過(guò)程
Discovery
發(fā)現(xiàn)模塊負(fù)責(zé)發(fā)現(xiàn)集群中的節(jié)點(diǎn),以及選舉主節(jié)點(diǎn),當(dāng)節(jié)點(diǎn)加入或者退出集群時(shí),主節(jié)點(diǎn)會(huì)采取相應(yīng)的行動(dòng)
gateway
負(fù)責(zé)對(duì)收到Master廣播下來(lái)的集群狀態(tài)數(shù)據(jù)的持久化存儲(chǔ),并在集群完成重啟時(shí)恢復(fù)它們
Indices
索引模塊管理全局級(jí)的索引設(shè)置,不包括索引級(jí)的(索引設(shè)置分為全局級(jí)和每個(gè)索引級(jí)),它還封裝了索引數(shù)據(jù)恢復(fù)功能,集群?jiǎn)?dòng)階段需要的主分片恢復(fù)和副本分片恢復(fù)就是在這個(gè)模塊實(shí)現(xiàn)的
HTTP
http模塊允許通過(guò)JSON over HTTP的方式訪(fǎng)問(wèn)ES的API,該模塊本質(zhì)上是完全異步的
Transport
傳輸模塊用于集群內(nèi)節(jié)點(diǎn)之間的內(nèi)部通信,節(jié)點(diǎn)到另一個(gè)節(jié)點(diǎn)的每個(gè)請(qǐng)求都使用傳輸模塊,也是異步的
Engine文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-838910.html
封裝了對(duì)Lucene的操作及translog的調(diào)用,是對(duì)一個(gè)分片讀寫(xiě)操作的最終提供者文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-838910.html
到了這里,關(guān)于分布式搜索分析引擎ES的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!