Elasticsearch(二):核心

1 開篇

上一篇文章對(duì)elasticsearch進(jìn)行了整體的介紹简识,初步了解了下elasticsearch的發(fā)展溜歪、應(yīng)用場(chǎng)景赌髓、整體功能架構(gòu)和一些基本的概念祝钢,并且實(shí)際上手搭建了一個(gè)集群做了下文檔的操作府框;elasticsearch是如何進(jìn)行數(shù)據(jù)分片的呢吱窝,集群的容錯(cuò)性又是如何保證的呢。為什么elasticsearch是近實(shí)時(shí)搜索而不是實(shí)時(shí)搜索的呢迫靖?帶著這些問題院峡,我們將從分片容錯(cuò)、選主系宜、索引生命周期照激、倒排索引等核心概念來深入了解elasticsearch。

2 分片與容錯(cuò)

2.1 分片

image

我們知道通過主分片盹牧,可以將數(shù)據(jù)分布在所有的節(jié)點(diǎn)上实抡,分片提供了集群水平擴(kuò)展的能力欠母,而副本提升了系統(tǒng)的容錯(cuò)性,也在一定程度上提升了讀的吞吐量吆寨,但是降低了索引的速率赏淌。需要根據(jù)實(shí)際的應(yīng)用場(chǎng)景選擇合適的副本數(shù)量。

2.2 故障轉(zhuǎn)移原理

如上圖所示啄清,是一個(gè)由3個(gè)節(jié)點(diǎn)構(gòu)成的集群六水,上面的一個(gè)索引有3個(gè)主分片,每個(gè)分片一個(gè)副本±弊洌現(xiàn)演示一個(gè)節(jié)點(diǎn)宕機(jī)的情況:

  1. 將node1節(jié)點(diǎn)宕掉掷贾,elasticsearch會(huì)重新選一個(gè)主節(jié)點(diǎn)。

  2. Node1的p0主分片丟失荣茫,node3上的R0提升為主分片想帅,集群健康狀態(tài)變?yōu)辄S色

  3. R0和R1再分配如圖所示,集群變綠

    image

3 選主與腦裂

elasticsearch可以配置多個(gè)master eligible節(jié)點(diǎn)啡莉,每個(gè)節(jié)點(diǎn)啟動(dòng)默認(rèn)都是一個(gè)master eligible節(jié)點(diǎn)港准,這種類型的節(jié)點(diǎn)參與選主流程,然后其中一個(gè)成為master節(jié)點(diǎn)咧欣。

3.1 主節(jié)點(diǎn)作用

  1. 維護(hù)了所有的節(jié)點(diǎn)信息

  2. 維護(hù)了所有的索引浅缸、mapping、setting信息

  3. 維護(hù)了分片信息(所以一個(gè)elasticsearch的分片和索引并不能無限擴(kuò)大魄咕,主節(jié)點(diǎn)有限)

  4. 其它節(jié)點(diǎn)同步保存了集群狀態(tài)信息衩椒,只有主節(jié)點(diǎn)才能修改狀態(tài)信息,然后同步給其它節(jié)點(diǎn)哮兰,這樣才能保證一致性

3.2 選主流程

  1. 互相ping對(duì)方毛萌,node id低的會(huì)成為被選舉的節(jié)點(diǎn)

  2. 新節(jié)點(diǎn)加入,不會(huì)重新選主喝滞,發(fā)現(xiàn)主節(jié)點(diǎn)丟失朝聋,重新選主

這里會(huì)存在一些問題,Master職責(zé)負(fù)載過重囤躁,可能無法即時(shí)對(duì)組內(nèi)成員作出響應(yīng),這是一種假死荔睹。但是其它節(jié)點(diǎn)開始選主狸演,選主成功了,原來的Master恢復(fù)了僻他,因?yàn)樵瓉鞰aster節(jié)點(diǎn)的id優(yōu)先級(jí)最高宵距,又開始一輪選主,重新把原來Master又成為主吨拗,后來它又負(fù)載過重了满哪,這樣便重復(fù)選主婿斥,不可用時(shí)間很長。

3.3 腦裂

當(dāng)出現(xiàn)網(wǎng)絡(luò)分區(qū)問題時(shí)哨鸭,可能導(dǎo)致集群分成兩部分民宿,每一部分都有一個(gè)主

image

在7.0版本以前:

需要配置一個(gè)參數(shù),必須要大于某個(gè)值才能選舉像鸡,來避免腦裂 比如有三個(gè)master eligible節(jié)點(diǎn)活鹰,這個(gè)參數(shù)discovery.zen.minimum_master_nodes設(shè)置為2,必須兩個(gè)節(jié)點(diǎn)才能選舉只估。計(jì)算方法為Quorum = (master 節(jié)點(diǎn)總數(shù) /2)+ 1

