文章目錄
- 一、ElasticSearch簡介
- 二、ElasticSearch的安裝與啓動
- 三、ElasticSearch相關概念
- 四、使用Postman對ES進行操作
- 4.1 ES接口語法
- 4.2 創建索引index和映射mapping(PUT)
- 4.3 創建索引後設置Mapping(POST)
- 4.4 刪除索引(DELETE)
- 4.5 創建文檔document(POST)
- 4.6 修改文檔document(POST)
- 4.7 刪除文檔document(DELETE)
- 4.8 查詢文檔——根據id查詢(GET)
- 4.9 查詢文檔——querystring查詢(POST)
- 4.10 查詢文檔——term關鍵字查詢(POST)
- 五、IK中文分詞器
- 第六章 ElasticSearch集羣
歡迎訪問筆者個人技術博客:http://rukihuang.xyz/
一、ElasticSearch簡介
- Elaticsearch,簡稱爲es, es是一個開源的高擴展的分佈式全文檢索引擎,它可以近乎實時的存儲、檢索數據;本身擴展性很好,可以擴展到上百臺服務器,處理PB級別的數據。es也使用Java開發並使用Lucene作爲其核心來實現所有索引和搜索的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜索變得簡單。
二、ElasticSearch的安裝與啓動
2.1 下載ES壓縮包
- 進入官網進行下載,下載windows shaasc即可,但本文使用的是較老的5.6.8版本
2.2 安裝ES服務
- Window版的ElasticSearch的安裝很簡單,類似Window版的Tomcat,解壓開即安裝完畢,解壓後的ElasticSearch的目錄結構如下:
- 修改
config/elasticsearch.yml
配置文件,增加以下兩句命令。這兩句命令的命令的作用是:允許es跨域訪問,爲後續安裝elasticsearch-head做準備(不安裝head可以不添加)
http.cors.enabled: true
http.cors.allow-origin: "*"
2.3 啓動ES服務
- 點擊es文件夾下bin目錄的
elasticsearch.bat
啓動es
- 控制檯信息打印如下:
-
注意:
- 9200是http協議的RESTful接口(外部訪問)
- 9300是tcp通訊端口,集羣間和TCPClient都執行該端口(集羣節點間的通信)
-
注意:ES需要jdk版本是1.8以上,並正確配置好環境變量,否則ES啓動會失敗。
2.4 安裝ES的圖形化界面插件elasticsearch-head
- ES5.*以上版本安裝head需要安裝node和grunt
2.4.1 下載head插件
2.4.2 下載安裝nodejs
-
nodejs下載地址,安裝過程直接Next即可
-
安裝完畢,可以在cmd中輸入
node -v
查看版本號 -
本文使用的nodejs版本是8.9.4
2.4.3 將grunt安裝爲全局命令
- grunt是基於nodejs的項目構建工具
- 在cmd控制檯中輸入以下執行命令
npm install -g grunt-cli
- 進入elasticsearch-head-master目錄啓動head,在cmd中輸入
npm install
grunt server
- 打開瀏覽器,輸入 http://localhost:9100,進入圖形化界面
- 點擊連接,即可連接到es服務,若不能連接到es服務,需要修改config目錄下的配置文件:config/elasticsearch.yml`,增加以下兩句命令
http.cors.enabled: true
http.cors.allow-origin: "*"
- 然後重新啓動es服務即可。
三、ElasticSearch相關概念
3.1 ES與數據庫進行類比
數據庫 | ES |
---|---|
Databases | Indics |
Tables | Types |
Rows | Documents |
Columns | Fields |
3.2 Elasticsearch核心概念
3.2.1 索引 index
- 一個索引就是一個擁有幾分相似特徵的文檔的集合。比如說,你可以有一個客戶數據的索引,另一個產品目錄的索引,還有一個訂單數據的索引。一個索引由一個名字來標識(必須全部是小寫字母的),並且當我們要對對應於這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。在一個集羣中,可以定義任意多的索引。
3.2.2 類型 type
- 在一個索引中,你可以定義一種或多種類型。一個類型是你的索引的一個邏輯上的分類/分區,其語義完全由你來定。通常,會爲具有一組共同字段的文檔定義一個類型。比如說,我們假設你運營一個博客平臺並且將你所有的數據存儲到一個索引中。在這個索引中,你可以爲用戶數據定義一個類型,爲博客數據定義另一個類型,當然,也可以爲評論數據定義另一個類型。
3.2.3 字段Field
- 相當於是數據表的字段,對文檔數據根據不同屬性進行的分類標識
3.2.4 映射 mapping
- mapping是處理數據的方式和規則方面做一些限制,如某個字段的數據類型、默認值、分析器、是否被索引等等,這些都是映射裏面可以設置的,其它就是處理es裏面數據的一些使用規則設置也叫做映射,按着最優規則處理數據對性能提高很大,因此才需要建立映射,並且需要思考如何建立映射才能對性能更好。
3.2.5 文檔 document
-
一個文檔是一個可被索引的基礎信息單元。比如,你可以擁有某一個客戶的文檔,某一個產品的一個文檔,當然,也可以擁有某個訂單的一個文檔。文檔以JSON(Javascript Object Notation)格式來表示,而JSON是一個到處存在的互聯網數據交互格式。
-
在一個index/type裏面,你可以存儲任意多的文檔。注意,儘管一個文檔,物理上存在於一個索引之中,文檔必須被索引/賦予一個索引的type。
3.2.6 接近實時 NRT
- Elasticsearch是一個接近實時的搜索平臺。這意味着,從索引一個文檔直到這個文檔能夠被搜索到有一個輕微的延遲(通常是1秒以內)
3.2.7 集羣 cluster
- 一個集羣就是由一個或多個節點組織在一起,它們共同持有整個的數據,並一起提供索引和搜索功能。一個集羣由一個唯一的名字標識,這個名字默認就是“elasticsearch”。這個名字是重要的,因爲一個節點只能通過指定某個集羣的名字,來加入這個集羣
3.2.8 節點 node
-
一個節點是集羣中的一個服務器,作爲集羣的一部分,它存儲數據,參與集羣的索引和搜索功能。和集羣類似,一個節點也是由一個名字來標識的,默認情況下,這個名字是一個隨機的漫威漫畫角色的名字,這個名字會在啓動的時候賦予節點。這個名字對於管理工作來說挺重要的,因爲在這個管理過程中,你會去確定網絡中的哪些服務器對應於Elasticsearch集羣中的哪些節點。
-
一個節點可以通過配置集羣名稱的方式來加入一個指定的集羣。默認情況下,每個節點都會被安排加入到一個叫做“elasticsearch”的集羣中,這意味着,如果你在你的網絡中啓動了若干個節點,並假定它們能夠相互發現彼此,它們將會自動地形成並加入到一個叫做“elasticsearch”的集羣中。
-
在一個集羣裏,只要你想,可以擁有任意多個節點。而且,如果當前你的網絡中沒有運行任何Elasticsearch節點,這時啓動一個節點,會默認創建並加入一個叫做“elasticsearch”的集羣。
3.2.9 分片和複製 shards&replicas
-
一個索引可以存儲超出單個結點硬件限制的大量數據。比如,一個具有10億文檔的索引佔據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢。爲了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。當你創建一個索引的時候,你可以指定你想要的分片的數量。每個分片本身也是一個功能完善並且獨立的“索引”,這個“索引”可以被放置到集羣中的任何節點上。分片很重要,主要有兩方面的原因:
1)允許你水平分割/擴展你的內容容量。
2)允許你在分片(潛在地,位於多個節點上)之上進行分佈式的、並行的操作,進而提高性能/吞吐量。 -
至於一個分片怎樣分佈,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對於作爲用戶的你來說,這些都是透明的。
-
在一個網絡/雲的環境裏,失敗隨時都可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者由於任何原因消失了,這種情況下,有一個故障轉移機制是非常有用並且是強烈推薦的。爲此目的,Elasticsearch允許你創建分片的一份或多份拷貝,這些拷貝叫做複製分片,或者直接叫複製。
-
複製之所以重要,有兩個主要原因: 在分片/節點失敗的情況下,提供了高可用性。因爲這個原因,注意到複製分片從不與原/主要(original/primary)分片置於同一節點上是非常重要的。擴展你的搜索量/吞吐量,因爲搜索可以在所有的複製上並行運行。總之,每個索引可以被分成多個分片。一個索引也可以被複制0次(意思是沒有複製)或多次。一旦複製了,每個索引就有了主分片(作爲複製源的原來的分片)和複製分片(主分片的拷貝)之別。分片和複製的數量可以在索引創建的時候指定。在索引創建之後,你可以在任何時候動態地改變複製的數量,但是你事後不能改變分片的數量。
-
默認情況下,Elasticsearch中的每個索引被分片5個主分片和1個複製,這意味着,如果你的集羣中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個完全拷貝),這樣的話每個索引總共就有10個分片。
四、使用Postman對ES進行操作
4.1 ES接口語法
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
- 參數詳解
其中:
參數 | 解釋 |
---|---|
VERB |
適當的 HTTP 方法 或 謂詞 : GET 、 POST 、 PUT 、 HEAD 或者 DELETE 。 |
PROTOCOL |
http 或者 https (如果你在 Elasticsearch 前面有一個 https 代理) |
HOST |
Elasticsearch 集羣中任意節點的主機名,或者用 localhost 代表本地機器上的節點。 |
PORT |
運行 Elasticsearch HTTP 服務的端口號,默認是 9200 。 |
PATH |
API 的終端路徑(例如 _count 將返回集羣中文檔數量)。Path 可能包含多個組件,例如:_cluster/stats 和 _nodes/stats/jvm 。 |
QUERY_STRING |
任意可選的查詢字符串參數 (例如 ?pretty 將格式化地輸出 JSON 返回值,使其更容易閱讀) |
BODY |
一個 JSON 格式的請求體 (如果請求需要的話) |
4.2 創建索引index和映射mapping(PUT)
- 請求url
PUT localhost:9200/blog1
- 請求體
{
"mappings": {
"article": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":"not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
},
"content": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
}
}
}
}
}
4.3 創建索引後設置Mapping(POST)
- 在創建索引時,可以不添加請求體,即mapping信息。可以在創建索引後再設置Mapping
- 請求的URL
POST http://127.0.0.1:9200/blog2/hello/_mapping
- 請求體
{
"hello": {
"properties": {
"id":{
"type":"long",
"store":true
},
"title":{
"type":"text",
"store":true,
"index":true,
"analyzer":"standard"
},
"content":{
"type":"text",
"store":true,
"index":true,
"analyzer":"standard"
}
}
}
}
4.4 刪除索引(DELETE)
- 請求URL
DELETE localhost:9200/blog1
4.5 創建文檔document(POST)
- 請求URL
POST localhost:9200/blog1/article/1
- 請求體
{
"id":1,
"title":"ElasticSearch是一個基於Lucene的搜索服務器",
"content":"它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作爲Apache許可條款下的開放源碼發佈,是當前流行的企業級搜索引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。"
}
4.6 修改文檔document(POST)
- 請求URL
POST localhost:9200/blog1/article/1
- 請求體
{
"id":1,
"title":"【修改】ElasticSearch是一個基於Lucene的搜索服務器",
"content":"【修改】它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作爲Apache許可條款下的開放源碼發佈,是當前流行的企業級搜索引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。"
}
4.7 刪除文檔document(DELETE)
- 清理url
DELETE localhost:9200/blog1/article/1
4.8 查詢文檔——根據id查詢(GET)
- 請求URL
GET localhost:9200/blog1/article/1
4.9 查詢文檔——querystring查詢(POST)
- 請求URL
POST localhost:9200/blog1/article/_search
- 請求體
{
"query": {
"query_string": {
"default_field": "title",
"query": "搜索服務器"
}
}
}
4.10 查詢文檔——term關鍵字查詢(POST)
- 請求URL
POST localhost:9200/blog1/article/_search
- 請求體
{
"query": {
"term": {
"title": "搜索"
}
}
}
五、IK中文分詞器
5.1 標準分析器的侷限
- 由於之前再創建mapping映射時,使用的都是標準分析器,這會導致中文內容的關鍵詞以單個字來展示。
- 標準分詞器分詞效果測試:
http://127.0.0.1:9200/_analyze?analyzer=standard&pretty=true&text=我是程序員
- 分詞結果
{
"tokens" : [
{
"token" : "我",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "是",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "程",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 2
},
{
"token" : "序",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 3
},
{
"token" : "員",
"start_offset" : 4,
"end_offset" : 5,
"type" : "<IDEOGRAPHIC>",
"position" : 4
}
]
}
5.2 ES集成IK分詞器
5.2.1 IK分詞器的安裝
-
將分析器解壓後重命名爲
analysis-ik
,並移動到elasticsearch文件夾下的plugin目錄中 -
重新啓動ES
5.2.2 IK分詞器
- IK提供了兩個分詞器
ik_smart
和ik_max_word
ik_smart
:最少切分ik_max_word
:最細粒度劃分
5.2.3 修改索引映射(先刪後創)
- 創建原有索引
DELETE localhost:9200/blog1
- 創建索引
PUT localhost:9200/blog1
- mapping映射
{
"mappings": {
"article": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":"not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"ik_max_word" #--修改分詞器
},
"content": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"ik_max_word"
}
}
}
}
}
- 在設置
mappings
時,"analyzer"
設置爲對應"ik_smart"
或"ik_max_word"
即可
第六章 ElasticSearch集羣
-
ES集羣是一個 P2P類型(使用 gossip 協議)的分佈式系統,除了集羣狀態管理以外,其他所有的請求都可以發送到集羣內任意一臺節點上,這個節點可以自己找到需要轉發給哪些節點,並且直接跟這些節點通信。所以,從網絡架構及服務配置上來說,構建集羣所需要的配置極其簡單。在 Elasticsearch 2.0 之前,無阻礙的網絡下,所有配置了相同 cluster.name 的節點都自動歸屬到一個集羣中。2.0 版本之後,基於安全的考慮避免開發環境過於隨便造成的麻煩,從 2.0 版本開始,默認的自動發現方式改爲了單播(unicast)方式。配置裏提供幾臺節點的地址,ES 將其視作 gossip router 角色,藉以完成集羣的發現。由於這只是 ES 內一個很小的功能,所以 gossip router 角色並不需要單獨配置,每個 ES 節點都可以擔任。所以,採用單播方式的集羣,各節點都配置相同的幾個節點列表作爲 router 即可。
-
集羣中節點數量沒有限制,一般大於等於2個節點就可以看做是集羣了。一般處於高性能及高可用方面來考慮一般集羣中的節點數量都是3個及3個以上。
6.1 集羣的相關概念
6.1.1 集羣 cluster
- 一個集羣就是由一個或多個節點組織在一起,它們共同持有整個的數據,並一起提供索引和搜索功能。一個集羣由一個唯一的名字標識,這個名字默認就是“elasticsearch”。這個名字是重要的,因爲一個節點只能通過指定某個集羣的名字,來加入這個集羣
6.1.2 節點 node
-
一個節點是集羣中的一個服務器,作爲集羣的一部分,它存儲數據,參與集羣的索引和搜索功能。和集羣類似,一個節點也是由一個名字來標識的,默認情況下,這個名字是一個隨機的漫威漫畫角色的名字,這個名字會在啓動的時候賦予節點。這個名字對於管理工作來說挺重要的,因爲在這個管理過程中,你會去確定網絡中的哪些服務器對應於Elasticsearch集羣中的哪些節點。
-
一個節點可以通過配置集羣名稱的方式來加入一個指定的集羣。默認情況下,每個節點都會被安排加入到一個叫做“elasticsearch”的集羣中,這意味着,如果你在你的網絡中啓動了若干個節點,並假定它們能夠相互發現彼此,它們將會自動地形成並加入到一個叫做“elasticsearch”的集羣中。
-
在一個集羣裏,只要你想,可以擁有任意多個節點。而且,如果當前你的網絡中沒有運行任何Elasticsearch節點,這時啓動一個節點,會默認創建並加入一個叫做“elasticsearch”的集羣。
6.1.3 分片和複製 shards&replicas
-
一個索引可以存儲超出單個結點硬件限制的大量數據。比如,一個具有10億文檔的索引佔據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢。爲了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。當你創建一個索引的時候,你可以指定你想要的分片的數量。每個分片本身也是一個功能完善並且獨立的“索引”,這個“索引”可以被放置到集羣中的任何節點上。分片很重要,主要有兩方面的原因:
1)允許你水平分割/擴展你的內容容量。
2)允許你在分片(潛在地,位於多個節點上)之上進行分佈式的、並行的操作,進而提高性能/吞吐量。 -
至於一個分片怎樣分佈,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對於作爲用戶的你來說,這些都是透明的。
-
在一個網絡/雲的環境裏,失敗隨時都可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者由於任何原因消失了,這種情況下,有一個故障轉移機制是非常有用並且是強烈推薦的。爲此目的,Elasticsearch允許你創建分片的一份或多份拷貝,這些拷貝叫做複製分片,或者直接叫複製。
-
複製之所以重要,有兩個主要原因: 在分片/節點失敗的情況下,提供了高可用性。因爲這個原因,注意到複製分片從不與原/主要(original/primary)分片置於同一節點上是非常重要的。擴展你的搜索量/吞吐量,因爲搜索可以在所有的複製上並行運行。總之,每個索引可以被分成多個分片。一個索引也可以被複制0次(意思是沒有複製)或多次。一旦複製了,每個索引就有了主分片(作爲複製源的原來的分片)和複製分片(主分片的拷貝)之別。分片和複製的數量可以在索引創建的時候指定。在索引創建之後,你可以在任何時候動態地改變複製的數量,但是你事後不能改變分片的數量。
-
默認情況下,Elasticsearch中的每個索引被分片5個主分片和1個複製,這意味着,如果你的集羣中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個完全拷貝),這樣的話每個索引總共就有10個分片。
6.2 集羣的搭建
6.2.1 準備三臺elasticsearch服務器
- 創建elasticsearch-cluster文件夾,在內部複製三個elasticsearch服務
6.2.2 修改每臺服務器配置
- 修改
elasticsearch-cluster\node*\config\elasticsearch.yml
配置文件
node1節點:
#節點1的配置信息:
#集羣名稱,保證唯一
cluster.name: my-elasticsearch
#節點名稱,必須不一樣
node.name: node-1
#必須爲本機的ip地址
network.host: 127.0.0.1
#服務端口號,在同一機器下必須不一樣
http.port: 9200
#集羣間通信端口號,在同一機器下必須不一樣
transport.tcp.port: 9300
#設置集羣自動發現機器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
node2節點:
#節點2的配置信息:
#集羣名稱,保證唯一
cluster.name: my-elasticsearch
#節點名稱,必須不一樣
node.name: node-2
#必須爲本機的ip地址
network.host: 127.0.0.1
#服務端口號,在同一機器下必須不一樣
http.port: 9201
#集羣間通信端口號,在同一機器下必須不一樣
transport.tcp.port: 9301
#設置集羣自動發現機器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
node3節點:
#節點3的配置信息:
#集羣名稱,保證唯一
cluster.name: my-elasticsearch
#節點名稱,必須不一樣
node.name: node-3
#必須爲本機的ip地址
network.host: 127.0.0.1
#服務端口號,在同一機器下必須不一樣
http.port: 9202
#集羣間通信端口號,在同一機器下必須不一樣
transport.tcp.port: 9302
#設置集羣自動發現機器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
6.2.3 啓動各個節點服務器
雙擊elasticsearch-cluster\node*\bin\elasticsearch.bat
6.2.4 集羣測試
添加索引和映射
PUT localhost:9200/blog1
{
"mappings": {
"article": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":"not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
},
"content": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
}
}
}
}
}
添加文檔
POST localhost:9200/blog1/article/1
{
"id":1,
"title":"ElasticSearch是一個基於Lucene的搜索服務器",
"content":"它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作爲Apache許可條款下的開放源碼發佈,是當前流行的企業級搜索引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。"
}