一、全文檢索
全文檢索是計(jì)算機(jī)程序通過(guò)掃描文章中的每一個(gè)詞,對(duì)每一個(gè)詞簡(jiǎn)歷索引,指明改詞在文章中出現(xiàn)的次數(shù)和位置。當(dāng)用戶查詢時(shí)根據(jù)建立的索引查找,類似通過(guò)字典的檢索字表查字的過(guò)程,衡量全文檢索系統(tǒng)的關(guān)鍵性指標(biāo):全面,準(zhǔn)確,快速。
- 只處理文本,不處理語(yǔ)義,不進(jìn)行語(yǔ)義轉(zhuǎn)換查詢;
- 檢索時(shí)英文不區(qū)分大小寫;
- 檢索出的結(jié)果按相關(guān)性進(jìn)行排序。
二、簡(jiǎn)介
You Know, for Search.
ElasticSearch是基于Apache Lucene構(gòu)建的分布式開(kāi)源搜索引擎,是當(dāng)前最流行的企業(yè)級(jí)搜索引擎。Lucene本身被認(rèn)為是迄今為止性能最好的一款開(kāi)源搜索引擎工具包,但Lucene的API相對(duì)復(fù)雜,需要深厚的搜索理論,很難集成到實(shí)際的應(yīng)用中。ES采用java語(yǔ)言編寫,提供了簡(jiǎn)單易用的Restful API,開(kāi)發(fā)者可以使用簡(jiǎn)單的Restful API,開(kāi)發(fā)相關(guān)的搜索功能,避免Lucene的復(fù)雜性。
三、ES安裝(7.14.0版本)
- 傳統(tǒng)安裝方式:下載安裝包,解壓
- Docker方式安裝:推薦
3.1 傳統(tǒng)安裝方式
# 1.環(huán)境準(zhǔn)備
- centos7.x+,windows,macos
- 安裝jdk11.0+,并設(shè)置環(huán)境變量
# 2.下載ES
- https://www.elastic.co/cn/start
# 3.安裝ES不要使用root用戶,創(chuàng)建普通用戶
# 添加用戶名
$ useradd es
#修改密碼
$ passwd es
# 4.解壓縮ES安裝包,解壓后的目錄如下圖
$ tar -zxvf elasticsearch-7.14.0-linux-86_64.tar.gz
# 5.啟動(dòng)es,啟動(dòng)完,訪問(wèn)127.0.0.1:9200
$ ./elasticsearch
解壓后的目錄如下:


啟動(dòng)錯(cuò)誤
- 虛擬內(nèi)存過(guò)?。篺ailure [1]:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144].
解決方法:
$ vim /etc/sysctl.conf
vm.max_map_count=655360 #centos7 系統(tǒng)
vm.max_map_count=262144 #ubuntu 系統(tǒng)
$ sysctl -p
- 默認(rèn)配置模式以集群?jiǎn)?dòng):failure[2]:the default discovery settings are unsuitable for production use; at least one of[discoery.seed_hosts, discovery.seed_providers...
解決方法:
$ vim conf/elastic_search.yml
cluster.initial_master_nodes: [ "node-1" ].
- 必須已非root用戶啟動(dòng)
解決方法:切換到普通用戶啟動(dòng)。
解決上述錯(cuò)誤后重啟elasticsearch服務(wù)即可。
3.2 Docker方式安裝
# 1.獲取鏡像
- docker pull elasticsearch:7.14.0
# 2.運(yùn)行ES
- docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.14.0
# 3.訪問(wèn)ES
- http://127.0.0.1:9200/
3.3 elasticsearch.yml配置詳解
network.host: 0.0.0.0 //配置遠(yuǎn)程訪問(wèn)
cluster.initial_master_nodes: [ "node-1" ] //設(shè)置單節(jié)點(diǎn)啟動(dòng)
四、Kibana(官方ES客戶端工具)
Kibana是一個(gè)針對(duì)ElasticSearch的開(kāi)源分析及可視化平臺(tái),使用Kibana可以查詢、查看并與存儲(chǔ)在ES索引的數(shù)據(jù)進(jìn)行交互操作,使用Kibana能執(zhí)行高級(jí)的數(shù)據(jù)分析,并能以圖標(biāo)、表格與地圖的形式可視化數(shù)據(jù)。
4.1 Kibana傳統(tǒng)方式安裝
# 1. 下載Kibana
- https://elastic.co/download/kibana
# 2. 安裝下載的Kibana
$ tar -zxvf kibana-7.14.0-linux-x86_64.tar.gz
# 3. 編輯kibana配置文件
$ vim ./kibana安裝目錄conf目錄/kibana.yml
# 4.修改配置如下
- server.host: "0.0.0.0" #開(kāi)啟kibana遠(yuǎn)程訪問(wèn)
- elsaticsearch.hosts: [ "http://localhost:9200" ] #ES服務(wù)器地址
# 5. 啟動(dòng)kibana
- ./bin/kibana
輸出"Kibana is now available(was degraded)"表示啟動(dòng)成功。
# 6. 訪問(wèn)kibana
- http://localhost:5601
4.1 Kibana Docker方式安裝
# 1.獲取鏡像
- docker pull kibana:7.14.0
# 2.運(yùn)行kibana
- docker run -d --name kibana -p 5601:5601 kibana:7.14.0
# 3.進(jìn)入容器連接到ES,重啟kibana容器,訪問(wèn)
- http://127.0.0.1:5601
# 4.基于數(shù)據(jù)卷加載配置文件方式運(yùn)行
- a.從容器復(fù)制kibana配置文件出來(lái)
- b.修改配置文件對(duì)應(yīng)的ES服務(wù)器地址
- c.通過(guò)數(shù)據(jù)卷加載配置文件方式啟動(dòng)
- docker run -d -v /宿主機(jī)kibana.yml目錄/kibana.yml:/usr/share/kibana/config/kibana.yml --name kibana -p 5601:5601 kibana:7.14.0
4.3 compose方式安裝(推薦)
# kibana配置文件連接到es
server.host: "0"
server.shutdownTimeout: "5s"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
#monitoring.ui.container.elasticsearch.enable: true
version: "3.8"
volumes:
data:
config:
plugin:
networks:
es:
services:
elasticsearch:
environment:
- "discovery.type=single-node"
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
image: "elasticsearch:7.14.0"
ports:
- "9200:9200"
- "9300:9300"
networks:
- "es"
volumes:
- data:/usr/share/elasticsearch/data
- config:/usr/share/elasticsearch/config
- plugin:/usr/share/elasticsearch/plugin
kibana:
image: kibana:7.14.0
ports:
- "5601:5601"
networks:
- "es"
volumes:
- ./kibana.yml:/usr/share/kibana/config/kibana.yml
五、核心概念(索引,映射,文檔)
索引(index):索引就是一個(gè)擁有相似文檔的集合,索引由一個(gè)名字來(lái)唯一標(biāo)識(shí)(全小寫),在對(duì)這個(gè)索引中的文檔進(jìn)行索引、搜索、更新和刪除的時(shí)候都要使用這個(gè)索引名。
映射(mapping):定義一個(gè)文檔和它所包含的字段如何被存儲(chǔ)和索引的過(guò)程,mapping中主要包括字段及其類型。動(dòng)態(tài)映射,根據(jù)文檔自動(dòng)創(chuàng)建mapping,靜態(tài)映射,存儲(chǔ)文檔前自定義mapping(更符合業(yè)務(wù)實(shí)際場(chǎng)景)。
文檔(document):文檔中存儲(chǔ)的一條條數(shù)據(jù),一條文檔是可被索引的最小單元,文檔采用輕量級(jí)的JSON數(shù)據(jù)格式來(lái)表示。

基本操作
索引
# 1.查看索引
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana-event-log-7.14.0-000001 fEP5eEZ5SmavP6C8FY6iSQ 1 0 4 0 21.8kb 21.8kb
green open .geoip_databases 2HuyGoOZRmuFBfbz5khHuw 1 0 41 34 41.5mb 41.5mb
green open .kibana_7.14.0_001 Nur7JeOSQkiqJZ8ek-N3dA 1 0 52 5 4.3mb 4.3mb
green open .apm-custom-link Lyy8YHKmRguONODxP6p2Vw 1 0 0 0 208b 208b
green open .apm-agent-configuration 1MwrINkORBiqoBipgvhycA 1 0 0 0 208b 208b
green open .kibana_task_manager_7.14.0_001 rihXKN13TF-q57ZXRJPyVw 1 0 14 2004 17mb 17mb
yellow open backup_products ijd5atmoQlKf2jC4MuA86g 1 1 0 0 208b 208b
green open products 7w2ie_Q0SIm7OHIOsBG_PQ 1 0 0 0 208b 208b
green open .tasks BE5vwDh0QgWJJorQJRdeCA 1 0 4 0 21.3kb 21.3kb
# 2.創(chuàng)建索引
#PUT /索引名 ====> PUT /products
- 注意:
1.ES中的索引健康狀態(tài) red(索引不可用) yellow(索引可用,存在風(fēng)險(xiǎn)) green(健康)
2.默認(rèn)ES創(chuàng)建索引時(shí)會(huì)為索引創(chuàng)建一個(gè)備份索引和一個(gè)primary索引
# 3.創(chuàng)建索引 進(jìn)行索引分片配置
PUT /products
{
"settings": {
"number_of_shards": 1, #指定主分片的數(shù)量
"number_of_replicas": 0 #指定副本分片的數(shù)量
}
}
# 4.創(chuàng)建成功返回
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "products"
}
# 5.刪除索引(不允許修改)
DELETE /products
映射
# 1.創(chuàng)建索引&映射
PUT /products
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"title":{
"type":"keyword",
"store": true
},
"price":{
"type":"double"
},
"create_at":{
"type":"date"
},
"description":{
"type":"text",
"store": true,
"analyzer": "standard"
}
}
}
}
# 2.查看已創(chuàng)建的索引映射
GET /products/_mapping
# 3.映射不允許修改,只能刪除
文檔
# 1.添加文檔
# 指定文檔id
POST /products/_doc/1
{
"title":"iphone13",
"price":7999.0,
"create_at":"2019-10-01",
"description":"Iphone13是一款性能不錯(cuò)的手機(jī),價(jià)格偏貴"
}
# 自動(dòng)生成文檔id
POST /products/_doc/
{
"title":"HuaweiP50",
"price":5999.0,
"create_at":"2021-10-01",
"description":"HuaweiP50是一款性能不錯(cuò)的手機(jī),喜歡拍照的女生可以購(gòu)買"
}
# 2.文檔的查詢
#基于id查詢
GET /products/_doc/1
#3.刪除文檔
#根據(jù)id刪除
DELETE /products/_doc/1
# 4.更新文檔
#根據(jù)id更新,刪除原始文檔再添加新文檔,若不想刪除原文檔,將原文檔全部字段傳遞
PUT /products/_doc/1
{
"title":"小米10"
}
#根據(jù)指定字段更新,保留原文檔
POST /products/_doc/1/_update
{
"doc":{
"title":"小米10"
}
}
# 5.批量操作文檔
# 增加兩條記錄,修改一條記錄,刪除一條記錄
POST /products/_doc/_bulk
{"index":{}}
{"title":"HuaweiMate40","price":6999.0,"create_at":"2020-10-01","description":"Huawei Mate 20是華為手機(jī)的謝幕之作"}
{"index":{}}
{"title":"Honor 60 Pro","price":3699.0,"create_at":"2021-10-01","description":"榮耀最新手機(jī)60 pro還是不錯(cuò)的"}
{"update":{"_id":3}}
{"doc":{"tilte":"華為P40 pro"}}
{"delete":{"_id":"R8WrNX8Be4vXDspnRdKS"}}
#批量操作時(shí)不會(huì)因?yàn)橐粋€(gè)失敗而全部失敗,而是繼續(xù)執(zhí)行后續(xù)操作,攢返回時(shí)按照?qǐng)?zhí)行的狀態(tài)返回!
六、高級(jí)查詢Query DSL
ES提供強(qiáng)大的數(shù)據(jù)檢索方式,這種方式稱之為Query DSL(Domain Specific Language),Query DSL是利用Rest API傳遞JSON格式的請(qǐng)求體數(shù)據(jù)與ES進(jìn)行交互,這種方式的豐富查詢語(yǔ)法讓ES檢索變得更強(qiáng)大,更簡(jiǎn)潔。
語(yǔ)法
GET /索引名/_search {json格式請(qǐng)求體數(shù)據(jù)}
# 1.查詢所有,match_all
GET /products/_search
{
"query": {
"match_all": {}
}
}
# 2.基于term查詢,term,注意text類型字段會(huì)分詞,其余類型均不會(huì)分詞
# 默認(rèn)text字段使用標(biāo)準(zhǔn)分詞器,英語(yǔ)是單個(gè)單詞分詞,中文是單字分詞
GET /products/_search
{
"query": {
"term": {
"title": {
"value": "iphone13"
}
}
}
}
# 3.基于范圍查詢查詢,range
GET /products/_search
{
"query": {
"range": {
"price": {
"gte": 5000,
"lte": 7000
}
}
}
}
# 4.基于前綴查詢,prefix
GET /products/_search
{
"query": {
"prefix": {
"title": {
"value": "iphone"
}
}
}
}
# 5.通配符查詢,?匹配任意一個(gè)字符, *匹配任意多個(gè)字符,wildcard
GET /products/_search
{
"query": {
"wildcard": {
"title": {
"value": "H?aweiMate*"
}
}
}
}
# 6.多ids查詢,ids
GET /products/_search
{
"query": {
"ids": {
"values": [1,2,3]
}
}
}
# 7.模糊查詢,fuzzy
#注意,fuzzy模糊查詢,最大模糊錯(cuò)誤必須在0-2之間
- 搜索關(guān)鍵詞長(zhǎng)度為2,不允許存在模糊
- 搜索關(guān)鍵詞長(zhǎng)度為3-5,允許一次模糊
- 搜索關(guān)鍵詞長(zhǎng)度為大于5,允許最大2模糊
GET /products/_search
{
"query": {
"fuzzy": {
"title": "Honor 60 pro"
}
}
}
# 8.bool查詢,bool(must,should,must_not)
#bool關(guān)鍵字:用來(lái)組合多個(gè)條件復(fù)雜查詢
- must:相當(dāng)于&&,必須成立
- should:相當(dāng)于||,
- must_not:相當(dāng)于!,必須不成立
GET /products/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"title": {
"value": "Honor 60 Pro"
}
}
},
{
"range": {
"create_at": {
"lt": "2021-10-01"
}
}
}
]
}
}
}
# 9.多字段查詢
# 注意:query輸入關(guān)鍵詞 輸入一段文本,搜索詞會(huì)分詞
GET /products/_search
{
"query": {
"multi_match": {
"query": "iphone13",
"fields": ["title","description"]
}
}
}
# 10.默認(rèn)字段查詢
# 注意:查詢字段類型是分詞則查詢條件會(huì)分詞查詢,查詢字段類型部分詞則查詢條件不會(huì)分詞查詢
GET /products/_search
{
"query": {
"query_string": {
"default_field": "description",
"query": "真貴"
}
}
}
# 11.高亮查詢,highlight
#只有分詞字段能高亮,通過(guò)pre_tags和post_tags自定義高亮標(biāo)簽
GET /products/_search
{
"query": {
"term": {
"description": {
"value": "iphone13"
}
}
},
"highlight": {
"fields": {
"description":{}
},
"pre_tags":"<a>",
"post_tags": "</a>"
}
}
# 12.分頁(yè)查詢,from,size
# 默認(rèn)from = 0, size = 10
GET /products/_search
{
"query": {
"match_all": {}
},
"size": 5,
"from": 2
}
# 13.查詢后排序,sort
#先按日期降序,再按價(jià)格升序排序
GET /products/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"create_at": {
"order": "desc"
}
},
{
"price": {
"order": "asc"
}
}
]
}
# 14.查詢后返回指定字段,_source
GET /products/_search
{
"query": {
"match_all": {}
},
"_source": ["title","price","create_at"]
}
七、索引原理
倒排索引:也叫反向索引,與數(shù)據(jù)庫(kù)的正向索引對(duì)應(yīng)。反向索引是通過(guò)value找key,再根據(jù)key拿記錄,ES底層再檢索使用的就是倒排索引。
現(xiàn)有索引和映射如下:
{
"products" : {
"mappings" : {
"properties" : {
"description" : {
"type" : "text",
},
"price" : {
"type" : "integer"
},
"title" : {
"type" : "keyword"
}
}
}
}
}
先錄入如下數(shù)據(jù),有三個(gè)字段title,price, description等
| _id | title | price | description |
|---|---|---|---|
| 1 | 蘋果手機(jī) | 13999.0 | 蘋果手機(jī)系統(tǒng)很流暢 |
| 2 | 華為電腦 | 8999.0 | 很不錯(cuò)的電腦 |
| 3 | 小米背包 | 129.0 | 年輕人的第一個(gè)背包,很好 |

