Elasticsearch(一)——Es安装(三个必安工具、安装各种类型分词器)、Es 十大核心概念、通过 Kibana 操作 Es(中文分词、Es各种索引命令操作)
Elasticsearch(一)——Es安裝(三個必安工具、安裝各種類型分詞器)、Es 十大核心概念、通過 Kibana 操作 Es(中文分詞、Es各種索引命令操作)
一、Elasticsearch 安裝
這里博主是用 windows 來安裝,其他地方不太好安裝,容器出問題,主要是比較費空間和占內存。
這個 ES 可以當成搜索引擎來對待,也可以當成 NoSQL 數據庫。
1、引言
在海量數據中執行搜索功能時,如果使用MySQL,效率太低。
將搜索關鍵字,以紅色的字體展示。
Lucene,搜索的基礎工具,是一個 jar 包。
Hadoop 兩個可以直接用的產品,搜索引擎:
- Solr
- Elasticsearch
2、介紹
a、介紹
- ES 是一個使用 Java 語言并且基于 Lucene 編寫的搜索引擎框架,他提供了分布式的全文搜索功能,提供了一個統一的基于 RESTful 風格的 WEB 接口,官方客戶端也對多種語言都提供了相應的 API。
- Lucene:Lucene 本身就是一個搜索引擎的底層,一個搜索工具。Solr,Es
- 分布式:ES 主要是為了突出他的橫向擴展能力。
- 全文檢索:將一段詞語進行分詞,并且將分出的單個詞語統一的放到一個分詞庫中,在搜索時,根據關鍵字去分詞庫中檢索,找到匹配的內容。(倒排索引)
- RESTful 風格的 WEB 接口:操作 ES 很簡單,只需要發送一個 HTTP 請求,并且根據請求方式的不同,攜帶參數的同時,執行相應的功能。
- 應用廣泛:Github.com,WIKI,Gold Man 用 ES 每天維護將近 10TB 的數據。
b、由來
c、ES 和 Solr
- Solr 在查詢死數據時,速度相對 ES 更快一些。但是數據如果是實時改變的,Solr 的查詢速度會降低很多,ES 的查詢的效率基本沒有變化。
- Solr 搭建基于需要依賴 Zookeeper 來幫助管理。ES 本身就支持集群的搭建,不需要第三方的介入。
- 最開始 Solr 的社區可以說是非常火爆,針對國內的文檔并不是很多。在 ES 出現之后,ES 的社區火爆程度直線上升,ES 的文檔非常健全。
- ES 對現在云計算和大數據支持的特別好。
d、倒排索引
將存放的數據,以一定的方式進行分詞,并且將分詞的內容存放到一個單獨的分詞庫中。當用戶去查詢數據時,會將用戶的查詢關鍵字進行分詞。然后去分詞庫中匹配內容,最終得到數據的id標識。根據id標識去存放數據的位置拉取到指定的數據。
3、安裝(強烈建議安裝目錄下沒有中文)
安裝目錄如果有中文,后面可能會有一些難以察覺的錯誤;一開始就純英文路徑就可以免去這些問題的考慮。
安裝要裝三個東西。
a、單節點安裝(Es 本體)
首先打開 Es 官網,找到 Elasticsearch:
https://www.elastic.co/cn/elasticsearch/
然后點擊下載按鈕,選擇合適的版本直接下載即可。
配置完成后,保存配置文件,并重啟 es。重啟成功后,刷新瀏覽器 localhost:9200 頁面,就可以看到最新信息。
Es 支持矩陣:
https://www.elastic.co/cn/support/matrix
b、HEAD 插件(查看 Es 詳細信息,非必須安裝)
這玩意不是必須安裝的,但是安裝了會方便查看。
這里有兩種方式,一個是瀏覽器插件,另外一個是下載插件安裝。不建議下載插件,因為這么安裝相當于 ES-HEAD 是一個獨立運行的工程,這種方式訪問 ES 會有一個跨域的問題,還要配置跨域,比較麻煩。
(1)瀏覽器插件安裝
Chrome 直接在 App Store 搜索 Elasticsearch-head,點擊安裝即可。
如果是 火狐瀏覽器,可以直接在擴展插件下載。(聽說的,但是博主找不到)
(2)下載插件安裝(不建議,因為要處理跨域問題)
四個步驟:
啟動成功,頁面如下:
注意,此時看不到集群數據。原因在于這里通過跨域的方式請求集群數據的,默認情況下,集群不支持跨域,所以這里就看不到集群數據。
解決辦法如下,修改 es 的 config/elasticsearch.yml 配置文件,添加如下內容,使之支持跨域:
http.cors.enabled: true http.cors.allow-origin: "*"配置完成后,重啟 es,此時 head 上就有數據了。
c、Kibana 安裝
一個測試、練習的工具。也可以用 postman 來測試,但是 postman 不方便, Kibana 內部提供了一些工具。
Kibana 是一個 Elastic 公司推出的一個針對 es 的分析以及數據可視化平臺,可以搜索、查看存放在 es中的數據。
注意:要跟 Es 相同版本,不然可能鏈接不上 Es。
安裝步驟如下:
上面第三步的配置演示:
Kibana 安裝好之后,首次打開時,可以選擇初始化 es 提供的測試數據,也可以不使用。
d、分布式安裝
這個分布式安裝這里只是提一下,主要還是上面的三個安裝。
假設:
一主二從,master 的端口是 9200,slave 端口分別是 9201 和 9202。
首先修改 master 的 config/elasticsearch.yml 配置文件:
node.master: true network.host: 127.0.0.1配置完成后,重啟 master。將 es 的壓縮包解壓兩份,分別命名為 slave01 和 slave02,代表兩個從機。分別對其進行配置。
slave01/config/elasticsearch.yml:
# 集群名稱必須保持一致 cluster.name: javaboy-es node.name: slave01 network.host: 127.0.0.1 http.port: 9201 discovery.zen.ping.unicast.hosts: ["127.0.0.1"]slave02/config/elasticsearch.yml:
# 集群名稱必須保持一致 cluster.name: javaboy-es node.name: slave02 network.host: 127.0.0.1 http.port: 9202 discovery.zen.ping.unicast.hosts: ["127.0.0.1"]然后分別啟動 slave01 和 slave02。啟動后,可以在 head 插件上查看集群信息:
4、安裝分詞器(強烈建議安裝目錄下沒有中文)
Es中默認不提供中文分詞,其實不是不能分,主要是對中文分詞的方式不對。
a、內置分詞器
ElasticSearch 核心功能就是數據檢索,首先通過索引將文檔寫入 es。查詢分析則主要分為兩個步驟:
器、小寫過濾器等。
ElasticSearch 中內置了多種分詞器可以供使用。
內置分詞器(下面這些統統都不支持中文分詞):
b、中文分詞器
在 Es 中,使用較多的中文分詞器是 elasticsearch-analysis-ik,這個是 es 的一個第三方插件,代碼托管在 GitHub 上:
https://github.com/medcl/elasticsearch-analysis-ik
兩種使用方式:
(1)第一種使用方式(Windows)
(2)第二種使用方式(Linux)
/bin/elasticsearch-plugin install https://github.com/medcl/elasticsearchanalysis-ik/releases/download/v7.9.3/elasticsearch-analysis-ik-7.9.3.zip
c、測試
測試看第三章的第四、五小節,可以看到有無中文分詞器的差別。
d、本地自定義擴展詞庫
比如有的網絡流行熱詞,這種詞語肯定是不能按照我們想的意思來分詞的,所以可以通過本地自定義詞庫來對一些我們想要的詞語進行分詞,比如像:群除我佬(群里除了我都是大佬)這種詞,就可以自定義。
先查看 es/plugins/ik/config 目錄下的 IKAnalyzer.cfg.xml 文件:
在 es/plugins/ik/config 目錄下(這里已經導入了分詞庫,ik 是自定義的文件夾),新建 my_ext.dic 文件(文件名任意),在該文件中可以配置自定義的詞庫:
新建這么一個文件:
記得這里要設置編碼格式:
然后還要配置這個詞庫:
接著重啟 Es,然后再測試,這時就能發現可以成功分詞了。測試結果看第三章第四小節。
e、遠程詞庫
也可以配置遠程詞庫,遠程詞庫支持熱更新(不用重啟 es 就可以生效)。
熱更新只需要提供一個接口,接口返回擴展詞即可。
具體使用方式如下,新建一個 Spring Boot 項目,引入 Web 依賴即可。然后在 resources/stastic 目錄下新建 ext.dic 文件,寫入擴展詞:
接下來,在 es/plugins/ik/config/IKAnalyzer.cfg.xml 文件中配置遠程擴展詞接口:
配置完成后,重啟 es ,即可生效。
熱更新,主要是響應頭的 Last-Modified 或者 ETag 字段發生變化,ik 就會自動重新加載遠程擴展。
5、打開步驟
安裝好以后,以后每次需要打開就按照以下步驟:
打開 Es 本體( Es 目錄下 / bin / elasticsearch.bat)。
打開 Kibana (Kibana 目錄下 / bin / kibana.bat)。
二、Es 十大核心概念
1、集群(Cluster)
一個或者多個安裝了 es 節點的服務器組織在一起,就是集群,這些節點共同持有數據,共同提供搜索服務。
一個集群有一個名字,這個名字是集群的唯一標識,該名字成為 cluster name,默認的集群名稱是 elasticsearch,具有相同名稱的節點才會組成一個集群。
意思就是只要起同一個名字,就是集群,會自動的互相找到對方。
可以在 config/elasticsearch.yml 文件中配置集群名稱:
cluster.name:xxx
在集群中,節點的狀態有三種:綠色、黃色、紅色:
- 綠色:節點運行狀態為健康狀態。所有的主分片、副本分片都可以正常工作。
- 黃色:表示節點的運行狀態為警告狀態,所有的主分片目前都可以直接運行,但是至少有一個副本分片是不能正常工作的。
- 紅色:表示集群無法正常工作。
2、節點(Node)
集群中的一個服務器就是一個節點,節點中會存儲數據,同時參與集群的索引以及搜索功能。一個節點想要加入一個集群,只需要配置一下集群名稱即可。默認情況下,如果我們啟動了多個節點,多個節點還能夠互相發現彼此,那么它們會自動組成一個集群,這是 es 默認提供的,但是這種方式并不可靠,有可能會發生腦裂現象。所以在實際使用中,建議一定手動配置一下集群信息。
3、索引(index)
索引可以從兩方面來理解:
名詞:具有相似特征文檔的集合。類似于關系型數據庫中的數據庫概念,并不跟庫完全一樣,只是可以當成這么理解。
動詞:索引數據以及對數據進行索引操作。意思就是要存儲一個數據,存儲到 Es 里面去。
4、類型(Type)
類型是索引上的邏輯分類或者分區。在 es6 之前,一個索引中可以有多個類型,從 es7 開始,一個索引中,只能有一個類型。在 es6.x 中,依然保持了兼容,依然支持單 index 多個 type 結構,但是已經不建議這么使用。
5、文檔(Document)
一個可以被索引的數據單元。例如一個用戶的文檔、一個產品的文檔等等。文檔都是 JSON 格式的。
6、分片(Shards)
索引都是存儲在節點上的,但是受限于節點的空間大小以及數據處理能力,單個節點的處理效果可能不理想,此時我們可以對索引進行分片。當我們創建一個索引的時候,就需要指定分片的數量。每個分片本身也是一個功能完善并且獨立的索引。
默認情況下,一個索引會自動創建 1 個分片,并且為每一個分片創建一個副本。
7、副本(Replicas)
副本也就是備份,是對主分片的一個備份。
8、Settings
集群中對索引的定義信息,例如索引的分片數、副本數等等。
9、Mapping
Mapping 保存了定義索引字段的存儲類型、分詞方式、是否存儲等信息。
10、Analyzer
字段分詞方式的定義。
11、ElasticSearch Vs 關系型數據
三、通過 Kibana 操作 Es
1、初識命令行
2、關于 http 的 get 的請求體說法
其實 http 協議中并沒有說 get 不能有請求體,但是在 Java 中確實是沒有請求體的。但是在 Es 中可以傳請求體,Es也考慮到有的語言不支持 get 的請求體,所以在 Es 中能夠使用 get 請求的統統都可以使用 post 請求,就是防止有的語言中 get 沒有請求體;換成 post 的就可以處理了。
3、簡單使用
首先,創建索引不能有大寫字母!不然會報錯。
a、請求創建索引
可以看到現在沒有一個叫 test 的索引,那么現在可以創建索引(put 請求可以添加索引也可以更新索引;當沒有這個索引的時候就是添加索引):
然后看控制臺右邊:
此時再刷新 Es-head 索引分欄:
可以發現就有 test 索引了。
b、通過 head 插件創建索引
然后效果:
可以看到這就是五個分片(0、1、2、3、4),然后上下有兩層,也就是一個副本。
c、對一個英文語句進行分詞
結果:
可以看到 hello zhangsan 分詞后的結果是:hello zhangsan
start_offset:從第幾個字符開始的。
end_offset:從第幾個字符結束。
position:位置。
4、中文分詞
a、沒有使用中文分詞器
然后查看結果:
可以看到是一個詞一個詞的分,那么 Es 存儲就是一個字一個字的存,所以搜索也就是一個字一個字的搜索,不能用詞語去搜索;也就意味著不能斷句。
b、使用 ik_max_word 分詞器
還是這個素材:
結果:
其他素材:
c、使用 ik_smart 分詞器
素材同上:
效果:
d、網絡熱詞等少見詞
像網絡熱詞就不能分詞了:
像下面這種就是分詞器寫好了詞匯才能完整分詞:
e、網絡熱詞(使用了自定義分詞庫)
效果:
5、Es索引
a、創建索引
創建索引看第三小節。
b、更新索引(修改索引副本)
前面創建 book 索引只有一個副本數量,副本數量可以更新。但是分片的數量在創建好以后就不能更新了。 因為每一條記錄/文檔存儲到哪里都是根據現有的索引算出來的,所以一旦分片的數量變化了會導致后面搜索搜不到想要的記錄。
可以通過下面命令來更新副本數量:
結果:
c、向索引中寫入文檔
向索引中寫入文檔,并賦予這條記錄的 id:
結果:
這樣就向 book 索引里面添加了一條記錄。
然后查看 head 插件:
docs 應該是沒有加載出來的原因,所以才顯示 0。
可以點擊數據瀏覽里面查看信息:
d、修改索引的讀寫權限
默認情況下,索引是具備讀寫權限的,當然這個讀寫權限可以關閉。
例如,關閉索引的寫權限:
關閉之后,就無法添加文檔了。關閉了寫權限之后,如果想要再次打開,方式如下:
其他類似的權限有:
- blocks.write
- blocks.read
- blocks.read_only
e、查看索引
f、刪除索引
(1)通過 head 插件刪除索引
head 插件可以刪除索引:
(2)通過請求刪除索引
請求刪除如下:
DELETE test
刪除一個不存在的索引會報錯。
g、索引打開/關閉
當然,可以同時關閉/打開多個索引,多個索引用 , 隔開,或者直接使用 _all 代表所有索引。
h、復制索引
索引復制,只會復制數據,不會復制索引配置。
復制的時候,可以添加查詢條件。
i、索引別名(增刪查)
(1)創建別名
可以為索引創建別名,如果這個別名是唯一的,該別名可以代替索引名稱(前提是這個索引要存在的情況下才能創建別名):
可以在創建別名的同時添加其他查詢條件,這樣就可以根據索引的名字或者索引的別名通過設置好的查詢條件去查詢。
然后看到 head 插件,可以看到別名:
(2)刪除別名
點擊 b 那里的叉叉,就可以刪除別名。
將 add 改為 remove 就表示移除別名:
(3)查看 索引/集群 別名
j、put 新建文檔(補充一些信息和版本號的用途)
關于文檔這一塊上面講過了,這里補充一些:
put 請求可以添加索引也可以更新索引;當沒有這個索引的時候就是添加索引。
- _index 表示文檔索引。
- _type 表示文檔的類型。
- _id 表示文檔的 id。
- _version 表示文檔的版本(更新文檔,版本會自動加 1,針對一個文檔的)。
- result 表示執行結果。
- _shards 表示分片信息。
- _seq_no 和 _primary_term 這兩個也是版本控制用的(針對當前 index)。
當更新當前文檔時,版本號會自增:
結果:
這個版本號可以在并發控制的時候,就可以利用版本號,去防止并發協作的線程不安全。比如:當剛拿到的時候是版本號 2,修改完還沒有提交發現版本號變成 3,說明有人修改過了,就放棄這一次的操作。
result 顯示的是 updated,意思是這一次是更新。
total 顯示的是2,成功 1 個,失敗 0 個。因為 book 有一個副本,實際上是往兩個地方寫,但是有一個副本操作不了,所以顯示的是成功 1 個。
下面的 _seq_no 和 _primary_term 也是做版本并發控制的。
k、post 新建文檔
可以看到這里的 id 跟 put 方式不同,因為 post 方式不需要指定 id,會自動生成 id。
當然也可以按照 put 的方式去寫,同樣是有效,且也有更新的效果。
l、查詢文檔
(1)查看文檔的信息
這里先簡單的通過 id 來查詢文檔(有些復雜的效果后面文章再介紹):
結果:
如果查詢不存在的文檔,結果:
false 表示沒有查到。
(2)批量查詢文檔
結果:
(3)查看文檔是否存在
如果僅僅只是想探測某一個文檔是否存在,可以使用 head 請求:
如果文檔存在,響應如下:
如果文檔不存在,響應如下:
m、文檔更新(通過腳本語言更新)
前面說過 put 請求有創建和更新功能,但這種更新會把文檔覆蓋掉。
大多數時候,我們只是想更新文檔的某個字段,這個可以通過腳本(painless)來實現:
painless 腳本是 Es 內置的一種腳本,通過這個腳本可以動態的更新:
結果:
注意:
1、ctx 代表的是(可以簡單理解為):
2、如果直接這樣寫 ctx._source.name=xxx,這樣需要轉義,有點麻煩,所以才有后面的 params 那些內容。
轉義是啥?就比如這種:
3、這種更新不能用 put 請求,只能 post 請求。
也可以通過這種方式向文檔中添加字段:
結果:
n、腳本語言的其他操作
通過這個腳本語言還可以做其他事,比如修改數組、使用 if else:
上圖的 if else:如果包含 java,就把這條記錄刪掉,否則什么都不做。
注意:這種通過腳本方式去操作的,即便是 post 請求,也要帶上 id。
o、查詢更新
通過條件查詢找到文檔,然后再去更新:
然后把 java 改成 python:
結果:
p、刪除文檔
(1)根據 id 刪除
從索引中刪除一個文檔。
刪除一個 id 為 TuUpmHUByGJWB5WuMasV 的文檔。
如果在添加文檔時指定了路由,則刪除文檔時也需要指定路由,否則刪除失敗。
q、查詢刪除
查詢刪除是 POST 請求。
例如刪除索引 blog 中 title 包含 666 的文檔:
r、副本
es 是一個分布式系統,當我們存儲一個文檔到 es 上之后,這個文檔實際上是被存儲到 master 節點中的某一個主分片上。
新建一個索引:
然后添加一條記錄:
文檔保存成功后,可以查看該文檔被保存到哪個分片中去了:
prirep 下面的 p 和 r:p 是主分片,r 是副本分片。
state:狀態。STARTED 是 ok 的,另外那個就是不行的意思。
docs 找到為 2 的那一行,意思是剛剛保存的兩條記錄都放到 4 號分片里面。
那么 es 中到底是按照什么樣的規則去分配分片的?
es 中的路由機制是通過哈希算法,將具有相同哈希值的文檔放到一個主分片中,分片位置的計算方式如下:
shard=hash(routing) % number_of_primary_shards
routing 可以是一個任意字符串,es 默認是將文檔的 id 作為 routing 值,通過哈希函數根據 routing 生成一個數字,然后將該數字和分片數取余,取余的結果就是分片的位置。
默認的這種路由模式,最大的優勢在于負載均衡,這種方式可以保證數據平均分配在不同的分片上。但是他有一個很大的劣勢,就是查詢時候無法確定文檔的位置,此時它會將請求廣播到所有的分片上去執行。另一方面,使用默認的路由模式,后期修改分片數量不方便。
像剛剛都保存到分片 4 上,是根據 id 為1 來取余;現在是根據 2 來取余,是找不出來的:
如果是 1 的話:
就可以找得到:
如果不指定 routing ,則會查找的慢一些,指定了正確的 routing ,則查找的快一些。
總結
以上是生活随笔為你收集整理的Elasticsearch(一)——Es安装(三个必安工具、安装各种类型分词器)、Es 十大核心概念、通过 Kibana 操作 Es(中文分词、Es各种索引命令操作)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 思科路由器-配置RIP协议
- 下一篇: 【20号微软推广正版验证】