ElasticSearch實戰系列四: ElasticSearch理論知識介紹

前言

在前幾篇關於ElasticSearch的文章中,簡單的講了下有關ElasticSearch的一些使用,這篇文章講一下有關 ElasticSearch的一些理論知識以及自己的一些見解。
雖然本人是一個實戰派,不太喜歡講這些理論知識,因爲這塊可以查看官方文檔,那裏會寫得非常詳細,但是在使用了ElasticSearch之後,發現有的知識點需要掌握一定的理論知識才能理解,對於初學者來說有的不好理解,因此寫下該篇文章,希望讀者在看完之後能夠有所幫助。

ElasticSearch 理論知識介紹

ElasticSearch是什麼

Elasticsearch 是一個基於JSON的分佈式搜索和分析引擎。它可以從RESTful Web服務接口訪問,並使用模式少JSON(JavaScript對象符號)文檔來存儲數據。它是基於Java編程語言,這使Elasticsearch能夠在不同的平臺上運行。使用戶能夠以非常快的速度來搜索非常大的數據量。

ElasticSearch可以做什麼

  • 分佈式的實時文件存儲,每個字段都被索引並可被搜索
  • 分佈式的實時分析搜索引擎
  • 可以擴展到上百臺服務器,處理PB級結構化或非結構化數據

Lucene是什麼

ApacheLucene將寫入索引的所有信息組織成一種倒排索引(Inverted Index)的結構之中,該結構是種將詞項映射到文檔的數據結構。其工作方式與傳統的關係數據庫不同,大致來說倒排索引是面向詞項而不是面向文檔的。且Lucene索引之中還存儲了很多其他的信息,如詞向量等等,每個Lucene都是由多個段構成的,每個段只會被創建一次但會被查詢多次,段一旦創建就不會再被修改。多個段會在段合併的階段合併在一起,何時合併由Lucene的內在機制決定,段合併後數量會變少,但是相應的段本身會變大。段合併的過程是非常消耗I/O的,且與之同時會有些不再使用的信息被清理掉。在Lucene中,將數據轉化爲倒排索引,將完整串轉化爲可用於搜索的詞項的過程叫做分析。文本分析由分析器(Analyzer)來執行,分析其由分詞器(Tokenizer),過濾器(Filter)和字符映射器(Character Mapper)組成,其各個功能顯而易見。

Elk架構

“ELK”是三個開源項目的首字母縮寫,這三個項目分別是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一個搜索和分析引擎。Logstash 是服務器端數據處理管道,能夠同時從多個來源採集數據,轉換數據,然後將數據發送到諸如 Elasticsearch 等“存儲庫”中。Kibana 則可以讓用戶在 Elasticsearch 中使用圖形和圖表對數據進行可視化。

ElasticSearch名詞

集羣(cluster)

一個集羣由一個或多個共享相同的羣集名稱的節點組成。每個羣集有一個單獨的主節點,這是由程序自動選擇,如果當前主節點失敗,程序會自動選擇其他節點作爲主節點。

節點(node)

一個節點屬於一個集羣。通常情況下一個服務器有一個節點,但有時候爲了測試方便,一臺服務器也可以有多個節點。在啓動時,一個節點將使用廣播來發現具有相同羣集名稱的現有羣集,並將嘗試加入該羣集。節點屬性根據elasticsearch.yml的一些配置來決定!其中master和datanode是必不可少的,其他的可以按照情況來進行添加!爲了防止腦裂以及後續維護,建議將節點屬性分離!

elasticsearch.yml配置:

  1. node.master: true 並且 node.data: true
    這種組合表示這個節點即有成爲主節點的資格,又存儲數據。
    如果某個節點被選舉成爲了真正的主節點,那麼他還要存儲數據,這樣對於這個節點的壓力就比較大了。ElasticSearch默認每個節點都是這樣的配置,在測試環境下這樣做沒問題。實際工作中建議不要這樣設置,因爲這樣相當於主節點和數據節點的角色混合到一塊了。

  2. node.master: false 並且 node.data: true
    這種組合表示這個節點沒有成爲主節點的資格,也就不參與選舉,只會存儲數據。 這個節點我們稱爲data(數據)節點。在集羣中需要單獨設置幾個這樣的節點負責存儲數據,後期提供存儲和查詢服務。

  3. node.master: true 並且 node.data: false
    這種組合表示這個節點不會存儲數據,有成爲主節點的資格,可以參與選舉,有可能成爲真正的主節點,這個節點我們稱爲master節點。

  4. node.master: false node.data: false
    這種組合表示這個節點即不會成爲主節點,也不會存儲數據,這個節點的意義是作爲一個client(客戶端)節點,主要是針對海量請求的時候可以進行負載均衡。

  5. node.ingest: true
    執行預處理管道,不負責數據和集羣相關的事物。
    它在索引之前預處理文檔,攔截文檔的bulk和index請求,然後加以轉換。
    將文檔傳回給bulk和index API,用戶可以定義一個管道,指定一系列的預處理器。

示例圖:

在這裏插入圖片描述

上述的節點屬性可以根據實際的情況來進行配置。如果只有三臺配置一般的服務器,在測試環境可以將master節點和datanode節點共用,也就是 node.master: true 並且 node.data: true ;在生產環境中,最好將節點分離,特別是masternode和datanode,哪怕是用配置非常差的服務器安裝masternode。至於clientnode則需要看情況,如果有大量的查詢,並且有很多的聚合分析查詢的話,可以部署;ingestnode這個也是看具體的情況,如果有使用ingest等api的情況,也可以進行部署。至於集羣規劃這個我們在後續的文章中再來講解。

