ElasticSearch 知识梳理笔记

摘要: 本文原创,转载请注明地址 https://www.cnblogs.com/baokang/p/18540660

一、ElasticSearch 是什么?

ElasticSearch 是一个分布式的、基于 Lucene 的搜索引擎数据分析引擎(服务器)

ElasticSearch 提供了 RESTful 风格的操作 API,是用 java 语言编写的开源软件,可以提供 PB 级别的数据存储与搜索

 

二、ElasticSearch 基本概念

ElasticSearch 是面向文档型的数据库,一条数据在 ElasticSearch 里面就是一个文档,以 JSON 的格式进行存储

索引(index)

类似于数据库,是文档数据的逻辑存储空间,是具有相似特征的文档的集合

文档(document)

是 ElasticSearch 中存储的基本数据单元,以 JSON 的格式表示,类似于 mysql 中的一条记录

类型(type)

在 ElasticSearch 早期版本中,用于对索引数据的逻辑分组,从 7.x 版本开始被移除,后续索引均为固定的 _doc 类型(具体原因是在 ES 中 不通 type 下的相同字段数据,在 lucene 中的处理方式是一样的,会导致数据冲突,需要进行特殊的处理)

字段(field)

字段是文档的基本组成部分,一个文档可以由多个字段组成,对应着要存储的数据的不同属性

字段可以是基本类型、数据类型或者嵌套类型

映射(mapping)

映射是对文档及其字段的类型、格式的元数据信息的定义,类似于数据库中的 scheme 

节点(node)

节点是 ElasticSearch 运行的一个实例,可以看出是组成 ElasticSearch 集群的一个独立服务器,一台物理机上可以有多个节点

节点按照其功能可以分成三种:主节点(Master Node)、协调节点(Coordinating Node)、数据节点(Data Node)

  • 主节点(Master Node):处理创建、删除索引等请求,维护集群状态信息,可以设置一个节点不承担主节点角色
  • 协调节点(Coordinating Node):处理客户端请求,把请求分发到合适的节点,把最终结果汇聚到一起,每一个节点默认起到了协调节点的作用
  • 数据节点(Data Node):用来保存数据的节点、在数据扩展上起到了关键作用,可以设置一个节点不承担数据节点角色

集群(cluster)

集群是一个或者多个节点的集合,这些节点协同工作存储数据和处理数据

分片(shard)

分片是 ElasticSearch 中存储数据的容器,所有文档都存储在分片中,一个索引由多个分片组成,分片可以分为主分片(primary shard)和副本分片(replica shard)

  • 主分片(primary shard):是文档数据存储的物理容器,用来解决数据水平扩展的问题,通过主分片,可以将数据分不到集群内的所有节点上,一个分片就是一个运行的 Lucene 实例
  • 副本分片(replica shard):是主分片的一个拷贝,用来备份数据,为搜索文档和返回文档提供读操作服务
    • 主分片可以对应 0 个、1 个或者多个副本分片
    • 副本分片数可以动态调整
    • 当主分片宕机的时候,副本分片提升为主分片
    • 副本分片和主分片不能分布在同一个节点上

 

三、ElasticSearch 数据类型

常见的数据类型如下

注意事项:

5.x版本之后不在支持 string类型,而是用 text、keyword 类型代替

  • text 类型字段不用于排序,需要使用分词器进行分词
  • keyword 用于索引结构化的字段,keyword 类型的字段只能精确搜索,不会分词

 

四、Kibana 基本操作

集群数据操作

# 获取集群信息
GET _cluster/health
# 获取节点信息
GET _cat/nodes
# 获取分片信息
GET _cat/shards
# 获取所有索引信息
GET /_cat/indices?v
# 查看所有映射信息
GET /_mapping?pretty=true
# 查看某一个索引映射信息
# 格式:GET {index_name}/_mapping?pretty=true
GET movies/_mapping?pretty=true
# 创建索引
PUT student_info
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"age": {
"type": "long"
},
"name": {
"type": "keyword"
},
"desc": {
"type": "text"
},
"hobby": {
"type": "text"
}
}
}
}

文档写操作

# 创建文档
# 如果命令中索引不存在的话,会自动创建索引
# 如果索引存在,索引中字段不存在,则会自动创建映射字段
POST users_info/_doc
{
"user" : "Mike",
"post_date" : "2019-04-15T14:12:12",
"message" : "trying out Kibana",
"ingfo": "Happy"
}
# 制定 id 创建文档
# 如果命令中索引不存在的话,会自动创建索引
# 如果索引存在,索引中字段不存在,则会自动创建映射字段
# 如果文档 id 已经存在,则会报错,提示文档已经存在(document already exists)
POST users_info/_doc/5?op_type=create
{
"user" : "ZYC",
"post_date" : "2016-04-15T14:12:12",
"message" : "i have id",
"ingfo222": "Happy"
}
# PUT等价命令
put users_info/_create/5
{
"user" : "ZYC",
"post_date" : "2016-04-15T14:12:12",
"message" : "i have id",
"ingfo222": "Happy"
}
# 如果 op_type=index 为更新文档,更新成功则版本号(_version)+1
# ?op_type=index 条件不存在,默认为 index
# 更新的目标文档不存在,则会创建文档
POST users_info/_doc/5?op_type=index
{
"user" : "ZYC",
"post_date" : "2016-04-15T14:12:12",
"message" : "i have id",
"ingfo222": "Happy"
}
# PUT等价命令
put users_info/_doc/5
{
"user" : "11dian",
"post_date" : "2016-04-15T14:12:12",
"message" : "i have id by put"
}
# 更新文档
# 按 _id 更新文档,版本号不变,只更新 doc 内制定字段信息
POST users_info/_update/5
{
"doc":{
"message" : "Update!"
}
}

