阅读《es权威指南》的要点学习&总结

2 篇文章 0 订阅
1 篇文章 0 订阅
本文详细介绍了Elasticsearch(ES)的存储原理,包括倒排索引的工作机制,文档的存储与检索过程,以及分布式环境下的节点协调。通过类比和实例解释了ES如何实现快速搜索和排序,并探讨了分片均衡、更新文档、批量操作等高级话题。
摘要由CSDN通过智能技术生成

前言

都知道es是一个搜索引擎,那么阅读本书我们想要得到的解答的几个问题: * 一个文档es是如何进行存储的?

  • 存储后是如何检索出来的?
  • 文档的排序是如何做到的?
  • 分布式的es节点间是如何组织协调的?

如果已经知道这些,那应该不需要再读本文了

一个文档es是如何进行存储的?

类比

类型字段
mysqldatabasetablecolumn
esindextypefield

说明:

  1. es是面向文档的,将文档以json格式进行存储
  2. index就是对应于传统数据库的database,库中可以存储很多类型的文档,其中每种类型就是一个type

使用

  • 索引创建
    索引就相当于是数据库, 想要对文档进行存储,首先需要创建数据库。创建索引需要指定分片数量和副本数,一个分片就是一个Lucene引擎,分片之间相互独立进行数据的管理,通过es又实现分片之间的数据的统筹管理。副本有2个作用,一个是为了在主分片挂了时能够顶上去,一个是提高读能力。
    创建的原则是,同类的数据放在一个索引中。
  • 类型指定
    类型是不用单独创建的,它是es封装,在lucene中是没此独立结构,只是在文档中有个_type字段来标识。
  • 映射设置
    对于类型,可以手动提前设置映射,就是字段的数据类型,如果不配置,es也提供了动态映射自动判断字段类型创建映射关系。
  • 添加文档
    指定索引和类型后,es提供了单文档索引(插入数据)和批量文档索引(批量插入)。

存储后是如何检索出来的?

一个文档存入es后,想要提高检索速度,都需要创建索引,例如mysql通过创建b+树提高,而es则也有自己的索引,就是倒排索引。

倒排索引

es中存储的元素是文档(doc),doc中有很多字段,字段可能是一个简单的数字,也可能是一段话,如何根据用户输入的信息(query)来匹配上文档中的一句话,简单来说这就是倒排索引需要做的事情。

词项

就是一句话中的特征词。

  • 词项(term)提取
    一段话可能具有一些独立的特征词项,例如我爱吃烧烤,那么“吃”“烧烤”就可以被提取出来,而完成词项提取的模块,称之为”分词器“。分词器是语言相关性的,例如英语的分词原理和汉语就不一样(这个很好理解,汉语是没有空格的)。
  • 停用词过滤
    一句话中很多次是没有意义的,例如汉语中的 “的”,这些词需要进行过滤。
  • 词项归一
    就是将词项进行统一,例如美式英语的color和英式英语的colour是一个意思,es中的文档存储和用于的检索输入可能是不同的,这时候我们需要对词项激进型归一,完成规范化的格式。
  • 词干提取&词型还原
    例如英语中单数和复数的表示是不同的,例如apple和apples,词性不同标识也是不同的,例如do和doing,需要进行词项的统一规范化。

词项和文档的映射

有了词项后,es会简历词项和文档的映射关系:
term1—> doc1,doc2,doc3 … docN
这就是倒排索引的基础结构,有了该映射关系,es会将该映射关系写入磁盘中间文件,es在后台会对中间文件进行文件合并,形成倒排索引文件。

检索

有了词项与文档的映射,对用户的输入进行词项提取、过滤、归一、词干词型规范后,就可以在索引文件中进行对比查找。
这个时候会发现有很多文档是匹配上的,那么这个时候就需要进行词项TF-IDF指标、词频等文档相关度分析和得分计算,返回相关度更大的文档集合。

文档的排序是如何做到的?

上面也提到了,检索的过程中会进行文档的相关度计算,文档的排序也是按照相关度计算得到。有哪些因素会参与计算文档的相关度呢?

相关度

什么是相关度? 相关度越高,文档的_score越高,其排序越靠前,这就是检索排序的策略。
相关度与哪些指标有关系?

  1. 词项频率:词项在字段中出现的频率,词项出现在一个字段中次数多,相关度越高
  2. 反向文档频率:词项在文档中出现的频率,词项在很多文档中出现,其相关度越低
  3. 长度规则: 字段越长,相关度越低

分布式的es节点间是如何组织协调的?

路由

在索引一个文档是,es如何决定将文档交给哪个分片存储的呢?
shard = hash(routing) % number_of_primary_shards
这也是分片数量需要在索引创建时设置的原因,且无法修改。

分片交互

写操作
写操作只能在主分片上进行,es节点接收到client请求会进行以下几步:

  1. hash计算文档所在分片
  2. 分片不在es节点则进行请求转发
  3. 对应的节点分片进行数据新增、并且同步其他副本分片,副本分片响应成功则返回原es节点
  4. es节点响应client

我们发现es的主分片在处理数据后需要将数据同步给副本,这增加了很大的时间开销,因此es支持几种配置:
sync: 副本同步完再响应
async: 不等待副本同步直接响应
consistency: 默认是过半同步则响应,也可以设置成one 和 all

读操作
读操作在主副分片都可以完成。

其他思考

分片均衡算法

在es中每个分片(shard)就是一个Lucene搜索引擎,es集群中分片是如何进行均衡分布的呢?
主要基于以下几种配置:

  • cluster level shard allocation,在集群层面来控制分片分配和再均衡的过程
  • disk-based shard allocation,在分片分配的时候,考虑可用的磁盘空间
  • shard allocation awareness,在不同的机架上进行分片分布
  • shard allocation filter,可以控制有些节点不参与分片分配,方便节点安全下线

欲了解详细的配置可以参考这个

更新一个文档过程

es更新一个文章时,做了以下几个步骤的操作:

  1. 标记老的文档为删除
  2. 生成新的文档,文档_version和新创建的文档不同
  3. 在segment merge阶段将标记的文档删除

segment merge 是什么?
后台任务每秒会创建一个新的段,es在后台会对小的段做合并操作,合并后的段再做合并形成大的段,以提高查询性能,在合并的过程中,会丢弃被标记为删除状态的文档;

bulk请求为啥用换行符而不是json数组

bulk请求文档可能分布在不用的分片上,如果以json数组的形式,在需要解析json后,再分组,发送不同的分片执行,增加了ram的消耗;
es在接受请求时,读取网络缓冲区中的参数,以\n作为分隔符来解析决定将请求分发到不同的分片,没有内存全部读取的消耗;

batch-get思考

客户端连接es做batch-get操作,es会在服务端做检索和汇总,聚合后返回给客户端;看到这个想起来hbase也有batch-get,但是hbase的batch-get操作实际上是客户端连接各region-server做检索,分别得到节后后再客户端聚合,还是有一定的差异性的。

analyzed 和 not_analyzed 区别

对一个字段设置索引方式时,可以设置3个值,默认是analyzed,分别代表:
analyzed:文本会被分析器解析成词项(例如:hot dog会建立’hot’ ‘dog’ 2个词项到文档的映射),建立倒排索引;
not_analyzed:文本不会被分析器解析成此项,而以文本的整体建立倒排索引;
no:不生成倒排索引;

搜索的种类1. 普通的全文搜索

  1. 短语搜索
  2. 前缀搜索(instant search)

参考

倒排索引解读
es权威指南

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值