八、分詞器
Analysis:文本分詞是把全文本轉(zhuǎn)換成一系列單詞(term/token)的過(guò)程,也叫分詞(Analyzer)。Analysis是通過(guò)Analyzer來(lái)實(shí)現(xiàn)的。 分詞就是將文檔通過(guò)Analyzer分成一個(gè)一個(gè)的Term(關(guān)鍵詞查詢),每一個(gè)Term都指向包含這個(gè)Term的文檔。
分詞器由三種構(gòu)建組成:Character Filters(0或多個(gè))->Tokenizers->Token Filters(0或多個(gè))
Character Filters:對(duì)文本進(jìn)行預(yù)處理,如過(guò)濾html標(biāo)簽;
Tokenizers分詞器: 標(biāo)準(zhǔn)分詞器將英文按空格分詞為單詞,中文單個(gè)漢字分詞;
Token Filters: 將切分單詞進(jìn)行加工,大小寫轉(zhuǎn)換,去除停用詞,加入同義詞等。
內(nèi)置分詞器
- Standard Analyzer:默認(rèn)分詞器,英文按單詞詞切分,并小寫處理;
- Simple Analyzer:按照單詞切分(符號(hào)被過(guò)濾),小寫處理;
- Stop Analyzer:小寫處理,停用詞過(guò)濾;
- Whitespace Analyzer:按照空格切分,不轉(zhuǎn)小寫;
- Keyword Analyzer:不分詞,直接將輸入作為輸出。
# 1.標(biāo)準(zhǔn)分詞器
GET /_analyze
{
"analyzer": "standard",
"text":"中華人民共和國(guó),I am Chinese"
}
# 2.simple分詞器
GET /_analyze
{
"analyzer": "simple",
"text":"中華人民共和國(guó),I am Chinese"
}
# 3.stop分詞器
GET /_analyze
{
"analyzer": "stop",
"text":"中華人民共和國(guó),I am Chinese"
}
# 4.whitespace分詞器
GET /_analyze
{
"analyzer": "whitespace",
"text":"中華人民共和國(guó),I am Chinese"
}
# 5.keyword分詞器
GET /_analyze
{
"analyzer": "keyword",
"text":"中華人民共和國(guó),I am Chinese"
}
# 6.ik分詞器(ik_smart)
{
"analyzer": "ik_smart",
"text":"中華人民共和國(guó),I am Chinese"
}
# 7.ik分詞器(ik_max_word,切分更細(xì))
{
"analyzer": "ik_smart",
"text":"中華人民共和國(guó),I am Chinese"
}
IK中文分詞器
安裝IK分詞器
# github地址:https://github.com/medcl/elasticsearch-analysis-ik
- 注意IK分詞器的版本與ES的版本要一致
- Docker容器運(yùn)行ES安裝插件目錄為:/usr/share/elasticsearch/plugins
# 1.下載對(duì)應(yīng)版本
- wget https://github.com/medcl/elasticsearch-analysis-ik/release/download/v7.14.0/elasticsearch-analysis-ik.zip
# 2.解壓安裝包
- tar -zxvf elasticsearch-analysis-ik.zip ./
# 3.映射plugins
- ./plugins/ik-7.14.0:/usr/share/elasticsearch/plugins/ik-7.14.0
IK的兩種顆粒度拆分
- ik_smart: 做最粗粒度的拆分
- ik_max_word:文本按最細(xì)粒度的拆分
擴(kuò)展詞、停用詞
- 擴(kuò)展詞典:有些詞不是關(guān)鍵詞,但是也希望被ES用來(lái)作為檢索的關(guān)鍵詞,可以將這些詞加入到擴(kuò)展詞典。
-
停用詞典:有些詞是關(guān)鍵詞,但出于業(yè)務(wù)場(chǎng)景不想使用這些關(guān)鍵詞被檢索到,可以將這些詞放入停用詞典。
定義擴(kuò)展詞典和停用詞典可以修改IK分詞器中config目錄中IKAnalyzer.cfg.xml文件。
#1.修改vim IKAnalyzer.cfg.xml,配置擴(kuò)展詞典項(xiàng)與停用詞典項(xiàng)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴(kuò)展配置</comment>
<!--用戶可以在這里配置自己的擴(kuò)展字典 -->
<entry key="ext_dict">my_ext.dic<entry>
<!--用戶可以在這里配置自己的擴(kuò)展停止詞字典-->
<entry key="ext_stopwords">my_stop.dic</entry>
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
#2.重啟elasticsearch服務(wù)即可
九、過(guò)濾查詢
Filter查詢:過(guò)濾查詢只會(huì)篩選符合條件的文檔并不會(huì)計(jì)算得分,而且它可以緩存文檔,查詢性能優(yōu)于query。適合在大范圍篩選數(shù)據(jù),而query適合精確匹配數(shù)據(jù)。一般應(yīng)用是,應(yīng)先使用過(guò)濾操作過(guò)濾數(shù)據(jù),然后使用查詢匹配數(shù)據(jù)。