文档读操作

# 按照 id 读取文档
# 格式:{index_name}/_doc/{_id}
GET users_info/_doc/5
# 文档未找到,则返回信息:"found": false
GET users_info/_doc/10
# 条件查询
GET users_info/_search
{
"query": {
"match_all": {
}
},
"size": 5
}

分词器调用

# 默认分词器
GET /_analyze
{
"analyzer": "standard",
"text":"i like coding"
}
# 中文分词
GET /_analyze
{
"analyzer": "standard",
"text":"我喜欢旅游"
}

 

五、Elasticsearch 索引原理

Elasticsearch 的索引是通过倒排索引来实现的,是一个通过 value 寻找 key 的过程

1、倒排索引由单词单词词典倒排列表组成

单词:即为可以被索引的最小单元

举例如下:

单词词典:记录了单词到倒排列表的关联关系

倒排列表:记录了单词对应文档的组合,由倒排索引项组成

倒排索引项,有以下几项:

  • 文档id
  • 词频(TP),单词出现的频率,用于相关性打分
  • 位置(Position),单词出现的位置
  • 偏移(Offset),单词的起止位置,用于高亮显示

举例如下:

2、文档(document)的每个字段都有自己的倒排索引,可以对字段设置不做索引,这样的话这个字段就无法被搜索

 

六、Elasticsearch 索引文档的过程

Elasticsearch 索引一个文档(document)主要有两个过程组成,示意图如下

1、定位用于存储文档(document)的主分片位置

由于一个索引由多个分片组成,分片分布在不同的节点上,Elasticsearch 会根据文档计算出的 hash码、节点的数量、主分片的数量,来定位具体主分片的位置

2、通过 Lucene 引擎构建倒排索引

Lucenc 会根据文档字段类型进行分词处理,形成单词词典以及对应的倒排索引项,完成倒排索引项之后,就可以供后续查询使用

 

七、Elasticsearch 查询数据过程

Elasticsearch 中的数据查询分为按id查询按条件查询,按 id 查询时 Elasticsearch 会通过路由算法定位到具体的分片来获取数据,按条件查询时 Elasticsearch 会查询每一个分片来汇总查询数据返回

按 id 查询,流程如下:

1、客户端(Client)将请求发送到任意一个节点上,此时该节点将作为协调节点

2、协调节点会使用路由算法更具文档 id 路由到具体的数据分片上,分片有可能是主分片也有可能是副本分片

3、分片将数据返回给协调节点

4、协调节点将数据返回给客户端

按条件查询,流程如下:

1、客户端(Client)将请求发送到任意一个节点上,此时该节点将作为协调节点

2、协调节点会对查询条件进行分词等逻辑处理,然后将请求转发到各个分片

3、各个分片会将匹配的文档 id 返回给协调节点

4、协调节点根据所有数据,截取获得最终结果 id 列表

5、协调节点根据结构 id 向对应分片获取全量数据

6、协调节点将最终数据返回给客户端

 

八、Elasticsearch master 选举机制

一个 Elasticsearch 集群中只能有一个 Master 节点,但是可以有多个有 Master 选举资质的节点(Master-eligible),当主节点发送故障后,集群将发起新的主节点选举

流程大致如下:

1、选举范围为所有拥有 Master 选举资质的节点,每一个候选节点回去获取其他候选节点的信息

2、获取到所有候选节点信息后,根据 nodeId 字典排序进行投票(排序也会包括本身节点),投给第 0 位的候选节点3

3、当候选节点获取到超半数投票后,即选举成功,称为主节点

选举中的脑裂问题:

由于网络,硬件等问题,一个 Elasticsearch 集群可能会分裂成多个集群,造成选出多个主节点,造成数据不一致的问题

设置最小选举节点数为 3 可以很大程度上缓解脑裂问题(无法根本解决此问题,当然 Elasticsearch 可以选择使用 Zookeeper 来进行主节点的选举)

 

在并发情况下,Elasticsearch 如果保证读写一致?

可以通过乐观锁的形式对并发进行控制,更新条件中加上文档版本号字段,也可以使用自定义的版本号字段

 

参考:

https://blog.csdn.net/xhl1123456789/article/details/130445015

https://blog.csdn.net/m0_38060977/article/details/105643334

 https://xie.infoq.cn/article/7f84ceaca3e1537eab40b853d

https://blog.csdn.net/UbuntuTouch/article/details/129396057

posted @   lenbkan  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示

目录导航