ES是基於Lucene構建的開源、分布式、RESTful接口全文搜索引擎。同時它還是一個分布式文檔數據庫,其中每個字段均是被索引的數據且可被搜索,便於擴展,能在短時間內搜索和分析大量數據。
Lucene
Lucene是一個Java全文搜索引擎;僅是一個框架,提供代碼庫和API,並不是完整的應用程序。
倒排索引
倒排索引源於實際應用中需要根據屬性值來查找記錄。這種索引表中每一項都包括一個屬性值和具有該屬性值的各記錄的地址。倒排索引根據屬性值來確定記錄的位置,而不是由記錄來確定屬性值。
倒排索引的關鍵步驟:
-
取得關鍵詞;對文本進行解析,由Analyzer將文章內容拆分成關鍵詞組。
-
建立倒排索引;建立關鍵詞與文章號的對應關系如下圖,三列分別作為詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件(positions)保存,其中詞典文件還保存了指向頻率文件和位置文件的指針。
-
壓縮算法;
-
對詞典文件中關鍵詞進行壓縮,關鍵詞壓縮為<前綴長度,后綴>,例:當前詞為“阿拉伯語”,上一個詞為“阿拉伯”,那么“阿拉伯語”壓縮為<3,語>。
-
對數字進行壓縮,數字只保存與上一個值的差值。例:當前文章號是16389(不壓縮需要3個字節保存),上一文章號是16382,壓縮后保存7(僅用一個字節)。
-
RESTful接口
介紹
-
RESTful是一種架構的規范與約束、原則,符合這種規范的架構就是RESTful架構。
-
RESTful(Representational state transfer)即資源的表述性狀態轉移,通過http動詞來實現資源的轉態轉移。
-
資源是REST系統的核心概念,所有的設計都是以資源為中心。
方法
Get /user:列出所有用戶
POST /user:新建一個用戶
PUT /user:更新指定用戶信息
DELETE /user:刪除指定用戶
工具
-
postman
-
curl
-
kibana
全文搜索
數據分類
-
結構化數據:指具有固定格式或有限長度的數據,如數據庫,元數據等。
-
對於結構化數據,一般使用關系型數據庫(mysql,oracle等)的table方式存儲和搜索,也可建立索引。通過b-tree等數據結構快速搜索數據。
-
-
非結構化數據:全文數據,指不定長或無固定格式的數據,文本數據。
-
對於非結構化數據,即全文數據的搜索主要有兩種方法:順序掃描法,全文搜索法。
-
順序掃描
通過順序掃描的方式查找特定的關鍵字,效率低。
全文搜索
全文搜索是指通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該次在文章中出現的次數和位置,當用戶查詢時,根據索引查找。
ElasticSearch存儲架構解析
集群(cluster)
一個ElasticSearch集群由一個或多個節點(node)組成,每一個集群都有一個共同的集群名稱作為標識,默認是"ElasticSearch"。
節點(node)
-
一個ElasticSearch實例即為一個node,通過node.master、node.data設置節點類型。
-
node.master:表示節點是否能成為主節點
-
true 代表節點能競選主節點
-
false 代表節點不能競選主節點
-
-
node.data:表示節點是否存儲數據
-
node節點組合
-
主節點加數據節點
node.master:true
node.data:true -
數據節點
node.master:false
node.data:true -
客戶端節點
主要應用於海量請求時進行負載均衡。
node.master:false
node.data:false
-
路由(routing)
當存儲一個文檔時,它會存儲在唯一的主分片中,具體哪個分片由路由算法確定。
shard = hash(routing) % number_of_primary_shards
-
routing是一個可變值,默認是文檔的 _id,也可以設置成一個自定義的值。routing通過hash函數生成一個數字,數字再對分片的總數(number_of_primary_shards)取余,這個余數就是文檔所在分片的位置。
分片(Shard)
分片是單個Lucene實例,索引是指向主分片和副本分片的邏輯空間。分片可以理解為存儲數據的最小邏輯單元,每個分片本身是一個全功能的獨立單元,可以托管在集群中的任何節點上。
-
每個ElasticSearch分片是一個Lucene的索引,有文檔存儲數量限制,單一的Lucene索引中最多可存儲2147483519(=integer.max_value-128)個文檔,可使用 _cat/shards API 查詢分片的大小。
一個索引可以存儲很大的數據,針對索引進行分片,可以將大數據分片存儲到多個節點,提高存儲能力和搜索效率。創建索引時可以定義分片數量。
分片的作用:
-
允許水平分割擴展數據。
-
允許分配和並行操作(多節點),提高性能和吞吐量。
主分片(primary shard)
每個文檔都存儲在一個分片中,寫入文檔時,系統會先寫入到主分片,然后復制到不同的副本中。ElasticSearch7.x版本之后默認一個索引創建一個主分片,7.x版本之前默認創建5個主分片,創建索引時可以指定分片數量,當分片一旦建立主分片數量不能修改(路由規則決定修改已建立的分片數量會導致集群無法定位分片位置),副本分片的數量可以改變。
副本分片(replica shard)
每一個主分片可以有零個或多個副本,默認一個。副本分片的作用:
-
增加高可用性:當主分片失敗的時候,可以從副本分片中選擇一個作為主分片。
-
提高性能:查詢時可以到主分片或者副本分片中進行查詢。副本分片不能與主分片部署在同一節點上。
復制(replica)
復制是對分片的拷貝。當新增文檔時會根據設定的副本分片數量復制主分片到其他節點;在網絡中某個節點出現問題時,復制可以對故障進行轉移,保證系統的高可用。
ElasticSearch核心概念介紹
索引詞(term)
在ElasticSearch中索引詞(term)是一個能被索引的精確值。索引詞(term)可以通過term查詢進行准確的搜索。
文本(text)
文本是一段普通的非結構化文字。通常,文本會被分析成一個個的索引詞,存儲在ES的索引庫中。為了讓文本能夠進行搜索,文本字段在存儲時需要預先分析;對文本中關鍵詞進行查詢時,搜索引擎應該根據搜索條件搜索出原文本。
分析(analysis)
分析是將文本轉換為索引詞的過程,分析的結果依賴於分詞器。
-
常用的內置分詞器
-
standard analyzer 默認分詞器
-
simple analyzer
-
whitespace analyzer
-
stop analyzer
-
language analyzer
-
pattern analyzer 可以自定義正則規則進行分詞
-
-
常見中文分詞器
-
smartCN 一個簡單的中文或中英文混合文本分詞器
-
IK分詞器 更智能友好的中文分詞器
-
-
ElasticSearch的分詞原理
-
寫時分詞
-
文檔寫入時會根據字段設置的分詞器類型進行分詞
-
寫時分詞器需要在mapping中指定,一旦指定不能修改,若需修改必須重建索引
-
-
讀時分詞
-
讀時分詞器默認與寫時分詞器保持一致
-
讀時分詞器可以單獨設置,若設置的分詞器與寫時不一致,可能會導致搜索結果難以匹配
-
-
深入分析
-
分析器(analyzer)由三部分組成
-
char filter:字符過濾器
-
tokenizer:分詞器
-
token filter:token過濾器
-
-
char filter(字符過濾器)
字符過濾器以字符流的形式接收原始文本,並可以通過添加、刪除或更改字符來轉換該流。一個分析器可能有0個或多個字符過濾器。
-
tokenizer(分詞器)
一個分詞器接收一個字符流,並將其拆分成單個token(通常是單個單詞),並輸出一個token流。一個分析器只能有一個分詞器。
-
token filter(token過濾器)
一個分詞器接收token流,並且可能會添加、刪除或更改tokens。比如一個lowercase token filter可以將所有的token轉換成小寫。一個分析器可能有0個或多個token過濾器,它們按順序使用。
-
standard分析器
-
tokenizer
Standard tokenizer
-
token filters
-
Standard Token Filter
-
Lower Case Token Filter
-
-
-
-
索引(index)
索引類似於關系數據庫中的數據庫。索引是具有相同結構的文檔集合。例如,可以有一個客戶信息的索引,包含一個產品目錄的索引,一個訂單數據的索引。在系統上索引的名字全部小寫,這個名字可以用來執行索引、搜索、更新和刪除操作等。在單個集群中,可以定義多個索引。
類型(type)
類型類似於關系數據庫中的表。在索引中,可以定義一個或多個類型,類型是索引的邏輯分區。在一般情況下,一種類型被定義為具有一組公共字段的文檔。例如,對於一個博客平台,可以把所有的數據存儲在一個索引中。在此索引中,可以定義一種類型為用戶數據,一種類型為博客數據,一種類型為評論數據。
文檔(document)
映射(mapping)
映射類似於關系數據庫中的表結構,每一個索引都有一個映射,它定義了索引中的每一個字段類型,以及一個索引范圍內的設置。一個映射可以事先定義,也可以在第一次存儲文檔的時候自動識別。
字段(field)
字段類似於關系數據庫中表的列。文檔中包含零個或多個字段,字段可以是一個簡單的值(例如字符串、整數、日期),也可以是一個數組或對象的嵌套結構。每個字段都對應一個字段類型,例如整數、字符串、對象等。字段還可以指定如何分析該字段的值。
來源字段(source field)
默認原文檔將被存儲在_source字段中。
主鍵(ID)
ID是一個文件的唯一標識,如果在存庫的時候未提供ID,系統會自動生成一個ID,文檔的index/type/id必須是唯一的。
ElasticSearch核心數據類型
字符串
-
text
-
用於全文索引,該類型字段將通過分詞器進行分詞
-
-
keyword
-
部分次,只能搜索該字段的完整值
-
數值型
常見數值類型,long,integer,short,byte,double,float,half_float,scaled_float
布爾-boolean
二進制-binary
該類型的字段把值當做經過base64編碼的字符串,默認不存儲、且不可搜索
范圍類型
-
范圍類型表示值是一個范圍,而不是一個具體的值
-
integer_range,float_range,long_range,double_range,date_range
-
例integer_range,{"gte":"20", "lte":40}