在7.0版本以后

采用基于raft算法志群,無需配置,elasticsearch自身可以做判斷了蛔钙。Raft算法有三個(gè)角色锌云,跟隨者、候選人吁脱、領(lǐng)導(dǎo)者桑涎。標(biāo)準(zhǔn)raft的大致的流程為:節(jié)點(diǎn)發(fā)現(xiàn)沒有主了,發(fā)起選舉豫喧,任期增加石洗,接收的節(jié)點(diǎn)根據(jù)先到先得、任期最大紧显、日志最完整作為條件來確認(rèn)是否投票讲衫。elasticsearch與標(biāo)準(zhǔn)的raft有所改動(dòng)忆绰,比如初始都為候選人启涯、不限制每一個(gè)角色直投一票等等,可以參考博客(https://www.pianshen.com/article/16271108957/

4 倒排索引

4.1 正排索引

image

和我們通常理解的索引是一樣的草冈,如一本書的目錄一樣篙程,想查找“spring的結(jié)構(gòu)組成”的章節(jié)枷畏,可以直接定位到22頁

4.2 什么是倒排索引?

如果我們想查找“aop”字樣出現(xiàn)的位置虱饿,那么使用上面的目錄就無法做到了拥诡,只能全文掃描才知道。如何來為這個(gè)建立索引呢氮发?可以使用倒排索引渴肉,這么建立索引:

    Aop:23,34爽冕,45仇祭,65

    Aspect:24,56颈畸,344

    Configuration:245

     乌奇。没讲。。礁苗。爬凑。。寂屏。

如上面的索引贰谣,我們就可以輕松地找到“aop”所在的位置了。

Elasticsearch的倒排索引就是文檔的單詞和文檔的id關(guān)聯(lián)

4.3 倒排索引的組成

  1. 單詞詞典

    文檔的所有的單詞迁霎,這個(gè)量可能很多

  2. 倒排列表

    單詞出現(xiàn)的詞頻和單詞所在的位置

    image

倒排索引會(huì)占用很大的空間吱抚,如果不需要檢索,可以不使用倒排索引

4.4 相關(guān)度打分

Elasticsearch5之前考廉,默認(rèn)的相關(guān)性算分為TF-IDF秘豹,現(xiàn)在采?用 BM 25算法作為默認(rèn)打分。

  1. TF(Term Frequency)表示詞在一篇文檔出現(xiàn)的頻率昌粤。
  2. DF表示詞在所有?文檔中出現(xiàn)的頻率既绕。

如果只靠TF在文檔出現(xiàn)的頻率計(jì)算相關(guān)度打分可能不準(zhǔn)確,比如“的”字頻率很大涮坐,但是貢獻(xiàn)度不高凄贩,所以還需DF進(jìn)行加權(quán),IDF是DF的反向值袱讹,即IDF越大說明這個(gè)詞的貢獻(xiàn)度更有價(jià)值疲扎。1980年,Robertson用信息論相關(guān)理論證明和優(yōu)化了使用于搜索引擎的TF-IDF公式:

image

后來人們發(fā)現(xiàn)TF-IDF會(huì)隨TF增大而無限增大捷雕,對(duì)搜索的正確性有所影響椒丧,后續(xù)采用了BM25算法了。具體算法可查看相關(guān)資料救巷。 綜合下來壶熏,可以看出文檔的個(gè)數(shù)、詞頻浦译、文檔的長度都可能影響相關(guān)度得分棒假。

4.5 分詞器

分詞是將文本轉(zhuǎn)化為一系列單詞的過程。轉(zhuǎn)化為單詞后就可以形成倒排索引 分詞是由分詞器實(shí)現(xiàn)的精盅。分詞器主要由三部分組成:

  1. character filters

    原始文本去除一些特殊符號(hào)帽哑,比如《》之類的

  2. Tokenizer

    按照規(guī)則切分單詞

  3. Token filter

    對(duì)切分的單詞進(jìn)行加工,比如轉(zhuǎn)小寫渤弛,刪除一些特殊的單詞

image

Elasticsearch內(nèi)置了很多分詞器,比如standard分詞器甚带,切分單詞和小寫處理她肯,它是默認(rèn)的分詞器佳头。我們使用rest api可以測(cè)試分詞效果:

GET /_analyze
{
  "analyzer": "standard",
  "text": "Monitor & Metric"
}

{
  "tokens" : [
    {
      "token" : "monitor",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "metric",
      "start_offset" : 10,
      "end_offset" : 16,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

如果語句中有中文,則分詞效果不好晴氨,需要使用專門的中文分詞器康嘉,如對(duì)unicode很好支持的icu、ik籽前、thulac analyzer亭珍,需要在elasticserach上先安裝再使用

5 基本流程

5.1 索引

image

如圖所示,當(dāng)一個(gè)索引請(qǐng)求到了node3節(jié)點(diǎn)上枝哄,產(chǎn)生的流程為:

  1. 客戶端向 Node 3 發(fā)送新建肄梨、刪除請(qǐng)求。

  2. node3發(fā)現(xiàn)該文檔屬于p1分片挠锥,轉(zhuǎn)發(fā)請(qǐng)求到node1

  3. Node1完成p1分片的索引众羡,轉(zhuǎn)發(fā)node2、node3請(qǐng)求副本分片

  4. 所有的副本分片完成后node3返回結(jié)果蓖租。

5.2 查詢

查詢流程

image

如圖所示粱侣,當(dāng)一個(gè)查詢請(qǐng)求,請(qǐng)求到node1上蓖宦,它的查詢流程如下:

  1. node1為協(xié)調(diào)節(jié)點(diǎn)齐婴,它隨機(jī)從這6個(gè)主副分片選擇3個(gè)分片發(fā)送查詢請(qǐng)求。

  2. 每個(gè)分片查詢返回from size排序好了的id和排序值給協(xié)調(diào)節(jié)點(diǎn)稠茂。

  3. 協(xié)調(diào)節(jié)點(diǎn)進(jìn)入query階段柠偶,將每個(gè)分片獲取的id和排序值匯總重新排序,選取from size個(gè)id主慰。

  4. 并發(fā)攜帶id向?qū)?yīng)的分片獲取詳細(xì)信息嚣州,然后返回?cái)?shù)據(jù)給客戶端。