# 注意:
- filter查詢必須配合bool使用;
- 在執(zhí)行filter和query時(shí),先執(zhí)行filter再執(zhí)行query;
- ElasticSearch會(huì)自動(dòng)緩存經(jīng)常使用的過(guò)濾器,以加快性能。
#常用的過(guò)濾類型:term, terms, range, exists, ids等f(wàn)ilter
GET /products/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": [
{
"terms": {
"title": [
"Honor 60 Pro",
"iphone13"
]
}
}
]
}
}
}
十、集群cluster
集群主要是為了高可用,單節(jié)點(diǎn)的問(wèn)題主要是:
- 存在單節(jié)點(diǎn)故障問(wèn)題;
- 存在單節(jié)點(diǎn)并發(fā)壓力問(wèn)題,高并發(fā)場(chǎng)景下崩潰;
- 存在單節(jié)點(diǎn)物理上線問(wèn)題,存儲(chǔ)磁盤不夠用等。
相關(guān)概念
| 概念 | 含 義 |
|---|---|
| 集群<cluster> | 一個(gè)或多個(gè)節(jié)點(diǎn)組織在一起,共同持有所有的數(shù)據(jù),并一起提供索引和搜索功能。一個(gè)集群由唯一的名字標(biāo)識(shí)。默認(rèn)elasticsearch,節(jié)點(diǎn)通過(guò)指定某個(gè)集群的名字來(lái)加入集群。 |
| 節(jié)點(diǎn)<node> | 集群中的一個(gè)服務(wù)器,負(fù)責(zé)存儲(chǔ)數(shù)據(jù),參與集群的索引與搜索功能,一個(gè)節(jié)點(diǎn)由一個(gè)名字來(lái)標(biāo)識(shí)。 |
| 索引<index> | 一組相似文檔的集合 |
| 映射<mapping> | 用以定義文檔及其字段如何被索引與存儲(chǔ)的過(guò)程 |
| 文檔<document> | 索引中的一條記錄,可以被索引的最小單元 |
| 分片<shards> | 提供將索引劃分成多份的能力,每一份就是一個(gè)分片,每個(gè)分片本身就是一個(gè)功能完善并且獨(dú)立的“索引”。 |
| 副本<replicas | Index的分片中一份或多份副本。 |
集群搭建
# 1.準(zhǔn)備三個(gè)ES節(jié)點(diǎn),ES 9200 9300
- http:9201 tcp:9301 node-1 elasticsearch.yml
- http:9202 tcp:9302 node-1 elasticsearch.yml
- http:9203 tcp:9303 node-1 elasticsearch.yml
-注意
- 所有節(jié)點(diǎn)集群名稱必須一直 cluster.name
- 每個(gè)節(jié)點(diǎn)必須有唯一名字 node.name
- 開(kāi)啟每個(gè)節(jié)點(diǎn)遠(yuǎn)程連接 network.host: 0.0.0.0
- 指定使用IP地址進(jìn)行集群節(jié)點(diǎn)通信: network.publish_host
- 修改web端口與tcp端口:http:port transport.tcp.port
- 指定集群中所有節(jié)點(diǎn)通信列表:discovery.seed_hosts:node-1 node-2 node-3
- 允許集群初始化master節(jié)點(diǎn)數(shù):cluster.initial_master_nodes:[ "node-1", "node-2", "node-3" ]
- 集群最少幾個(gè)節(jié)點(diǎn)可用:gateway.recover_after_nodes:2
- 開(kāi)啟每個(gè)節(jié)點(diǎn)跨域訪問(wèn):http.cors.enabled:true http.cors.allow-origin: "*"
# node1配置
cluster.name: my-application
node.name: node-1
network.host: 127.0.0.1
network.publlish_host: 127.0.0.1
http.port: 9201
transport.tcp.port: 9301
discovery.seed_hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
gateway.recover_after_nodes: 2
http.cors.enabled: true
http.cors.allow-origin: "*"
# node2配置
cluster.name: my-application
node.name: node-2
network.host: 127.0.0.1
network.publlish_host: 127.0.0.1
http.port: 9202
transport.tcp.port: 9302
discovery.seed_hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
gateway.recover_after_nodes: 2
http.cors.enabled: true
http.cors.allow-origin: "*"
# node3配置
cluster.name: my-application
node.name: node-3
network.host: 127.0.0.1
network.publlish_host: 127.0.0.1
http.port: 9203
transport.tcp.port: 9303
discovery.seed_hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
gateway.recover_after_nodes: 2
http.cors.enabled: true
http.cors.allow-origin: "*"
# docker-compose.yml配置
version: "3.8"
volumes:
data:
config:
networks:
esclusetr:
services:
es01:
image: elasticsearch:7.14.0
environment:
- "discovery.type=single-node"
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
image: "elasticsearch:7.14.0"
ports:
- "9200:9201"
- "9300:9301"
networks:
- "esclusetr"
volumes:
- ./node-1/data:/usr/share/elasticsearch/data
- ./node-1/config:/usr/share/elasticsearch/config
- ./node-1/plugins/ik-7.14.0:/usr/share/elasticsearch/plugins/ik-7.14.0
es02:
image: elasticsearch:7.14.0
environment:
- "discovery.type=single-node"
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
image: "elasticsearch:7.14.0"
ports:
- "9200:9202"
- "9300:9302"
networks:
- "esclusetr"
volumes:
- ./node-2/data:/usr/share/elasticsearch/data
- ./node-2/config:/usr/share/elasticsearch/config
- ./node-2/plugins/ik-7.14.0:/usr/share/elasticsearch/plugins/ik-7.14.0
es03:
image: elasticsearch:7.14.0
environment:
- "discovery.type=single-node"
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
image: "elasticsearch:7.14.0"
ports:
- "9200:9203"
- "9300:9303"
networks:
- "esclusetr"
volumes:
- ./node-3/data:/usr/share/elasticsearch/data
- ./node-3/config:/usr/share/elasticsearch/config
- ./node-3/plugins/ik-7.14.0:/usr/share/elasticsearch/plugins/ik-7.14.0
kibana:
image: kibana:7.14.0
ports:
- "5601:5601"
networks:
- "es"
volumes:
- ./kibana.yml:/usr/share/kibana/config/kibana.yml
#查看集群狀態(tài)
http://127.0.0.1:9201/_cat/health?v
Head插件查看集群狀態(tài)
# 1.訪問(wèn)github網(wǎng)站
搜索:elasticsearch-head插件
# 2.安裝git
yum install git
# 3.下載elasticsearch-head到本地
git clone git://github.com/mobz/elasticsearch-head.git
# 4.安裝node.js
wget http://cdn.npm.taobao.org/dist/node/lastest-v8.x/node-v8.1.2-linux-x64.tar.xz
# 5.解壓縮node.js
tar -xvf node-v10.15.3-linux-arm64.tar
# 6.設(shè)置環(huán)境變量
mv node-v10.15.3-linux-arm64 nodejs
mv nodejs /usr/nodejs
vim /etc/profile
- export NODE_HOME=/usr/nodejs
- export PATH=$PATH:$JAVA_HOME/bin:$NODE_HOME/bin
# 7.進(jìn)入elasticsearch-head目錄
npm config set registry https://registry.npm.taobao.org
npm install
npm run start
# 8.啟動(dòng)訪問(wèn)head插件 默認(rèn)端口9100
http://127.0.0.1:9100 查看集群狀態(tài)

