核心概念
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index.html
什么是搜索引擎?
- 全文搜索引擎
自然语言处理(NLP)、爬虫、网页处理、大数据处理。如谷歌、百度、搜狗、必应等等。
- 垂直搜索引擎
有明确搜索目的的搜索行为。各大电商网站、OA、站内搜索、视频网站等。
面向海量数据,如何达到“搜索引擎”级别的查询效率?
索引:
- 帮助快速检索
- 以数据结构为载体
- 以文件的形式落地
数据库的存储数据最终也是以文件形式落地的。
节点
-
每个节点就是一个Elasticsearch的实例(一个java进程)。
-
一个节点≠一台服务器。
生产环境下一台服务器启动一个节点。
启动的时候,可以在一个文件夹里边启动多个节点,也可以在每个文件夹里边启动一个节点(node1、node2文件夹)。
这里是启动了9个节点。
角色
master:候选节点
data:数据节点
data_content:数据内容节点
data_hot:热节点
data_warm:索引不再定期更新,但仍可查询
data_code:冷节点,只读索引
Ingest:预处理节点,作用类似于Logstash中的Filter
ml:机器学习节点
remote_cluster_client:候选客户端节点
transform:转换节点
voting_only:仅投票节点(master也是一个投票节点,也有的节点只是一个投票节点)
node-1\2\3是master候选节点,node-3是一个主节点,3宕机了,会从master中选举出来一个主节点
node-4到node-9是data候选节点
分片
- 一个索引包含一个或多个分片,在7.0之前默认五个主分片,每个主分片一个副本;在7.0之后默认一个主分片。副本可以在索引创建之后修改数量,但是主分片的数量一旦确定不可修改,只能创建索引。
边框粗的是主分片,支持读写操作的,边框细的是副本分片,支持读操作的。一个主分片,可以有多个副本分片。
-
每个分片都是一个Lucene实例,有完整的创建索引和处理请求的能力。
-
ES会自动再nodes上做分片均衡。
假设副本分片数量由2变成3,副本上的数据会做 尽量、均匀的分布在每一个节点。尽量把节点的性能分配的均匀一点。
假设又增加了一个节点node-10(横向扩容,增加了数据的容量),会触发分片均衡。
- 一个doc不可能同时存在于多个主分片中,但是当每个主分片的副本数量不为一时,可以同时存在于多个副本中。
- 每个主分片和其副本分片不能同时存在于同一个节点上,所以最低的可用配置是两个节点互为主备。
my_test索引文件分成了3个主分片,边框粗的0\1\2组成了一个完整的数据文件。
node-5的主分片0和副本分片0 不能同时存在于node-5节点上。
集群
-
原生分布式。
-
一个节点≠一台服务器。
集群的健康值检查
(1) 健康值状态
① Green:所有Primary和Replica均为active,集群健康
② Yellow:至少一个Replica不可用,但是所有Primary均为active,数据仍然是可以保证完整性的。
③ Red:至少有一个Primary为不可用状态,数据不完整,集群不可用。
(2) 健康值检查
① _cat/health( _cat/health?v)
② _cluster/health
索引和文档
类型-Type: 7.x 弱化 8.x完全删除。 过渡阶段使用 _doc。
文档-Document 就是我们存入的数据。
索引的CURD
基于REST风格的API
(1)创建索引:PUT /index?psretty
(2)查询索引:GET _cat/indices?v
(3)删除索引:DELETE /index?pretty
(4)插入数据:PUT /index/_doc/id{ Json数据}
(5)
-
全量替换
PUT /index/_doc/id
-
指定字段更新
POST /index/_update/id
(6)删除数据 DELETE /index/type/id
创建索引
PUT /product
查询该索引下的所有信息
GET /product/_search
查询该索引下第一条数据
GET /product/_doc/1
插入和更新都是用的PUT
修改1的数据,把价格改为3999,再次执行。再次查询一下,数据已经被修改。
1.更新的时候把json的内容都写上,只修改了price的值。结果json内容还是都存在的
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"price" : 13999,
"tags": [ "xingjiabi", "fashao", "buka" ]
}
2.更新的时候只把price写上了,结果json内容变成了只有price的了。
PUT /product/_doc/1
{
"price" : 13999
}
那有没有办法只更新price字段值呢?
POST /product/_doc/1/_update
{
"doc":{
"price" : 999
}
}
再次查询,确实只更新了price的值。
在更新的时候给出的提示,推荐使用另一个语法。
#! Deprecation: [types removal] Specifying types in document update requests is deprecated, use the endpoint /{index}/_update/{id} instead.
使用这个语法试试。
POST /product/_update/1
{
"doc":{
"price" : 9991
}
}
再次查询,确实只更新了price的值。
删除索引
DELETE /product/_doc/1
PUT /product/_doc/2
{
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"price" : 4999,
"tags": [ "xingjiabi", "fashao", "gongjiaoka" ]
}
PUT /product/_doc/3
{
"name" : "nfc phone",
"desc" : "shouji zhong de hongzhaji",
"price" : 2999,
"tags": [ "xingjiabi", "fashao", "menjinka" ]
}
PUT /product/_doc/4
{
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"price" : 999,
"tags": [ "low", "bufangshui", "yinzhicha" ]
}
PUT /product/_doc/5
{
"name" : "hongmi erji",
"desc" : "erji zhong de kendeji",
"price" : 399,
"tags": [ "lowbee", "xuhangduan", "zhiliangx" ]
}