学习Elasticsearch做的笔记之三。
目录
01~05 ElasticSearch
1、什么是搜索。
2、如果用数据库做搜索会怎样。
3、什么是全文检索、倒排索引、Lucene。
(1)全文检索,倒排索引。
(2)Lucene.jar
4、什么是ElasticSearch。
5、ElasticSearch的功能。
(1)分布式的搜索引擎、数据分析引擎。
(2)全文检索、结构化检索、数据分析。
6、ElasticSearch的适用场景。
7、ES的特点。
8、ElasticSearch的核心概念。
06_快速入门案例实战之电商网站商品管理:集群健康检查。
一、简单的集群管理。
1、查看ES是否启动。
2、查看ES健康状况。
3、快速检查集群的健康状况。
4、快速查看集群中有哪些索引。
5、创建索引。
6、删除索引。
二、商品的CRUD操作。
1、新增商品:新增文档,建立索引。
2、查询商品:检索文档。
3、修改商品:替换文档。
4、修改商品:更新文档。
5、删除商品:删除文档。
07_快速入门案例实战之电商网站商品管理:多种搜索方式。
1、query string search
(1)搜索全部数据记录。
(2)带参数条件搜索数据记录,按某个field字段降序排序。
2、query DSL
(1)查询所有数据记录。
(2)带参数条件搜索数据记录,按某个field字段降序排序。
(3)分页查询数据记录。
(4)指定要查询出那几个field字段。
3、query filter
4、full-text search
5、phrase search
6、highlight search
08_快速入门案例实战之电商网站商品管理:嵌套聚合,下钻分析,聚合分析。
1、聚合分析,统计每个tag下的数量。
2、聚合分析,指定名称中包含某个商品名称,统计每个tag下的数量。
3、聚合分析,先分组,再计算每个分组的平均值。
4、聚合分析,计算每个tag下的平均值,并且安装平均值降序排序。
5、聚合分析,先按照指定数字区间进行分组,在分组的基础上再按照tag进行分组,最后计算每个分组的平均价格。
09_手工画图剖析Elasticsearch的基础分布式架构。
1、Elasticsearch对复杂分布式机制的透明隐藏特性。
2、Elasticsearch的垂直扩容与水平扩容。
3、增加或减少节点的时候,数据rebalance。
4、master节点。
5、节点对等的分布式架构。
10_shard&replica机制再次梳理以及单node环境中创建index图解。
1、_shard&replica机制再次梳理
2、单node节点环境中创建index情景。
11_图解2个node环境下replica shard是如何分配的。
1、2个node环境下replica shard是如何分配的。
12_分布式原理_图解横向扩容过程,如何超出扩容极限,以及如何提升容错性。
1、横向扩容过程,如何超出扩容极限,以及如何提升容错性。
13_图解Elasticsearch容错机制:master选举,replica容错,数据恢复。
1、Elasticsearch容错机制:master选举,replica容错,数据恢复。
14_初步解析document的核心元数据以及图解剖析index创建反例。
1、_index元数据。
2、_type元数据。
3、id元数据。
15_document id的手动指定与自动生成两种方式解析。
1、手动指定document的id。
2、ES自动生成document的id。
16_document的_source元数据以及定制返回结果解析。
1、_source元数据。
2、定制返回结果。
17_document的全量替换、强制创建以及图解lazy delete机制。
1、document的全量替换。
2、document的强制创建。
3、document的删除。
19_深度图解剖析悲观锁与乐观锁两种并发控制方案。
1、悲观锁。
2、乐观锁。
01~05 ElasticSearch
1、什么是搜索。
百度搜索,垂直搜索(站内搜索),互联网搜索(电商网站、招聘网站、新闻网站、各种APP),IT系统的搜索(OA软件、办公自动化软件、会议管理、日程管理、项目管理),电商网站管理后台搜索订单。
搜索就是在任何场景下,找你想要的信息,输入你要搜索的关键字,找到这个关键字相关的信息。
2、如果用数据库做搜索会怎样。
(1)每条记录的指定字段的文本可能会很长。比如商品描述。
(2)不能将搜索词拆分开来,搜索更多符合期望的结果。
3、什么是全文检索、倒排索引、Lucene。
(1)全文检索,倒排索引。
ES引擎把文档数据写入到倒排索引的数据结构中,倒排索引建立的是分词Term和文档之间的映射关系。在倒排索引中,数据是面向词而不是面向文档的。
一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表。
(2)Lucene.jar
里面包含各种封装好的建立倒排索引,用于进行搜索的代码,各种算法。
用Lucene的api去进行开发,将已有的数据在磁盘上建立索引,组织索引的数据结构,可以对磁盘上的索引数据,进行搜索。
4、什么是ElasticSearch。
(1)自动维护数据分布到多个节点的索引的建立,搜索请求分布到多个节点执行,然后汇合在一起返回。
(2)自动维护数据的冗余副本,部分机器宕机,不会丢失数据。
(3)基于Lucene封装了更多的高级功能,例如:复杂的搜索功能、聚合分析功能、基于地理位置的搜索。
(4)ES是分布式、高性能、高可用、可伸缩的搜索和分析系统。
分布式解决单台机器的Lucene承载不了很大的搜索请求,存储不了很大的索引。
可伸缩,可以扩容机器,几乎不用作任何改变。
高可用,ES节点很多,保证了高可用。
高性能,ES会作为搜索方面的优化。
5、ElasticSearch的功能。
(1)分布式的搜索引擎、数据分析引擎。
分布式搜索、数据分析、最近7天销量排名前10的某类商品,最近一个月访问量排名前7的版块。
(2)全文检索、结构化检索、数据分析。
搜索:
全文检索:有很多条大文本的数据,搜索是否包含某个关键字。例如:搜索商品名称包含牙膏的商品。
结构化检索:搜索某一类别的商品有哪些。例如:搜索商品分类为日化用品的商品。
部分匹配、自动完成、搜索纠错、搜索推荐。
数据分析:分析每一个商品分类下有多少个商品。
(3)对海量数据进行近实时的处理。
ES自动可以将海量数据分散存储到各台服务器,实现海量数据的检索和处理。在秒级别对数据进行搜索和分析。
6、ElasticSearch的适用场景。
(1)维基百科,全文检索,高亮,搜索推荐。
(2)The Guardian新闻网站、用户行为日志(点击、浏览、收藏、评论),社交网络数据(对某某新闻的相关看法),数据分析(公众反馈)。
(3)Stack Overflow程序讨论。全文检索,搜索相关问题和答案。
(4)GitHub开源代码高亮,搜索上千亿行代码。
(5)电商网站,检索商品。
(6)日志数据分析,ELK。
(7)商品价格监控网站,当商品低于用户设定的阈值时,通知用户。
(8)BI系统,商业智能Business Intelligence。ES执行数据分析和挖掘,Kibana进行数据可视化。
(9)站内搜索(电商、招聘、门户)、IT系统搜索(OA、CRM、ERP)。
7、ES的特点。
(1)可以作为一个大型分布式集群,处理PB级别数据,也可以运行在单机上。
(2)ES合并了全文检索、数据分析、分布式技术。
(3)开箱即用,非常简单。
(4)数据库功能不够用,ES作为补充。例如:全文检索同义词处理,相关度排名,复杂数据分析,海量数据近实时处理。
8、ElasticSearch的核心概念。
(1)Near Real Time(NRT):近实时。从写入数据到可以被搜索到,有1秒的延迟。
(2)Cluster:集群,包含多个节点,集群名称,每个节点属于那个集群通过配置实现。
(3)Node节点:集群中的一个节点,节点名称默认随机分配,默认节点会加入一个名称为elasticsearch的默认集群。
(4)Index:索引。相当于数据库中的“库”,包含一堆有相似结构的文档数据。
一个Index包含多个document,一个index代表了一类类似的或者相同的document。
(5)type:类型。相当于数据库中“表”。每一个Index索引可以包含一个或多个type,type是index中的一个逻辑数据库分类,每一个type下的document具有相同的字段field。
(6)document和field:文档,相当于数据库表中的“行”。ES中的最小数据单元。一个document是一条数据。用json形式表示。
每一个index下的type中,可以有多个document,一个document里可以有多个field,每一个field就是一个字段。
(7)shard:分片。单台机器无法存储大量数据,ES可以将一个index索引中的数据切割分为多个分片shard,分别存储在多台服务器上,每个shard都是一个Lucene index。
(8)Replica:副本备份。ES为每个primary shard创建多个replica shard副本。默认一个primary shard有一个replica shard副本。
Replica shard个数可以修改。
Primary shard建立索引时默认5个,不能修改个数。
Primary shard主shard简称为shard。
Replica shard副本shard简称为replica。
ES最小的高可用配置需要两台服务器,每一台服务器存储部分primary shard和replica shard,互为主备。
ES默认每个index索引有10个shard,5个primary shard主shard,5个replica shard副本shard。
06_快速入门案例实战之电商网站商品管理:集群健康检查。
一、简单的集群管理。
1、查看ES是否启动。
http://localhost:9200/?pretty
1、查看ES是否启动。
http://localhost:9200/?pretty
2、查看ES健康状况。
GET _cluster/health
3、快速检查集群的健康状况。
GET _cat/health?v
GET _cat/health?v
elasticsearch-7.15.0启动一个ES就status是green?!status状态:
green:每个索引的主分片primary shard、副本分片replica shard都是活跃active状态的。
yellow:每个索引的主分片primary shard都是活跃active状态的,部分副本分片replica shard不是active状态,不可用状态。
red:不是每个索引的主分片primary shard都是活跃active状态的,部分索引有数据丢失。
4、快速查看集群中有哪些索引。
GET _cat/indices?v
5、创建索引。
PUT /test_index?pretty
6、删除索引。
DELETE /test_index?pretty
二、商品的CRUD操作。
1、新增商品:新增文档,建立索引。
语法格式:
PUT /index索引/type类型/商品ID
PUT /index/type/id
{
“json数据”
}
新增3个商品。
PUT /ecommerce/product/1
{
"name":"gaolujie yagao",
"desc": "gaoxiao meibai",
"price": 30,
"producer": "gaolujie producer",
"tags":["meibai", "fangzhu"]
}
PUT /ecommerce/product/2
{
"name":"jiajieshi yagao",
"desc": "youxiao fangzhu",
"price": 25,
"producer": "jiajieshi producer",
"tags":["fangzhu"]
}
PUT /ecommerce/product/3
{
"name":"zhonghua yagao",
"desc": "caoben meibai",
"price": 40,
"producer": "zhonghua producer",
"tags":["qingxin"]
}
ES自动创建index、type,默认对document每个字段field建立倒排索引,让字段field可以被搜索。
2、查询商品:检索文档。
语法格式:
GET /index索引/type类型/商品ID
查看商品ID为1的商品信息。
GET /ecommerce/product/1
3、修改商品:替换文档。
语法格式:
PUT /index索引/type类型/已经存在的商品ID
修改商品ID为1的商品名称。
PUT /ecommerce/product/1
{
"name":"jiaqiangban gaolujie yagao",
"desc": "gaoxiao meibai",
"price": 30,
"producer": "gaolujie producer",
"tags":["meibai", "fangzhu"]
}
替换必须带上所有全部的字段field,才能去进行信息的修改,否则少字段会丢失字段field数据,会覆盖数据。
4、修改商品:更新文档。
语法格式:
POST /index索引/type类型/商品ID/固定修改方法名称_update
修改商品ID为1的商品名称。
POST /ecommerce/product/1/_update
{
"doc":{
"name":"jiaqiangban gaolujie yagao"
}
}
5、删除商品:删除文档。
语法格式:
DELETE /index索引/type类型/商品ID
删除商品ID为1的商品。
DELETE /ecommerce/product/1
07_快速入门案例实战之电商网站商品管理:多种搜索方式。
1、query string search
(1)搜索全部数据记录。
(1)搜索全部数据记录。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
搜索全部商品。
GET /ecommerce/product/_search
返回响应json字段解释:
took:消耗了多少毫秒。
time_out:是否超时,false没有超时,true超时。
_shards:数据拆分成了几个分片,搜索请求会发送到所有的primary shard或者replica shard。
_shards.total:数据拆分成了几个分片。
_shards.successful:搜索成功了几个分片。
_shards.skipped:搜索跳过了几个分片。
_shards.failed:搜索失败了几个分片。
hits.total:搜索出了几条记录,查询出了几个document。
hits.tmax_score:匹配分数,数据记录与查询条件的相关匹配度,document对于一个search的相关度的匹配分数。相关匹配度越高,分数越高。
hits.hits:查询出的数据记录,包含了匹配搜索出的document的详细数据。
(2)带参数条件搜索数据记录,按某个field字段降序排序。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search?q=fieldName:fieldValue&sort=fieldName:desc
搜索商品名称中包含yagao的商品,并且按照售价降序排序。
GET /ecommerce/product/_search?q=name:yagao&sort=price:desc
2、query DSL
query DSL(Domain Specified Language,特定领域的语言):ES中特定的查询语法。
http request body:请求json内容体,可以构建各种复杂语法。
(1)查询所有数据记录。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {"match_all": {} }
}
搜索全部商品。
GET /ecommerce/product/_search
{
"query":
{
"match_all": {}
}
}
(2)带参数条件搜索数据记录,按某个field字段降序排序。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query":
{
"match": {
"fieldName": "fieldValue"
}
},
"sort": [
{"fieldName":"desc"}
]
}
查询商品名称中包含yagao的商品,并且按照售价降序排序。
GET /ecommerce/product/_search
{
"query":
{
"match": {
"name": "yagao"
}
},
"sort": [
{"price":"desc"}
]
}
(3)分页查询数据记录。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {
"match_all": {}
},
"from": start,
"size":pageSize
}
from:从第几条记录开始查询,0是第1条记录。
Size:每页显示条数。
分页查询商品,总共3条商品,每页显示1条记录,查询出第2页的数据。
GET /ecommerce/product/_search
{
"query": {
"match_all": {}
},
"from": 1,
"size":1
}
(4)指定要查询出那几个field字段。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {
"match_all": {}
},
"_source": [
"fieldName1","fieldName2"
]
}
指定查询出商品的名称、价格。
GET /ecommerce/product/_search
{
"query": {
"match_all": {}
},
"_source": [
"name","price"
]
}
3、query filter
对查询的数据进行过滤。
查询某个filed字段包含某个内容,并且某个filed大于某数字的记录。
有点类似sql:select * from table where fieldName1 like ‘%内容%’ and fieldName2>number
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {
"bool": {
"must": {
"match": {
"fieldName1": "fieldValue1"
}
},
"filter": {
"range": {
"fieldName2": {
"gt": fieldValue2
}
}
}
}
}
}
gt:大于某个数字。
查询商品名称包含yagao,并且售价大于25的商品。
GET /ecommerce/product/_search
{
"query": {
"bool": {
"must": {
"match": {
"name": "yagao"
}
},
"filter": {
"range": {
"price": {
"gt": 25
}
}
}
}
}
}
4、full-text search
全文检索,全文检索将输入的字符串拆解分开,与倒排索引一一相匹配,只要能匹配上任意一个拆分后的单词,就可以作为结果返回。
查询某个field字段包含“fieldValue1 fieldValue2”的记录。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {
"match": {
"fieldName": "fieldValue1 fieldValue2"
}
}
}
原先ES里已经有3条记录,再插入一条数据用于测试。
PUT /ecommerce/product/4
{
"name":"special yagao",
"desc": "special meibai",
"price": 50,
"producer": "special yagao producer",
"tags":["meibai"]
}
查询producer生产商包含“yagao producer”的记录。
优先按“yagao producer”去搜索,并且会拆分成“yagao”和“producer”去搜索。
查询出来的_score评分不一样。
GET /ecommerce/product/_search
{
"query": {
"match": {
"producer": "yagao producer"
}
}
}
producer这个field字段,会先被拆解,建立倒排索引。
| 关键词term | ID列表 |
| special | 4 |
| yagao | 4 |
| producer | 1,2,3,4 |
| jiajieshi | 2 |
| zhonghua | 3 |
| gaolujie | 1 |
5、phrase search
短语搜索,短语搜索不会拆分输入的字符串,在指定的field字段中,字符串作为一个整体,要求完全包含输入的字符串,一模一样,只有这样,才会作为匹配结果返回。
查询field字段中完全包括某个字符串内容的记录。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {
"match_phrase": {
"fieldName": "fieldValue1"
}
}
}
查询producer生产商完全包含“yagao producer”的记录。
GET /ecommerce/product/_search
{
"query": {
"match_phrase": {
"producer": "yagao producer"
}
}
}
6、highlight search
高亮搜索结果,在页面上用红色标记显示搜索的内容,用HTML标签内容标记。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"query": {
"match": {
"fieldName": "fieldValue1"
}
},
"highlight": {
"fields": {
"fieldName": {}
}
}
查询field字段producer中包含内容“producer”的记录,并且高亮显示。
GET /ecommerce/product/_search
{
"query": {
"match": {
"producer": "producer"
}
},
"highlight": {
"fields": {
"producer": {}
}
}
}
查询field字段producer中完全包含内容“yagao producer”的记录,并且高亮显示。
GET /ecommerce/product/_search
{
"query": {
"match_phrase": {
"producer": "yagao producer"
}
},
"highlight": {
"fields": {
"producer": {}
}
}
}
08_快速入门案例实战之电商网站商品管理:嵌套聚合,下钻分析,聚合分析。
1、聚合分析,统计每个tag下的数量。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"aggs": {
"group_by_name":{
"terms": {
"field": "fieldName"
}
}
}
}
修改一下tags字段。
PUT /ecommerce/_mapping/product?include_type_name=true
{
"properties": {
"tags": {
"type": "text",
"fielddata": true
}
}
}
aggs:聚合。group_name:聚合名字取名,根据需要取名。
terms:按照指定的field字段分组,分组之后统计每个分组中的document数量。
计算某个tag下的商品数量。
GET /ecommerce/product/_search
{
"aggs": {
"group_by_tags":{
"terms": {
"field": "tags"
}
}
}
}
buckets:按照tags分组,每一个组是一个bucket分桶。
设置"size": 0,属性不查询出原始数据。
GET /ecommerce/product/_search
{
"size": 0,
"aggs": {
"group_by_tags":{
"terms": {
"field": "tags"
}
}
}
}
2、聚合分析,指定名称中包含某个商品名称,统计每个tag下的数量。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"size": 0,
"query": {
"match": {
"fieldName": "fieldValue"
}
},
"aggs": {
"group_by_name":{
"terms": {
"field": "fieldName"
}
}
}
}
对名称中包含yagao的商品,计算每个tag下的商品的数量。
GET /ecommerce/product/_search
{
"size": 0,
"query": {
"match": {
"name": "yagao"
}
},
"aggs": {
"group_by_tags":{
"terms": {
"field": "tags"
}
}
}
}
先搜索,再分析。
3、聚合分析,先分组,再计算每个分组的平均值。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"size": 0,
"aggs": {
"group_by_name": {
"terms": {
"field": "fieldName1"
},
"aggs": {
"avg_name": {
"avg": {
"field": "fieldName2"
}
}
}
}
}
}
aggs:聚合。group_name:聚合名字取名,根据需要取名。
terms:按照指定的field字段fieldName1分组,分组之后统计每个分组中的document数量。
avg_name:聚合名字取名,计算平均价格聚合名称,根据需要取名。
avg:根据指定字段fieldName2,计算每个分组的平均价格。
计算每个tag下的商品平均价格。
GET /ecommerce/product/_search
{
"size": 0,
"aggs": {
"group_by_tags": {
"terms": {
"field": "tags"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
4、聚合分析,计算每个tag下的平均值,并且安装平均值降序排序。
语法格式:
GET /index索引/type类型/固定搜索方法名称_search
{
"size": 0,
"aggs": {
"group_by_name": {
"terms": {
"field": "fieldName1",
"order": {
"avg_name": "desc"
}
},
"aggs": {
"avg_name": {
"avg": {
"field": "fieldName2"
}
}
}
}
}
}
aggs:聚合。group_name:聚合名字取名,根据需要取名。
terms:按照指定的field字段fieldName1分组,分组之后统计每个分组中的document数量。
avg_name:聚合名字取名,计算平均价格聚合名称,根据需要取名。
avg:根据指定字段fieldName2,计算每个分组的平均价格。
order.avg_name:desc,按照降序排序。
计算每个tag下的商品的平均价格,并且按照平均价格降序排序。
GET /ecommerce/product/_search
{
"size": 0,
"aggs": {
"group_by_tags": {
"terms": {
"field": "tags",
"order": {
"avg_price": "desc"
}
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
5、聚合分析,先按照指定数字区间进行分组,在分组的基础上再按照tag进行分组,最后计算每个分组的平均价格。
语法格式:
见如下例子。
按照指定的价格范围区间进行分组,然后在某个分组内再根据tag进行分组,最后计算每个分组的平均价格。
GET /ecommerce/product/_search
{
"size": 0,
"aggs": {
"group_by_price": {
"range": {
"field": "price",
"ranges": [
{
"from": 0,
"to": 20
},
{
"from": 20,
"to": 40
},
{
"from": 40,
"to": 60
}
]
},
"aggs": {
"group_by_tags": {
"terms": {
"field": "tags"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
}
}
09_手工画图剖析Elasticsearch的基础分布式架构。
1、Elasticsearch对复杂分布式机制的透明隐藏特性。
ES是一套分布式系统,分布式是为了应对大数据量,隐藏了复杂的机制。
分片机制。
Cluster discovery集群发现机制。
Shard负载均衡,ES自动进行均衡分配,保持每个节点的请求数量的读写负载均衡。
Shard副本,请求路由,集群扩容,shard重分配。
2、Elasticsearch的垂直扩容与水平扩容。
垂直扩容:采购功能更强大的服务器,与先前的已使用的普通服务器不一样。
横向水平扩容:使用相同的普通的服务器组织在一起,构成强大的计算和存储能力。
一般采取水平扩容方案。每个shard可以占用的节点上更多资源(IO、CPU、Memory),整个系统性能会更好。
3、增加或减少节点的时候,数据rebalance。
增加或减少节点的时候,数据rebalance重新分配,使每个服务器尽量承载的数据均衡一些,实现负载均衡。
4、master节点。
Master节点管理ES集群的元数据,例如:索引的创建和删除,维护索引和集群的元数据,节点的增加和移出。
自动选出master节点,master不承载所有的请求。
5、节点对等的分布式架构。
节点对等,每个节点都能接收所有的请求,请求可以发送给任何节点。
自动将请求路由到有相关数据的节点上。
响应收集,原始接收客户端请求的节点,会汇总存储了相关数据的所有其他节点的数据,然后返回给客户端。
10_shard&replica机制再次梳理以及单node环境中创建index图解。
1、_shard&replica机制再次梳理
(1)index索引包含多个shard分片,数据记录document存储在shard中。
(2)每个shard都是一个最小的工作单元,承载部分数据,每1个shard都是1个Lucene实例,具有建立索引、处理请求的功能。
(3)增加减少节点时,shard分片自动在nodes节点中负载均衡。
(4)primary shard、replica shard,一条记录document只存在于某个primary shard和对应的replica shard,一条记录不能同时存在于多个primary shard中。
(5)Replica shard副本负责容错、读请求负载。
(6)Primary shard的数量在创建时固定了,不可以修改,replica shard的数量可以随时修改。
(7)Primary shard的数量默认是5,1个primary shard默认有1个replica shard。默认有10个shard,5个primary shard,5个replica shard。
(8)Primary shard不能与自己的replica shard部署在同一个服务器节点上。宕机会把主副本都丢失,不能容错。Primary shard可以与其他primary shard的replica shard部署在同一个服务器节点上。
2、单node节点环境中创建index情景。
PUT /test1_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
单node节点,创建1个index索引,number_of_shards指有3个primary shard,number_of_replicas指每个primary shard有1个replica shard,共有3个replica shard。
快速查看集群中有哪些索引。
GET _cat/indices?v
快速检查集群的健康状况。
GET _cat/health?v
集群status状态显示为yellow。
此时,只会将3个primary shard分配到1个服务node节点上去,因为是单台机器,另外3个replica shard是无法分配的。
虽然status状态显示为yellow,但是集群可以正常工作。
单台服务器node节点出现宕机,数据将全部丢失,整个集群不可用,发送接收任何请求。
11_图解2个node环境下replica shard是如何分配的。
1、2个node环境下replica shard是如何分配的。
单node节点环境中,增加1个node节点,ES会自动将未分配的replica shard分配到新增加的node节点上,分配3个replica shard。
Primary shard会将数据同步到replica shard。
Primary shard和replica shard都可以接受读请求。
12_分布式原理_图解横向扩容过程,如何超出扩容极限,以及如何提升容错性。
1、横向扩容过程,如何超出扩容极限,以及如何提升容错性。
(1)Primary shard、replica shard自动负载均衡,增加node节点,自动分配replica shard。
(2)扩容极限,此时,node服务器节点数与shard相同。6个shard,3个primary shard,3个replica shard,最多扩容到6台机器,每1个shard占用单台服务器所有资源。
(3)超出扩容极限,需要动态修改replica shard数量,Primary shard数量不能修改。
(4)3台服务器,6个shard,3个primary shard,3个replica shard,每台服务器上2个shard。容错性是2台,能容忍2台服务器宕机,数据不丢失。
(5)3台服务器,9个shard,3个primary shard,6个replica shard,每台服务器上有3个shard。容错性是2台,能容忍2台服务器宕机,数据不丢失。
(6)扩容就是提升系统整体吞吐量和容错性,让尽可能多的服务器宕机,保证数据不丢失。
13_图解Elasticsearch容错机制:master选举,replica容错,数据恢复。
1、Elasticsearch容错机制:master选举,replica容错,数据恢复。
从master node服务节点宕机到恢复的过程。
(1)9个shard,3个primary shard,6个replica shard,3个node服务器节点。
(2)master node服务器节点宕机。此时,不是所有的primary shard都是active状态,所以ES集群有一瞬间状态是red的。
(3)容错第1步,ES自动选举出新的master。
(4)容错第2步,Replica容错,新选举出的master将宕机的primary shard的某个replica shard提升为primary shard。
此时,所有的primary shard是active状态,少了1个replica shard,不是所有的replica shard状态都为active,集群状态为yellow。
(5)容错第3步,重启宕机的node节点服务器,新的master将缺失的副本复制到该宕机的node节点服务器,使用原有的shard数据,并且同步宕机后的修改。
此时,所有的primary shard和replica shard都是正常的,集群状态为green。
14_初步解析document的核心元数据以及图解剖析index创建反例。
1、_index元数据。
(1)表示一个document存放在哪个index索引中,一条记录存放在哪个index中。
(2)类似的数据存放在一个index索引中,非类似的数据存放在不同index索引中。类似是说每个document中的field字段很大一部分是相同的,这些数据的功能和支持的需求可能是类似的。
相同功能的数据放在一个index中,在自己独立的shard中,与其他的数据不在一个shard中,互不影响,提升查询数据的性能。
(3)index中包含了很多类似的document。
(4)index索引命名,索引的名称必须是小写字母的,不能用下划线开头,不能包含逗号。
2、_type元数据。
(1)表示document属于index索引中的那个类别type,表示记录属于index中那个类别。
(2)1个index索引划分的多个type,每个type具有很多相同的fields,不同的type可能有少数不同的fields,逻辑上进行分类。
例如:1个商品index中的type分为电子商品、生鲜商品、日化商品等。
(3)type类别命名,type的名称可以使大写或小写,不能用下划线开头,不能包含逗号。
3、id元数据。
(1)一条记录的唯一标识,一个document迭代唯一标识。一个_id与_index、_type组合在一起,唯一标识了一个document。
(2)可以手动指定document的_id,ES也可以自动生成。
15_document id的手动指定与自动生成两种方式解析。
1、手动指定document的id。
(1)从其他系统中,例如数据库中,导入一些数据到Elasticsearch中时。沿用原有数据库中数据的ID。
例如:
PUT /test_index/test_type/2
{
"test_content": "my test"
}
2、ES自动生成document的id。
例如:
POST /test_index/test_type
{
"test_content": "my test"
}
执行响应:
{
"_index" : "test_index",
"_type" : "test_type",
"_id" : "TyPCiHwBV51Sex99dF5l",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 6,
"_primary_term" : 3
}
GET /test_index/test_type/TyPCiHwBV51Sex99dF5l GET /test_index/test_type/UCPDiHwBV51Sex99b16v
自动生成的id长度为20个字符,使用GUID算法生成的ID,在分布式系统下不会产生重复。使用base64编码后,可以用于浏览器页面访问地址的安全URL。
16_document的_source元数据以及定制返回结果解析。
先新增1条件数据。
PUT /test_index/test_type/1
{
"test_field1": "test field1",
"test_field2": "test field2"
}
查看记录。
GET /test_index/test_type/1
响应返回:
{
"_index" : "test_index",
"_type" : "test_type",
"_id" : "1",
"_version" : 4,
"_seq_no" : 9,
"_primary_term" : 3,
"found" : true,
"_source" : {
"test_field1" : "test field1",
"test_field2" : "test field2"
}
}
1、_source元数据。
_source元数据,GET的时候,响应返回的_source,就是创建document时,放在request body中的json串,原样返回。
2、定制返回结果。
自定义返回的_source中包含哪些field字段。
GET /test_index/test_type/1?_source=test_field2
响应返回:
{
"_index" : "test_index",
"_type" : "test_type",
"_id" : "1",
"_version" : 4,
"_seq_no" : 9,
"_primary_term" : 3,
"found" : true,
"_source" : {
"test_field2" : "test field2"
}
}
用逗号隔开,指定返回多个field字段。
GET /test_index/test_type/1?_source=test_field1,test_field2
17_document的全量替换、强制创建以及图解lazy delete机制。
1、document的全量替换。
例如:
PUT /test_index/test_type/1
{
"test_field": "test_test111"
}
GET /test_index/test_type/1
(1)PUT时,如果document的id已经存在,就是全量替换document的json串内容操作。
如果document的id不存在,就是创建,新建。
(2)document是不可变的。如果要修改document的内容,第一种方式就是全量替换,直接对document重新建立索引,替换里面所有的内容。
(3)PUT全量替换时,ES会将旧的document记录标记为deleted状态,此时,旧的记录还不会被物理删除,只是查询不到了。然后新增指定的新document。
ES创建的document越来越多的时候,会在适当的时机自动删除标记为deleted状态的document记录。
2、document的强制创建。
新建document,不想全量替换document。
例如:
PUT /test_index/test_type/1/_create
{
"test_field": "test_test222"
}
PUT /test_index/test_type/1?op_type=create
{
"test_field": "test_test333"
}
3、document的删除。
例如:
DELETE /test_index/test_type/1
删除不会物理删除,将document记录标记为deleted状态,ES创建的document越来越多的时候,会在适当的时机自动删除标记为deleted状态的document记录。
19_深度图解剖析悲观锁与乐观锁两种并发控制方案。
1、悲观锁。
悲观锁很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,执行业务逻辑期间,别人拿不到锁,只有等锁释放后,才能拿到锁。
例如:关系数据库中的行锁、表锁、读锁、写锁。
悲观锁并发控制方案,就是在各种情况下,都上锁。上锁之后,就只有一个线程可以操作这一条数据了。
悲观锁的优点:方便,直接加锁,对应用程序来说,透明,不需要做额外的操作。
悲观锁的缺点:并发能力很低,同一时间只能有一条线程操作数据。
2、乐观锁。
乐观锁很乐观,每次去拿数据都认为别人不会修改,所以不会上锁。在更新的时候会去判断一下,在此期间,别人有没有去更新这个数据,可以使用版本号version等机制。
乐观锁不加锁,每个线程都可以任意操作。
乐观锁的优点:并发能力很高,不给数据加锁,大量线程并发操作。
乐观锁的缺点:麻烦,每次更新时,都需要先比较版本号version,然后可能需要重新加载数据,再次修改,再写入,这个过程可能要重复重试很多次。
例如:有线程A和线程B两个线程,有库存数量为100件的商品,数据记录version=1。
(1)线程A和线程B同时下单,读取商品记录,获取到数据记录,获取到的数据版本都为version=1。
(2)线程A先去将库存减1,因为线程A获取到的数据记录版本为version=1,与ES中的数据版本version=1是相同的,所以可以修改成功。修改成功后,此时ES中数据记录version=2,库存数量为99。
(3)线程B去减库存,在此之前获取到的数据的版本号version=1。然后与ES中的数据版本进行比较,因为ES中的数据的版本号version=2,版本号不相同,说明数据已经被其他人修改过了。此时线程B不会用100-1=99去更新库存,而是重新去数据库读取最新的数据版本version=2的商品数量99件,线程B用最新的数量99-1=98去更新库存,此时ES中数据记录version=3,库存数量为98。