索引(index)

索引是Elasticsearch對邏輯數據的邏輯存儲,所以它可以分爲更小的部分。你可以把索引看成關係型數據庫的表。然而,索引的結構是爲快速有效的全文索引準備的,特別是它不存儲原始值。如果你知道MongoDB,可以Elasticsearch的索引看成MongoDB裏的一個集合。如果你熟悉CouchDB,可以把索引看成CouchDB數據庫索引。Elasticsearch可以把索引存放在一臺機器或者分散在多臺服務器上,每個索引有一或多個分片(shard),每個分片可以有多個副本(replica)。

根據<ElasticSearch權威指南>將ElasticSearch和傳統關係型數據庫作比較的話如下類比表:

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),它決定這個索引庫最終的配置形態。初學者的話,可以只用管這三個配置參數即可:

  • number_of_shards: 是設置的分片數,設置之後無法更改!
  • refresh_interval: 是設置es緩存的刷新時間,如果寫入較爲頻繁,但是查詢對實時性要求不那麼高的話,可以設置高一些來提升性能。可以更改
  • number_of_replicas : 是設置該索引庫的副本數,建議設置爲1以上。

mapping

mapping可以理解爲關係型數據庫的表結構,指定字段的類型。初學者可以先只用關心text、keyword、byte、short、integer、long、float、double、boolean、date這幾個字段,其中text和keyword都是string類型,選擇區分很簡單,需要進行分詞用text,不需要並且進行排序或聚合的可以用keyword。

分片(shard)

分片是一個單一的Lucene實例。這個是由Elasticsearch管理的比較底層的功能。索引是指向主分片和副本分片的邏輯空間。對於使用,只需要指定分片的數量,其他不需要做過多的事情。在開發使用的過程中,我們對應的對象都是索引,Elasticsearch會自動管理集羣中所有的分片,當發生故障的時候,一個Elasticsearch會把分片移動到不同的節點或者添加新的節點。

  • 主分片(primary shard):每個文檔都存儲在一個分片中,當你存儲一個文檔的時候,系統會首先存儲在主分片中,然後會複製到不同的副本中。默認情況下,一個索引有5個主分片。你可以在事先制定分片的數量,當分片一旦建立,分片的數量則不能修改。

  • 副本分片(replica shard):每一個分片有零個或多個副本。副本主要是主分片的複製,其中有兩個目的:

    1、增加高可用性:當主分片失敗的時候,可以從副本分片中選擇一個作爲主分片。
    2、提高性能:當查詢的時候可以到主分片或者副本分片中進行查詢。默認情況下,一個主分配有一個副本,但副本的數量可以在後面動態的配置增加。副本必須部署在不同的節點上,不能部署在和主分片相同的節點上。

分片設置很重要!一個index指定了分片之後是無法修改的,因此在設置分片的時候一定要事前做好規劃!

示例圖:在這裏插入圖片描述

文檔

存儲在Elasticsearch中的主要實體叫文檔(document)。用關係型數據庫來類比的話,一個文檔相當於數據庫表中的一行記錄。當比較Elasticsearch中的文檔和MongoDB中的文檔,你會發現兩者都可以有不同的結構,但Elasticsearch的文檔中,相同字段必須有相同類型。這意味着,所有包含 title 字段的文檔, title 字段類型都必須一樣,比如 string 。
文檔由多個字段組成,每個字段可能多次出現在一個文檔裏,這樣的字段叫多值字段(multivalued)。每個字段有類型,如文本、數值、日期等。字段類型也可以是複雜類型,一個字段包含其他子文檔或者數組。字段類型在Elasticsearch中很重要,因爲它給出了各種操作(如分析或排序)如何被執行的信息。幸好,這可以自動確定,然而,我們仍然建議使用映射。與關係型數據庫不同,文檔不需要有固定的結構,每個文檔可以有不同的字段,此外,在程序開發期間,不必確定有哪些字段。當然,可以用模式強行規定文檔結構。從客戶端的角度看,文檔是一個JSON對象。每個文檔存儲在一個索引中並有一個Elasticsearch自動生成的唯一標識符和文檔類型。文檔需要有對應文檔類型的唯一標識符,這意味着在一個索引中,兩個不同類型的文檔可以有相同的唯一標識符。

  • 文檔類型:
    在Elasticsearch中,一個索引對象可以存儲很多不同用途的對象。例如,一個博客應用程序可以保存文章和評論。文檔類型讓我們輕易地區分單個索引中的不同對象。每個文檔可以有不同的結構,但在實際部署中,將文件按類型區分對數據操作有很大幫助。當然,需要記住一個限制,不同的文檔類型不能爲相同的屬性設置不同的類型。例如,在同一索引中的所有文檔類型中,一個叫 title 的字段必須具有相同的類型。
  • 核心數據類型
    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在映射中存儲有關字段的信息。

  • 路由(routing):
    當存儲一個文檔的時候,他會存儲在一個唯一的主分片中,具體哪個分片是通過散列值的進行選擇。默認情況下,這個值是由文檔的id生成。如果文檔有一個指定的父文檔,從父文檔ID中生成,該值可以在存儲文檔的時候進行修改。
    這個屬性在學習初期可以不必理會,使用默認即可。在有一定了解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

發佈了116 篇原創文章 · 獲贊 469 · 訪問量 59萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章