在前幾篇關於ElasticSearch的文章中,簡單的講了下有關ElasticSearch的一些使用,這篇文章講一下有關 ElasticSearch的一些理論知識以及本身的一些看法。
雖然本人是一個實戰派,不太喜歡講這些理論知識,由於這塊能夠查看官方文檔,那裏會寫得很是詳細,可是在使用了ElasticSearch以後,發現有的知識點須要掌握必定的理論知識才能理解,對於初學者來講有的很差理解,所以寫下該篇文章,但願讀者在看完以後可以有所幫助。html
Elasticsearch 是一個基於JSON的分佈式搜索和分析引擎。它能夠從RESTful Web服務接口訪問,並使用模式少JSON(JavaScript對象符號)文檔來存儲數據。它是基於Java編程語言,這使Elasticsearch可以在不一樣的平臺上運行。使用戶可以以很是快的速度來搜索很是大的數據量。node
- 分佈式的實時文件存儲,每一個字段都被索引並可被搜索
- 分佈式的實時分析搜索引擎
- 能夠擴展到上百臺服務器,處理PB級結構化或非結構化數據
ApacheLucene將寫入索引的全部信息組織成一種倒排索引(Inverted Index)的結構之中,該結構是種將詞項映射到文檔的數據結構。其工做方式與傳統的關係數據庫不一樣,大體來講倒排索引是面向詞項而不是面向文檔的。且Lucene索引之中還存儲了不少其餘的信息,如詞向量等等,每一個Lucene都是由多個段構成的,每一個段只會被建立一次但會被查詢屢次,段一旦建立就不會再被修改。多個段會在段合併的階段合併在一塊兒,什麼時候合併由Lucene的內在機制決定,段合併後數量會變少,可是相應的段自己會變大。段合併的過程是很是消耗I/O的,且與之同時會有些再也不使用的信息被清理掉。在Lucene中,將數據轉化爲倒排索引,將完整串轉化爲可用於搜索的詞項的過程叫作分析。文本分析由分析器(Analyzer)來執行,分析其由分詞器(Tokenizer),過濾器(Filter)和字符映射器(Character Mapper)組成,其各個功能顯而易見。數據庫
「ELK」是三個開源項目的首字母縮寫,這三個項目分別是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一個搜索和分析引擎。Logstash 是服務器端數據處理管道,可以同時從多個來源採集數據,轉換數據,而後將數據發送到諸如 Elasticsearch 等「存儲庫」中。Kibana 則可讓用戶在 Elasticsearch 中使用圖形和圖表對數據進行可視化。編程
一個集羣由一個或多個共享相同的羣集名稱的節點組成。每一個羣集有一個單獨的主節點,這是由程序自動選擇,若是當前主節點失敗,程序會自動選擇其餘節點做爲主節點。api
一個節點屬於一個集羣。一般狀況下一個服務器有一個節點,但有時候爲了測試方便,一臺服務器也能夠有多個節點。在啓動時,一個節點將使用廣播來發現具備相同羣集名稱的現有羣集,並將嘗試加入該羣集。節點屬性根據elasticsearch.yml的一些配置來決定!其中master和datanode是必不可少的,其餘的能夠按照狀況來進行添加!爲了防止腦裂以及後續維護,建議將節點屬性分離!數組
elasticsearch.yml配置:緩存
node.master: true 而且 node.data: true
這種組合表示這個節點即有成爲主節點的資格,又存儲數據。
若是某個節點被選舉成爲了真正的主節點,那麼他還要存儲數據,這樣對於這個節點的壓力就比較大了。ElasticSearch默認每一個節點都是這樣的配置,在測試環境下這樣作沒問題。實際工做中建議不要這樣設置,由於這樣至關於主節點和數據節點的角色混合到一塊了。服務器
node.master: false 而且 node.data: true
這種組合表示這個節點沒有成爲主節點的資格,也就不參與選舉,只會存儲數據。 這個節點咱們稱爲data(數據)節點。在集羣中須要單獨設置幾個這樣的節點負責存儲數據,後期提供存儲和查詢服務。數據結構
node.master: true 而且 node.data: false
這種組合表示這個節點不會存儲數據,有成爲主節點的資格,能夠參與選舉,有可能成爲真正的主節點,這個節點咱們稱爲master節點。架構
node.master: false node.data: false
這種組合表示這個節點即不會成爲主節點,也不會存儲數據,這個節點的意義是做爲一個client(客戶端)節點,主要是針對海量請求的時候能夠進行負載均衡。
node.ingest: true
執行預處理管道,不負責數據和集羣相關的事物。
它在索引以前預處理文檔,攔截文檔的bulk和index請求,而後加以轉換。
將文檔傳回給bulk和index API,用戶能夠定義一個管道,指定一系列的預處理器。
示例圖:
上述的節點屬性能夠根據實際的狀況來進行配置。若是隻有三臺配置通常的服務器,在測試環境能夠將master節點和datanode節點共用,也就是 node.master: true
而且 node.data: true
;在生產環境中,最好將節點分離,特別是masternode和datanode,哪怕是用配置很是差的服務器安裝masternode。至於clientnode則須要看狀況,若是有大量的查詢,而且有不少的聚合分析查詢的話,能夠部署;ingestnode這個也是看具體的狀況,若是有使用ingest等api的狀況,也能夠進行部署。至於集羣規劃這個咱們在後續的文章中再來說解。
索引是Elasticsearch對邏輯數據的邏輯存儲,因此它能夠分爲更小的部分。你能夠把索引當作關係型數據庫的表。然而,索引的結構是爲快速有效的全文索引準備的,特別是它不存儲原始值。若是你知道MongoDB,能夠Elasticsearch的索引當作MongoDB裏的一個集合。若是你熟悉CouchDB,能夠把索引當作CouchDB數據庫索引。Elasticsearch能夠把索引存放在一臺機器或者分散在多臺服務器上,每一個索引有一或多個分片(shard),每一個分片能夠有多個副本(replica)。
根據
Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields
可是根據最新的ElasticSearch7.x中已經將Types移除了,而且在平常的使用中,我建議最好把一個索引(index)當作數據庫的一張表來使用,類型(type)除了必要的狀況,最好無視它,將它和索引庫名設置同樣便可。
這裏順便再來講下建立索引庫的結構。咱們知道在關係型數據庫中須要建立表才能添加數據,可是在ElasticSearch中能夠直接插入數據,它會根據你的第一條數據來自動建立索引庫的結構, 可是這種在不少狀況下是不符合咱們要求的。若是咱們想本身進行建立的話,那麼就有必要了解一下index的setting和mapping了。
setting
setting能夠理解爲管理這個index的一些重要屬性的,好比分片(shard)和副本(replica),它決定這個索引庫最終的配置形態。初學者的話,能夠只用管這三個配置參數便可:
mapping
mapping能夠理解爲關係型數據庫的表結構,指定字段的類型。初學者能夠先只用關心text、keyword、byte、short、integer、long、float、double、boolean、date
這幾個字段,其中text和keyword都是string類型,選擇區分很簡單,須要進行分詞用text,不須要而且進行排序或聚合的能夠用keyword。
分片是一個單一的Lucene實例。這個是由Elasticsearch管理的比較底層的功能。索引是指向主分片和副本分片的邏輯空間。對於使用,只須要指定分片的數量,其餘不須要作過多的事情。在開發使用的過程當中,咱們對應的對象都是索引,Elasticsearch會自動管理集羣中全部的分片,當發生故障的時候,一個Elasticsearch會把分片移動到不一樣的節點或者添加新的節點。
主分片(primary shard):每一個文檔都存儲在一個分片中,當你存儲一個文檔的時候,系統會首先存儲在主分片中,而後會複製到不一樣的副本中。默認狀況下,一個索引有5個主分片。你能夠在事先制定分片的數量,當分片一旦創建,分片的數量則不能修改。
副本分片(replica shard):每個分片有零個或多個副本。副本主要是主分片的複製,其中有兩個目的:
一、增長高可用性:當主分片失敗的時候,能夠從副本分片中選擇一個做爲主分片。
二、提升性能:當查詢的時候能夠到主分片或者副本分片中進行查詢。默認狀況下,一個主分配有一個副本,但副本的數量能夠在後面動態的配置增長。副本必須部署在不一樣的節點上,不能部署在和主分片相同的節點上。
分片設置很重要!一個index指定了分片以後是沒法修改的,所以在設置分片的時候必定要事前作好規劃!
示例圖:
存儲在Elasticsearch中的主要實體叫文檔(document)。用關係型數據庫來類比的話,一個文檔至關於數據庫表中的一行記錄。當比較Elasticsearch中的文檔和MongoDB中的文檔,你會發現二者均可以有不一樣的結構,但Elasticsearch的文檔中,相同字段必須有相同類型。這意味着,全部包含 title 字段的文檔, title 字段類型都必須同樣,好比 string 。
文檔由多個字段組成,每一個字段可能屢次出如今一個文檔裏,這樣的字段叫多值字段(multivalued)。每一個字段有類型,如文本、數值、日期等。字段類型也能夠是複雜類型,一個字段包含其餘子文檔或者數組。字段類型在Elasticsearch中很重要,由於它給出了各類操做(如分析或排序)如何被執行的信息。幸虧,這能夠自動肯定,然而,咱們仍然建議使用映射。與關係型數據庫不一樣,文檔不須要有固定的結構,每一個文檔能夠有不一樣的字段,此外,在程序開發期間,沒必要肯定有哪些字段。固然,能夠用模式強行規定文檔結構。從客戶端的角度看,文檔是一個JSON對象。每一個文檔存儲在一個索引中並有一個Elasticsearch自動生成的惟一標識符和文檔類型。文檔須要有對應文檔類型的惟一標識符,這意味着在一個索引中,兩個不一樣類型的文檔能夠有相同的惟一標識符。
- 核心數據類型
text 和 keyword- 數值數據類型
long,integer,short,byte,double,float,half_float,scaled_float- 日期數據類型
date- 布爾數據類型
boolean- 二進制數據類型
binary範圍數據類型
integer_range,float_range,long_range,double_range,date_range- 複雜數據類型
- 對象數據類型
object 用於單個JSON對象嵌套數據類型
nested 用於JSON對象數組- 地理數據類型
- 地理位置數據類型
geo_point 緯度/經度積分地理形狀數據類型
geo_shape 用於多邊形等複雜形狀- 專業數據類型
- IP數據類型
ip 用於IPv4和IPv6地址- 完成數據類型
completion 提供自動完成建議- 令牌計數數據類型
token_count 計算字符串中令牌的數量
mapper-murmur3
murmur3 在索引時計算值的哈希並將其存儲在索引中
mapper-annotated-text
annotated-text 索引包含特殊標記的文本(一般用於標識命名實體)- 滲濾器類型
接受來自query-dsl的查詢- join 數據類型
爲同一索引內的文檔定義父/子關係別名數據類型
爲現有字段定義別名。多字段:
爲不一樣的目的以不一樣的方式對同一字段創建索引一般頗有用。例如,一個string字段能夠映射爲text用於全文搜索的字段,也能夠映射爲keyword用於排序或聚合的字段。或者,您可使用standard分析儀, english分析儀和 french分析儀索引文本字段。
這是多領域的目的。大多數數據類型經過fields參數支持多字段。
映射:
在有關全文搜索基礎知識部分,咱們提到了分析的過程:爲建索引和搜索準備輸入文本。文檔中的每一個字段都必須根據不一樣類型作相應的分析。舉例來講,對數值字段和從網頁抓取的文本字段有不一樣的分析,好比前者的數字不該該按字母順序排序,後者的第一步是忽略HTML標籤,由於它們是無用的信息噪音。Elasticsearch在映射中存儲有關字段的信息。
別名(alias):
它是一個或多個索引的一個附加名稱,容許使用這個名稱來查詢索引。一個別名能夠對應多個索引,反之亦然,一個索引能夠是多個別名的一部分。別名只能用做查詢,不能進行數據操做!
示例圖:
本文主要介紹了ElasticSearch的一些基礎知識,其中ElasticSearch的理論知識遠遠不止這些,可是介紹的太多的話吸取不過來,其實不少的知識最好是邊學邊用中在掌握。學習ElasticSearch知識理論能夠去官網學習,那裏有很是詳細的知識。
以後或許會寫一篇關於ElasticSearch的集羣規劃,會從案例中進行講解,包括機器、節點、索引庫、分片副本一些選擇和配置的一些具體知識。
參考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
參考書籍:
《ElasticSearch權威指南》
ElasticSearch實戰系列:
ElasticSearch實戰系列一: ElasticSearch集羣+Kinaba安裝教程
ElasticSearch實戰系列二: ElasticSearch的DSL語句使用教程---圖文詳解
ElasticSearch實戰系列三: ElasticSearch的JAVA API使用教程
原創不易,若是感受不錯,但願給個推薦!您的支持是我寫做的最大動力!
版權聲明:
做者:虛無境
博客園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm
掘金出處:https://juejin.im/user/5ae45d5bf265da0b8a6761e4
我的博客出處:http://www.panchengming.com