Elasticsearch ES索引

ES是一個基於RESTful web接口而且構建在Apache Lucene之上的開源分佈式搜索引擎。
同時ES仍是一個分佈式文檔數據庫,其中每一個字段都可被索引,並且每一個字段的數據都可被搜索,可以橫向擴展至數以百計的服務器存儲以及處理PB級的數據。
能夠在極短的時間內存儲、搜索和分析大量的數據。一般做爲具備複雜搜索場景狀況下的核心發動機。
ES就是爲高可用和可擴展而生的。一方面能夠經過升級硬件來完成系統擴展,稱爲垂直或向上擴展(Vertical Scale/Scaling Up)。
另外一方面,增長更多的服務器來完成系統擴展,稱爲水平擴展或者向外擴展(Horizontal Scale/Scaling Out)。儘管ES可以利用更強勁的硬件,可是垂直擴展畢竟仍是有它的極限。真正的可擴展性來自於水平擴展,經過向集羣中添加更多的節點來分擔負載,增長可靠性。ES天生就是分佈式的,它知道如何管理多個節點來完成擴展和實現高可用性。意味應用不須要作任何的改動。
 
Gateway,表明ES索引的持久化存儲方式。在Gateway中,ES默認先把索引存儲在內存中,而後當內存滿的時候,再持久化到Gateway裏。當ES集羣關閉或重啓的時候,它就會從Gateway裏去讀取索引數據。好比LocalFileSystem和HDFS、AS3等。
DistributedLucene Directory,它是Lucene裏的一些列索引文件組成的目錄。它負責管理這些索引文件。包括數據的讀取、寫入,以及索引的添加和合並等。
River,表明是數據源。是以插件的形式存在於ES中。 
Mapping,映射的意思,很是相似於靜態語言中的數據類型。好比咱們聲明一個int類型的變量,那之後這個變量只能存儲int類型的數據。好比咱們聲明一個double類型的mapping字段,則只能存儲double類型的數據。
Mapping不只是告訴ES,哪一個字段是哪一種類型。還能告訴ES如何來索引數據,以及數據是否被索引到等。
Search Moudle,搜索模塊,支持搜索的一些經常使用操做
Index Moudle,索引模塊,支持索引的一些經常使用操做
Disvcovery,主要是負責集羣的master節點發現。好比某個節點忽然離開或進來的狀況,進行一個分片從新分片等。這裏有個發現機制。
發現機制默認的實現方式是單播和多播的形式,即Zen,同時也支持點對點的實現。另一種是以插件的形式,即EC2。
Scripting,即腳本語言。包括不少,這裏很少贅述。如mvel、js、python等。   
Transport,表明ES內部節點,表明跟集羣的客戶端交互。包括 Thrift、Memcached、Http等協議
RESTful Style API,經過RESTful方式來實現API編程。
3rd plugins,表明第三方插件。
Java(Netty),是開發框架。
JMX,是監控。
使用案例
一、將ES做爲網站的主要後端系統
好比如今搭建一個博客系統,對於博客帖子的數據能夠直接在ES上存儲,而且使用ES來進行檢索,統計。ES提供了持久化的存儲、統計和不少其餘數據存儲的特性。
注意:可是像其餘的NOSQL數據存儲同樣,ES是不支持事務的,若是要事務機制,仍是考慮使用其餘的數據庫作真實庫。
 
二、將ES添加到現有系統
有些時候不須要ES提供全部數據的存儲功能,只是想在一個數據存儲的基礎之上使用ES。好比已經有一個複雜的系統在運行,可是如今想加一個搜索的功能,就可使用該方案。
 
三、將ES做爲現有解決方案的後端部分
由於ES是開源的系統,提供了直接的HTTP接口,而且如今有一個大型的生態系統在支持他。好比如今咱們想部署大規模的日誌框架、用於存儲、搜索和分析海量的事件,考慮到現有的工具能夠寫入和讀取ES,能夠不須要進行任何開發,配置這些工具就能夠去運做。
 
設計結構
一、邏輯設計
文檔
文檔是能夠被索引的信息的基本單位,它包含幾個重要的屬性:
是自我包含的。一篇文檔同時包含字段和他們的取值。
是層次型的。文檔中還能夠包含新的文檔,一個字段的取值能夠是簡單的,例如location字段的取值能夠是字符串,還能夠包含其餘字段和取值,好比能夠同時包含城市和街道地址。
擁有靈活的結構。文檔不依賴於預先定義的模式。也就是說並不是全部的文檔都須要擁有相同的字段,並不受限於同一個模式
{
  "name":"meeting",
  "location":"office",
  "organizer":"yanping"
}
{
  "name":"meeting",
  "location":{
    "name":"sheshouzuo",
       "date":"2019-6-28"
  },
  "memebers":["leio","shiyi"]
}
類型
類型是文檔的邏輯容器,相似於表格是行的容器。在不一樣的類型中,最好放入不一樣的結構的文檔。
字段
ES中,每一個文檔,實際上是以json形式存儲的。而一個文檔能夠被視爲多個字段的集合。
映射
每一個類型中字段的定義稱爲映射。例如,name字段映射爲String。
索引
索引是映射類型的容器一個ES的索引很是像關係型世界中的數據庫,是獨立的大量文檔集合。
 