十一、核心原理
11.1 ES的寫入與檢索原理

- 假如選擇了Node2(DataNode)發(fā)送請(qǐng)求,此時(shí)Node2稱為coordinating node(協(xié)調(diào)節(jié)點(diǎn))
- 計(jì)算得到文檔要寫入的分片 shard = hash(routing) % number_of_primary_shards routing 是一個(gè)可變值,默認(rèn)是文檔的 _id
- coordinating node會(huì)進(jìn)行路由,將請(qǐng)求轉(zhuǎn)發(fā)給其他DataNode(對(duì)應(yīng)某個(gè)primary shard,假如主分片在Node1節(jié)點(diǎn)上)
- Node1上的Primary Shard處理請(qǐng)求,寫入數(shù)據(jù)到索引庫(kù)中,并將數(shù)據(jù)同步到其他的Replica Shard中
- Primary Shard 和 Replica Shard都保存完文檔后,返回客戶端。

- 假如選擇了Node2,此時(shí)Node2稱為coordinating node(協(xié)調(diào)節(jié)點(diǎn))
- 協(xié)調(diào)節(jié)點(diǎn)(Coordinating Node)將查詢請(qǐng)求廣播到每一個(gè)數(shù)據(jù)節(jié)點(diǎn),這些數(shù)據(jù)節(jié)點(diǎn)的分片會(huì)處理該查詢請(qǐng)求。
- 每個(gè)分片進(jìn)行數(shù)據(jù)查詢,將符合條件的數(shù)據(jù)放在一個(gè)優(yōu)先隊(duì)列中,并將這些數(shù)據(jù)的文檔ID、節(jié)點(diǎn)信息、分片信息返回給協(xié)調(diào)節(jié)點(diǎn)。
- 協(xié)調(diào)節(jié)點(diǎn)將所有的結(jié)果進(jìn)行匯總,并進(jìn)行全局排序。
- 協(xié)調(diào)節(jié)點(diǎn)向包含這些文檔ID的分片發(fā)送get請(qǐng)求,對(duì)應(yīng)的分片將文檔數(shù)據(jù)返回給協(xié)調(diào)節(jié)點(diǎn),最后協(xié)調(diào)節(jié)點(diǎn)將數(shù)據(jù)返回給客戶端。