ElasticSearch淺談

雨中漫步我心飛揚發表於2018-05-11

一、基本概念

  ElasticSearch是一個可擴充套件的開源搜尋引擎,並可以儲存資料,它是面向Nosql的資料庫,使用json作為文件的序列化格式,半結構化的資料是通常是變化的,因此在索引一個文件的時候不必提前定義好索引和型別,與mysql有如下圖所示的對比。

ElasticSearch淺談

二、倒排索引的原理

  es是在lucense上做了進一步的封裝,將文件採用分詞器切分成詞,建立詞與文件的對映,採用倒排索引進行搜尋。倒排索引的基本結構如下所示:

ElasticSearch淺談
                  圖2-1

  那麼倒排索引如何建立的呢?現有如下圖2-1所示文件集合,分詞器會將文件切分成一系列的單詞集合,單詞同文件一樣有個唯一標識id,那麼需要資料結構記錄某個單詞出現在哪些文件,出現了多少次,也就是詞頻(這個用於做相似性計算,展示給使用者結果排序使用),也可以記錄在文件中出現的位置。這就轉化為了如圖2-2所示的對應關係。

ElasticSearch淺談

                  圖2-2

ElasticSearch淺談
                  圖2-3

  比如當搜尋“加盟”單詞時,會搜尋到編號為2、3、5的文件,單詞在該文件中出現過一次。

三、分片與叢集

  我們索引的文件是儲存在分片上的,分片(Shard),是Elasticsearch中的最小儲存單元。預設情況下,Elasticsearch會為每個索引分配5個分片,這些分片是主分片,一旦確定,在後期水平擴充套件時,也只是增加副本分片的數量,所以確定主分片應該考慮周全,根據索引下的資料量以及後期資料的增長情況考慮。在擴大叢集規模時,副本分片可以做冗餘備份,可以響應客戶端請求,從而提高效能。但是如果機器數量一定的情況下並不是分片越多越好,因為這樣的話其他分片所佔用的cpu以及硬體資源等會響應減少。那如果知道索引是放在分片1還是分片2呢?是通過如下公式進行計算,其中routing是文件的id.

shard = hash(routing) % number_of_primary_shards

  一個索引可以儲存在多個分片,分片可以分佈在叢集的不同節點上,elasticsearch叢集環境不是靠zookeeper進行協調的,當一個節點被選舉成為主節點時, 它將負責管理叢集範圍內的所有變更,例如增加、刪除索引,或者增加、刪除節點等。 而主節點並不需要涉及到文件級別的變更和搜尋等操作,所以當叢集只擁有一個主節點的情況下,即使流量的增加它也不會成為瓶頸。任何節點都可以成為主節點。作為使用者,我們可以將請求傳送到 叢集中的任何節點,包括主節點。每個節點都知道任意文件所處的位置,並且能夠將我們的請求直接轉發到儲存我們所需文件的節點。無論我們將請求傳送到哪個節點,它都能負責從各個包含我們所需文件的節點收集回資料,並將最終結果返回給客戶端。可能由於通訊問題,主節點沒有響應,其他節點認為主節點掛掉,會重新選舉主節點,可能會出現多個主節點的現象,稱之為腦裂現象

如何避免腦裂,通常有以下方法
1、設定引數discovery.zen.minimum_master_nodes 為n/2+1,即過半選舉
2、discovery.zen.ping.timeout可以設定的大一些,不是說一旦通訊失敗立馬認為節點掛掉,可以延遲認為掛掉的時間