關係型數據庫與ES的結構上的對比
 
 
二、物理設計
節點
一個節點是一個ES的實例,在服務器上啓動ES以後,就擁有了一個節點,若是在另外一個服務器上啓動ES,這就是另外一個節點。甚至能夠在一臺服務器上啓動多個ES進程,在一臺服務器上擁有多個節點。多個節點能夠加入同一個集羣。
當ElasticSearch的節點啓動後,它會利用多播(multicast)(或者單播,若是用戶更改了配置)尋找集羣中的其它節點,並與之創建鏈接。這個過程以下圖所示:
 
節點主要有3種類型,第一種類型是client_node,主要是起到請求分發的做用,相似路由。第二種類型是master_node,是主的節點,全部的新增,刪除,數據分片都是由主節點操做(elasticsearch底層是沒有更新數據操做的,上層對外提供的更新其實是刪除了再新增),固然也能承擔搜索操做。第三種類型是date_node,該類型的節點只能作搜索操做,具體會分配到哪一個date_node,就是由client_node決定,而data_node的數據都是從master_node同步過來的
分片
一個索引能夠存儲超出單個結點硬件限制的大量數據。好比,一個具備10億文檔的索引佔據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢。
 
爲了解決這個問題,ES提供了將索引劃分紅多份的能力,這些份就叫作分片。當你建立一個索引的時候,你能夠指定你想要的分片的數量。每一個分片自己也是一個功能完善而且獨立的「索引」,這個「索引」能夠被放置到集羣中的任何節點上。
分片之因此重要,主要有兩方面的緣由:
 
一、容許你水平分割/擴展你的內容容量
容許你在分片(潛在地,位於多個節點上)之上進行分佈式的、並行的操做,進而提升性能/吞吐量
至於一個分片怎樣分佈,它的文檔怎樣聚合回搜索請求,是徹底由ES管理的,對於做爲用戶的你來講,這些都是透明的。
 
二、在一個網絡/雲的環境裏,失敗隨時均可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者因爲任何緣由消失了。這種狀況下,有一個故障轉移機制是很是有用而且是強烈推薦的。爲此目的,ES容許你建立分片的一份或多份拷貝,這些拷貝叫作複製分片,或者直接叫複製。
複製之因此重要,主要有兩方面的緣由:
(1)在分片/節點失敗的狀況下,提供了高可用性。由於這個緣由,注意到複製分片從不與原/主要(original/primary)分片置於同一節點上是很是重要的。
(2)擴展你的搜索量/吞吐量,由於搜索能夠在全部的複製上並行運行
總之,每一個索引能夠被分紅多個分片。一個索引也能夠被複制0次(意思是沒有複製)或屢次。一旦複製了,每一個索引就有了主分片(做爲複製源的原來的分片)和複製分片(主分片的拷貝)之別。分片和複製的數量能夠在索引建立的時候指定。在索引建立以後,你能夠在任什麼時候候動態地改變複製數量,可是不能改變分片的數量。
 
默認狀況下,ES中的每一個索引被分片5個主分片和1個複製,這意味着,若是你的集羣中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個徹底拷貝),這樣的話每一個索引總共就有10個分片。一個索引的多個分片能夠存放在集羣中的一臺主機上,也能夠存放在多臺主機上,這取決於你的集羣機器數量。主分片和複製分片的具體位置是由ES內在的策略所決定的。
三、插件HEAD
elasticsearch-head是一個界面化的集羣操做和管理工具
 
● node:即一個 Elasticsearch 的運行實例,使用多播或單播方式發現 cluster 並加入。
● cluster:包含一個或多個擁有相同集羣名稱的 node,其中包含一個master node。
● index:類比關係型數據庫裏的DB,是一個邏輯命名空間。
● alias:能夠給 index 添加零個或多個alias,經過 alias 使用index 和根據index name 訪問index同樣,可是,alias給咱們提供了一種切換index的能力,好比重建了index,取名● customer_online_v2,這時,有了alias,我要訪問新 index,只須要把 alias 添加到新 index 便可,並把alias從舊的 index 刪除。不用修改代碼。
● type:類比關係數據庫裏的Table。其中,一個index能夠定義多個type,但通常使用習慣僅配一個type。
● mapping:類比關係型數據庫中的 schema 概念,mapping 定義了 index 中的 type。mapping 能夠顯示的定義,也能夠在 document 被索引時自動生成,若是有新的 field,Elasticsearch 會自動推測出 field 的type並加到mapping中。
● document:類比關係數據庫裏的一行記錄(record),document 是 Elasticsearch 裏的一個 JSON 對象,包括零個或多個field。
● field:類比關係數據庫裏的field,每一個field 都有本身的字段類型。
● shard:是一個Lucene 實例。Elasticsearch 基於 Lucene,shard 是一個 Lucene 實例,被 Elasticsearch 自動管理。以前提到,index 是一個邏輯命名空間,shard 是具體的物理概念,建索引、查詢等都是具體的shard在工做。shard 包括primary shard 和 replica shard,寫數據時,先寫到primary shard,而後,同步到replica shard,查詢時,primary 和 replica 充當相同的做用。replica shard 能夠有多份,也能夠沒有,replica shard的存在有兩個做用,一是容災,若是primary shard 掛了,數據也不會丟失,集羣仍然能正常工做;二是提升性能,由於replica 和 primary shard 都能處理查詢。另外,如上圖右側紅框所示,shard數和replica數均可以設置,可是,shard 數只能在創建index 時設置,後期不能更改,可是,replica 數能夠隨時更改。可是,因爲 Elasticsearch 很友好的封裝了這部分,在使用Elasticsearch 的過程當中,咱們通常僅須要關注 index 便可,不需關注shard。
 
