這篇文章主要介紹 ElasticSearch 的基本概念,學習文檔、索引、集羣、節點、分片等概念,同時會將 ElasticSearch 和關係型數據庫作簡單的類比,還會簡單介紹 REST API 的使用用法。html
索引和文檔是偏向於邏輯上的概念,節點和分片更偏向於物理上的概念。node
首先來講下什麼是文檔:數據庫
ElasticSearch(簡稱 ES) 是面向文檔的,文檔是全部可搜索數據的最小單位。數組
給你們舉幾個例子,讓你們更形象地理解什麼是文檔:服務器
你們能夠把文檔理解爲關係型數據庫中的一條記錄。markdown
在 ES 中文檔會被序列化成 JSON 格式,保存在 ES 中,JSON 對象由字段組成,其中每一個字段都有對應的字段類型(字符串/數組/布爾/日期/二進制/範圍類型)。數據結構
在 ES 中,每一個文檔都有一個 Unique ID,能夠本身指定 ID 或者經過 ES 自動生成。架構
在上一篇文章手把手教你搭建 ELK 實時日誌分析平臺中,咱們講到了經過 Logstash 向 ES 中導入數據,其中部分測試數據集和對應的轉換後的格式以下所示:app
movieId,title,genres 193585,Flint (2017),Drama 193587,Bungo Stray Dogs: Dead Apple (2018),Action|Animation 193609,Andrew Dice Clay: Dice Rules (1991),Comedy
咱們從測試數據集 csv 文件中讀取一個個的 RowData 的電影數據,而後經過 Logstash 轉換進行轉化之後進入到 ES 中就是 JSON 格式。運維
JSON 每一個字段都有本身的數據類型,ES 能夠幫助你自動作作一個數據類型的推算,而且在 ES 中數據還支持數組和嵌套。
每個文檔都有對應的元數據,用於標註文檔的相關信息,咱們來了解下元數據都有什麼內容:
{ "_index" : "movies", "_type" : "_doc", "_id" : "2035", "_score" : 1.0, "_source" : { "title" : "Blackbeard's Ghost", "genre" : [ "Children", "Comedy" ], "id" : "2035", "@version" : "1", "year" : 1968 } }
其中,_index 表明文檔所屬的索引名;_type 表示文檔所屬的類型名;_id 爲文檔惟一 id;_source 爲文檔的原始 JSON 數據,當搜索文檔的時候默認返回的就是 _source 字段;@version 爲文檔的版本信息,能夠很好地來解決版本衝突的問題;_score 爲相關性打分,是這個文檔在此次查詢中的算分。
介紹完文檔後,讓咱們來看下索引:
索引簡單來講就是類似結構文檔的集合,好比能夠有一個客戶索引,商品分類索引,訂單索引,索引有一個名稱,一個索引能夠包含不少文檔,一個索引就表明了一類相似的或者相同的文檔,好比說創建一個商品索引,裏面可能就存放了全部的商品數據,也就是全部的商品文檔。每個索引都是本身的 Mapping 定義文件,用來去描述去包含文檔字段的類型,分片(Shard)體現的是物理空間的概念,索引中的數據分散在分片上。
在一個的索引當中,能夠去爲它設置 Mapping 和 Setting,Mapping 定義的是索引當中全部文檔字段的類型結構,Setting 主要是指定要用多少的分片以及數據是怎麼樣進行分佈的。
索引在不一樣的上下文會有不一樣的含義,好比,在 ES 當中,索引是一類文檔的集合,這裏就是名詞;同時保存一個文檔到 ES 的過程也叫索引(indexing),拋開 ES,提到索引,還有多是 B 樹索引或者是倒排索引,倒排索引是 ES 中一個重要的數據結構,會在之後的文章進行講解。
接下來對類型進行講解:
在 7.0 以前,每個索引是能夠設置多個 Types 的,每一個 Type 會擁有相同結構的文檔,可是在 6.0 開始,Type 已經被廢除,在 7.0 開始,一個索引只能建立一個 Type,也就是 _doc。
每一個索引裏均可以有一個或多個 Type,Type 是索引中的一個邏輯數據分類,一個 Type 下的文檔,都有相同的字段(Field),好比博客系統,有一個索引,能夠定義用戶數據 Type,博客數據 Type,評論數據 Type 等。
到此爲止,咱們學習了文檔、索引以及類型的概念,接下來學習什麼是集羣?什麼是節點?什麼是分片?
首先來看下集羣的概念。
ES 集羣實際上是一個分佈式系統,要知足高可用性,高可用就是當集羣中有節點服務中止響應的時候,整個服務還能正常工做,也就是服務可用性;或者說整個集羣中有部分節點丟失的狀況下,不會有數據丟失,即數據可用性。
當用戶的請求量愈來愈高,數據的增加愈來愈多的時候,系統須要把數據分散到其餘節點上,最後來實現水平擴展。當集羣中有節點出現問題的時候,整個集羣的服務也不會受到影響。
ES 的分佈架構當中,不一樣的集羣是經過不一樣的名字來區分的,默認的名字爲 elasticsearch,能夠在配置文件中進行修改,或者在命令行中使用 -E cluster.name=wupx 進行設定,一個集羣中能夠有一個或者多個節點。
一個 ES 集羣有三種顏色來表示健康程度:
瞭解完集羣,那麼就來看下什麼是節點。
節點其實就是一個 ES 實例,本質上是一個 Java 進程,一臺機器上能夠運行多個 ES 進程,可是生產環境通常建議一臺機器上只運行一個 ES 實例。
每個節點都有本身的名字,節點名稱很重要(在執行運維管理操做的時候),能夠經過配置文件進行配置,或者啓動的時候 -E node.name=node1 指定。每個節點在啓動以後,會分配一個 UID,保存在 data 目錄下。
默認節點會去加入一個名稱爲 elasticsearch 的集羣,若是直接啓動不少節點,那麼它們會自動組成一個 elasticsearch 集羣,固然一個節點也能夠組成一個 elasticsearch 集羣。
候選主節點(Master-eligible Node) & 主節點(Master Node)
每個節點啓動後,默認就是一個 Master-eligible 節點,能夠經過在配置文件中設置 node.master: false 禁止,Master-eligible 節點能夠參加選主流程,成爲 Master 節點。當第一個節點啓動時候,它會將本身選舉成 Master 節點。
每一個節點上都保存了集羣的狀態,只有 Master 節點才能修改集羣的狀態信息,若是是任意節點都能修改信息就會致使數據的不一致性。
集羣狀態(Cluster State),維護一個集羣中必要的信息,主要包括以下信息:
下面咱們來看下什麼是 Data Node 和 Coordinating Node?
數據節點(Data Node) & 協調節點(Coordinating Node)
顧名思義,能夠保存數據的節點叫做 Data Node,負責保存分片上存儲的全部數據,當集羣沒法保存現有數據的時候,能夠經過增長數據節點來解決存儲上的問題,在數據擴展上有相當重要的做用。
Coordinating Node 負責接收 Client 的請求,將請求分發到合適的節點,最終把結果聚集到一塊兒返回給客戶端,每一個節點默認都起到了 Coordinating Node 的職責。
還有其餘的節點類型,你們能夠了解下:
每一個節點在啓動的時候會經過讀取 elasticsearch.yml 配置文件決定本身承擔什麼樣的角色,那麼讓咱們看下配置節點類型吧!
開發環境中一個節點能夠承擔多種角色。
生產環境中,應該設置單一的角色的節點(dedicated node)。
講完節點,讓咱們來看下什麼是分片?
因爲單臺機器沒法存儲大量數據,ES 能夠將一個索引中的數據切分爲多個分片(Shard),分佈在多臺服務器上存儲。有了分片就能夠橫向擴展,存儲更多數據,讓搜索和分析等操做分佈到多臺服務器上去執行,提高吞吐量和性能。
索引與分片的關係如上圖所示,一個 ES 索引包含不少分片,一個分片是一個 Lucene 的索引,它自己就是一個完整的搜索引擎,能夠獨立執行創建索引和搜索任務。Lucene 索引又由不少分段組成,每一個分段都是一個倒排索引。 ES 每次 refresh 都會生成一個新的分段,其中包含若干文檔的數據。在每一個分段內部,文檔的不一樣字段被單獨創建索引。每一個字段的值由若干詞(Term)組成,Term 是原文本內容通過分詞器處理和語言處理後的最終結果(例如,去除標點符號和轉換爲詞根)。
分片分爲兩類,一類爲主分片(Primary Shard),另外一類爲副本分片(Replica Shard)。
主分片主要用以解決水平擴展的問題,經過主分片,就能夠將數據分佈到集羣上的全部節點上,一個主分片就是一個運行的 Lucene 實例,當咱們在建立 ES 索引的時候,能夠指定分片數,可是主分片數在索引建立時指定,後續不容許修改,除非使用 Reindex 進行修改。
副本分片用以解決數據高可用的問題,也就是說集羣中有節點出現硬件故障的時候,經過副本的方式,也能夠保證數據不會產生真正的丟失,由於副本分片是主分片的拷貝,在索引中副本分片數能夠動態調整,經過增長副本數,能夠在必定程度上提升服務查詢的性能(讀取的吞吐)。
下面經過一個例子來理解下主分片和副本分片是怎麼樣把數據分散在集羣不一樣的節點上的:
PUT /blogs { "settings" :{ "number_of_shards" : 3, "number_of_repicas" : 1 } }
上面是 blogs 索引的定義,其中 settings 中的 number_of_shards 表示主分片數爲 3,number_of_repicas 表示副本只有 1 份。
上圖爲 wupx 的一個集羣,裏面總共有 3 個節點,經過上面對索引 blogs 的配置,當有數據進來的時候,ES 內部就會把主分片分散在三個節點上,同時把每一個分片的副本分散到其餘節點上,當集羣中有節點出現故障,ES 內部就會產生故障轉移的機制,故障轉移機制會在之後的文章進行講解,在上圖中能夠看到三個主分片被分散到三個節點上,若在這個時候爲集羣增長一個節點,是否能夠增長系統的可用性呢?
帶着這個問題,咱們先看下分片的設定:
分片的設定在生產環境中是十分重要的,不少時候須要提早作好容量規劃,由於主分片在索引建立的時候須要預先設定的,而且在過後沒法修改,在前面的例子中,一個索引被分紅了 3 個主分片,這個集羣即使增長再多節點,索引也只能分散在 3 個節點上。
分片設置過大的時候,也會帶來反作用,一方面來講會影響搜索結果的打分,影響統計結果的準確性,另外,單個節點上過多的分片,也會致使資源浪費,同時也會影響性能。從 7.0 版本開始,ES 的默認主分片數設置從 5 改成了 1,從這個方面也能夠解決 over-sharding 的問題。
在瞭解完 ES 的術語後,來和咱們熟悉的關係型數據庫作個類比,以便於咱們理解。
我相信你們對關係型數據庫(簡稱 RDBMS)應該比較瞭解,所以接下來拿關係型數據庫和 ES 作一個類比,讓你們更容易理解:
從表中,不難看出,關係型數據庫和 ES 有以下對應關係:
當進行全文檢索或者對搜索結果進行算分的時候,ES 比較合適,但若是對數據事務性要求比較高的時候,會把關係型數據庫和 ES 結合使用。
爲了方便其餘語言的整合,ES 提供了 REST API 來給其餘程序進行調用,當咱們的程序要和 ES 進行集成的時候,只須要發出 HTTP 的請求就會獲得相應的結果,接下來對基本的 API 進行介紹:
打開 Kibana,咱們首先打開 Kibana 的管理菜單(Management),其中提供索引管理功能,能夠看到索引管理中有 movies 索引,爲上篇文章中導入的,點擊索引,能夠看到索引的 Setting 和 Mapping 信息,如何對其進行設置會在以後的文章會進行介紹。
言歸正傳,來給你們看 REST API:
接下來打開 Kibana 的開發工具(Dev Tools),movies 爲索引,如今輸入 GET movies 點擊執行,就能夠查看電影索引相關的信息,主要包含索引的 Mapping 和 Setting。
輸入 GET movies/_count 點擊執行,就能夠看到索引的文檔總數,運行結果以下:
{ "count" : 9743, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 } }
輸入以下代碼
POST movies/_search { }
點擊執行,就能夠查看前 10 條文檔,瞭解文檔格式。
還能夠對索引的名字進行通配符查詢,使用 GET /_cat/indices/mov*?v&s=index ,能夠查看匹配的索引。
使用 GET /_cat/indices?v&s=docs.count:desc,能夠按照文檔個數排序。
使用 GET /_cat/indices?v&health=green,能夠查看狀態爲 green 的索引。
使用 GET /_cat/indices?v&h=i,tm&s=tm:desc,能夠查看每一個索引佔用的內存。
ES 還提供了 API 去查看集羣的健康情況,使用 GET _cluster/health 能夠集羣的健康情況,返回結果以下:
{ "cluster_name" : "wupx", "status" : "green", "timed_out" : false, "number_of_nodes" : 2, "number_of_data_nodes" : 2, "active_primary_shards" : 10, "active_shards" : 10, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 0, "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 }
能夠看到集羣名字叫 wupx,集羣狀態是 green,一共有 2 個節點,這兩個節點都是承擔 Data Node 角色,另外還有 10 個主分片。
REST API 就介紹到這裏,其他的你們能夠本身去摸索下。
細心的小夥伴會發現 Kibana 怎麼變成中文界面了,其實 Kibana 在 7.0 版本以後,官方自帶漢化資源文件(位於 Kibana 目錄下的 node_modules/x-pack/plugins/translations/translations/),你們能夠在 config 目錄下修改 kibana.yml 文件,在文件中加上配置項 i18n.locale: "zh-CN",而後從新啓動 Kibana 就漢化完成了。
本文主要學習了文檔、索引、集羣、節點等概念,瞭解到每一個集羣中每一個節點能夠承擔不一樣的角色,還了解了什麼是主分片和副本分片以及它們在分佈式系統中起到的做用,還經過和關係型數據庫作類比,讓你們更易理解,另外還介紹了 REST API 使用,最後給你們總結下 ES 術語的思惟導圖,思惟導圖源文件能夠在公衆號武培軒回覆es獲取。
ES 術語
參考文獻
《Elasticsearch技術解析與實戰》
《Elasticsearch源碼解析與優化實戰》
Elasticsearch核心技術與實戰
Elasticsearch頂尖高手系列
https://www.elastic.co/guide/en/elasticsearch/reference/7.1/index.html
完
●全文搜索引擎 Elasticsearch 入門:集羣搭建
●深刻源碼分析SpringMVC執行過程
●答完這10道題,我哭了(內含答案解析)
武培軒有幫助?在看,轉發走一波喜歡做者