存在問題

  1. 性能問題

    每個(gè)分片需要查詢的數(shù)量很大(from+size)共螺,深度分頁的時(shí)候性能消耗很嚴(yán)重该肴。解決:攜帶上一次文檔的id(從業(yè)務(wù)的角度解決)

  2. 算分不準(zhǔn)

    由于每個(gè)分片它的相關(guān)度計(jì)算是根據(jù)自身的分片的指標(biāo)計(jì)算的,和多個(gè)分片數(shù)據(jù)匯總起來的真實(shí)的相關(guān)度排名會(huì)有差異藐不。會(huì)存在整體相關(guān)度不準(zhǔn)的問題匀哄。

解決:

數(shù)據(jù)量少的時(shí)候,使用一個(gè)分片雏蛮,數(shù)據(jù)量大的時(shí)候涎嚼,從統(tǒng)計(jì)學(xué)來看分片的數(shù)據(jù)分布的會(huì)比較均勻,結(jié)果會(huì)趨近于準(zhǔn)確挑秉。

6 分片的生命周期

分片寫入數(shù)據(jù)的時(shí)候法梯,底層采用分段的存儲(chǔ)模式。單個(gè)的倒排索引文件被稱為一個(gè)段。多個(gè)段匯總在一起成為一個(gè)lucene索引立哑,也是一個(gè)elasticsearch索引的一個(gè)分片夜惭。

image

如上圖所示,為一個(gè)節(jié)點(diǎn)索引文檔的流程:

  1. elasticsearch節(jié)點(diǎn)接收index請(qǐng)求铛绰,存入index buffer诈茧,同步存入磁盤transationlog后返回索引結(jié)果

  2. Refresh定時(shí)將index buffer數(shù)據(jù)生成segment,存入到操作系統(tǒng)緩存捂掰,此時(shí)沒有fsync敢会,清空indexbuffer,此時(shí)就可以被elasticsearch查詢了这嚣,如果index buffer占滿時(shí)鸥昏,也會(huì)觸發(fā)refresh,默認(rèn)為jvm的10%疤苹。

  3. Flush定時(shí)將緩存中的segments寫入到磁盤互广,刪除transactionlog。如果transactionlog滿時(shí)(512m)卧土,也會(huì)觸發(fā)flush惫皱。

  4. 如果數(shù)據(jù)很多,segment的也很多尤莺,同時(shí)也可能由刪除的文檔旅敷,elasticsearch會(huì)定期將它們合并。

7 lucene索引初識(shí)

Mysql數(shù)據(jù)庫存儲(chǔ)數(shù)據(jù)使用b+樹颤霎,redis內(nèi)部使用了多種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)比如跳躍表媳谁。Elasticsearch是一款搜索引擎,核心能力之一就是全文檢索友酱,所以采用了倒排索引晴音。
倒排索引的基本結(jié)構(gòu)上文中已經(jīng)介紹。這里介紹下生成一個(gè)lucene段的結(jié)構(gòu)