shard、node、cluster 在物理上構成了 Elasticsearch 集羣,field、type、index 在邏輯上構成一個index的基本概念,在使用 Elasticsearch 過程當中,咱們通常關注到邏輯概念就好,就像咱們在使用MySQL 時,咱們通常就關注DB Name、Table和schema便可,而不會關注DBA維護了幾個MySQL實例、master 和 slave 等怎麼部署的同樣。
ES中的索引原理
(1)傳統的關係型數據庫
二叉樹查找效率是logN,同時插入新的節點沒必要移動所有節點,因此用樹型結構存儲索引,能同時兼顧插入和查詢的性能。所以在這個基礎上,再結合磁盤的讀取特性(順序讀/隨機讀),傳統關係型數據庫採用了B-Tree/B+Tree這樣的數據結構作索引
(2)ES
採用倒排索引
那麼,倒排索引是個什麼樣子呢?
 
首先,來搞清楚幾個概念,爲此,舉個例子:
假設有個user索引,它有四個字段:分別是name,gender,age,address。畫出來的話,大概是下面這個樣子,跟關係型數據庫同樣
 
Term(單詞):一段文本通過分析器分析之後就會輸出一串單詞,這一個一個的就叫作Term
Term Dictionary(單詞字典):顧名思義,它裏面維護的是Term,能夠理解爲Term的集合
Term Index(單詞索引):爲了更快的找到某個單詞,咱們爲單詞創建索引
Posting List(倒排列表):倒排列表記錄了出現過某個單詞的全部文檔的文檔列表及單詞在該文檔中出現的位置信息,每條記錄稱爲一個倒排項(Posting)。根據倒排列表,便可獲知哪些文檔包含某個單詞。(PS:實際的倒排列表中並不僅是存了文檔ID這麼簡單,還有一些其它的信息,好比:詞頻(Term出現的次數)、偏移量(offset)等,能夠想象成是Python中的元組,或者Java中的對象)
(PS:若是類比現代漢語詞典的話,那麼Term就至關於詞語,Term Dictionary至關於漢語詞典自己,Term Index至關於詞典的目錄索引)
咱們知道,每一個文檔都有一個ID,若是插入的時候沒有指定的話,Elasticsearch會自動生成一個,所以ID字段就很少說了
上面的例子,Elasticsearch創建的索引大體以下:
name字段:
 
age字段:
 
gender字段:
 
address字段:
 
Elasticsearch分別爲每一個字段都創建了一個倒排索引。好比,在上面「張三」、「北京市」、22 這些都是Term,而[1,3]就是Posting List。Posting list就是一個數組,存儲了全部符合某個Term的文檔ID。
只要知道文檔ID,就能快速找到文檔。但是,要怎樣經過咱們給定的關鍵詞快速找到這個Term呢?
固然是建索引了,爲Terms創建索引,最好的就是B-Tree索引(MySQL就是B樹索引最好的例子)。
咱們查找Term的過程跟在MyISAM中記錄ID的過程大體是同樣的
MyISAM中,索引和數據是分開,經過索引能夠找到記錄的地址,進而能夠找到這條記錄
在倒排索引中,經過Term索引能夠找到Term在Term Dictionary中的位置,進而找到Posting List,有了倒排列表就能夠根據ID找到文檔了
(PS:能夠這樣理解,類比MyISAM的話,Term Index至關於索引文件,Term Dictionary至關於數據文件)
(PS:其實,前面咱們分了三步,咱們能夠把Term Index和Term Dictionary當作一步,就是找Term。所以,能夠這樣理解倒排索引:經過單詞找到對應的倒排列表,根據倒排列表中的倒排項進而能夠找到文檔記錄)
爲了更進一步理解,用兩張圖來具現化這一過程:
 https://blog.csdn.net/zhenwei1994/article/details/94013059
相關文章
相關標籤/搜索