image

我們知道缔杉,倒排索引是由字典和倒排表組成锤躁,在lucnen的字典可以由多種數(shù)據(jù)結(jié)構(gòu)構(gòu)成。比如排序列表或详、hash表系羞、樹、跳躍表等等霸琴。正如上面所說椒振,當(dāng)詞的量很大時(shí),檢索這些詞也是非常費(fèi)勁梧乘,首先可以想到將詞排序澎迎,然后二分法查找,但是詞是海量的話,隨機(jī)io依然很多夹供,為了提升效率辑莫,可以使用term index來查找詞。elasticsearch使用trie(單詞查找)樹罩引,如圖所示

image

這個(gè)單詞前綴的樹結(jié)構(gòu)在內(nèi)存之中,不像mysql的b+樹需要和磁盤多次io操作枝笨。所以在磁盤中就可以根據(jù)索引樹查找到最終數(shù)據(jù)存在哪一個(gè)磁盤塊中袁铐,然后直接到那塊磁盤中查找對(duì)應(yīng)的倒排列表。上面只是介紹了簡單的trie樹横浑,實(shí)際上lucene采用了FST變種的trie樹剔桨,既能前綴匹配也能后綴匹配,而且大大節(jié)省了空間徙融,后續(xù)有時(shí)間再探討下lucene的FST結(jié)構(gòu)洒缀。如果多字段聯(lián)合檢索,獲取到了多個(gè)倒排列表欺冀,需要對(duì)它們的文檔id取交集树绩,lucene使用Skip List或者bitset的方式計(jì)算交集,有興趣的朋友可以去查閱相關(guān)資料了解具體的過程隐轩。
Lucene 為了提升索引和搜索的效率饺饭,從上層到底層,使用了各種巧妙的數(shù)據(jù)結(jié)構(gòu)和設(shè)計(jì)职车,來支持文檔的倒排檢索瘫俊。

8 總結(jié)

通過本文,我們了解了elasticsearch的核心原理悴灵,知道了elasticsearch底層是基于lucenen類庫來實(shí)現(xiàn)倒排索引的扛芽,通過lucene提供了豐富強(qiáng)大的文檔檢索能力。通過索引先刷入內(nèi)存积瞒、然后定時(shí)刷入磁盤來增強(qiáng)寫入性能川尖,這也是它近實(shí)時(shí)搜索的原因。一個(gè)索引是單機(jī)的赡鲜,elasticsearch通過分片副本機(jī)制來保證了容錯(cuò)性空厌,但是過多的副本會(huì)導(dǎo)致寫入性能下降,需要結(jié)合實(shí)際來設(shè)置副本數(shù)量银酬。6.x及以前的版本需要設(shè)置最小的選主節(jié)點(diǎn)數(shù)來預(yù)防腦裂嘲更,7.x以后通過新的選舉機(jī)制來規(guī)避了這個(gè)問題。篇幅有限揩瞪,后面會(huì)介紹一些elasticsearch有關(guān)的內(nèi)容赋朦。

image
image

關(guān)注IT巔峰技術(shù),私信作者,獲取以下2021全球架構(gòu)師峰會(huì)PDF資料宠哄。

image
image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壹将,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子毛嫉,更是在濱河造成了極大的恐慌诽俯,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件承粤,死亡現(xiàn)場(chǎng)離奇詭異暴区,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辛臊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門仙粱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彻舰,你說我怎么就攤上這事伐割。” “怎么了刃唤?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵隔心,是天一觀的道長。 經(jīng)常有香客問我尚胞,道長济炎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任辐真,我火速辦了婚禮须尚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侍咱。我一直安慰自己耐床,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布楔脯。 她就那樣靜靜地躺著撩轰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昧廷。 梳的紋絲不亂的頭發(fā)上堪嫂,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音木柬,去河邊找鬼皆串。 笑死,一個(gè)胖子當(dāng)著我的面吹牛眉枕,可吹牛的內(nèi)容都是我干的恶复。 我是一名探鬼主播怜森,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谤牡!你這毒婦竟也來了副硅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤翅萤,失蹤者是張志新(化名)和其女友劉穎恐疲,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體套么,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡流纹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了违诗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疮蹦,死狀恐怖诸迟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愕乎,我是刑警寧澤阵苇,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站感论,受9級(jí)特大地震影響绅项,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜比肄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一快耿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芳绩,春花似錦掀亥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘹害,卻和暖如春撮竿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笔呀。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工幢踏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人许师。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓惑折,卻偏偏與公主長得像授账,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惨驶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容