写点什么

啥是 ElasticSearch 全流程,看这篇我也懂了

  • 2021 年 11 月 22 日
  • 本文字数:2539 字

    阅读完需:约 8 分钟

ES 是什么搜索引擎 search engine 近实时 (Near) Real Time SearchRESTful API 分布式、高可用面向文档存储,json 格式基于 Apache Lucene 核心概念 Cluster 集群 Node 构成集群的单机节点 Index 索引 Shard 分片 Replica 副本 Segment 分段 Document 文档 Field 字段 Inverted Index 倒排索引 Text / Keyword 类型使用全流程 schema(mapping)es 不需要前置的 schema 定义,在索引 doc 时确定 schema


因为 es 数据的交互形式是 json,所以 doc 可以开箱即用,在写入 doc 时如果没有预先定义的 mapping,doc 的每一个 field 会根据传过来的 json 数据确定类型,默认规则(dynamic field mapping)如下:


json 类型


es 类型


null


不会增加 field


boolean


boolean


string


date(通过 Date detection)double/long(通过 Numeric detection)text(带 keyword 的 sub field)


number


float/long


object


Object


array


array(array 的 item 类型取决于第一个非 null 元素的类型)


同时 es 还支持定义模板 dynamic_template,来对默认的规则进行扩充、修改,例如下例就是修改了默认的 string 映射:


{


"mappings": {


"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "text"
}
}
}
]
复制代码


}不过如果没有动态字段的需求,个人不建议使用 es 的 dynamic mapping,使用不当的话会污染 mapping,所以可以指定 dynamic 为 false 来关闭动态 mapping。


当然可以使用 put mapping api 来预定义 index 的 mapping 结构,包括字段类型、使用的分析器(text 类型)、是否索引等等。


es 官方也非常推荐将相同的字段以不同的方式索引到 es 中,例如一个字符串类型的值可以使用索引成 text 类型来进行全文检索,也可以索引成 keyword 类型进行排序、聚合。


建议使用别名(alias),es 对 mapping 的拓展是开放的,但对 mapping 的修改是禁止的。例如,可以为 mapping 增加一个字段,但是不能删除/修改字段。所以使用 alias 指向真正的 index,这样,在有 field 需要修改的场景可以使用 reindex api 重建索引、再使用 alias api 更改指向,可以实现无缝的切换。


数据写入分布式写入流程 ElasticSearch 全流程,看这篇我也懂了可以看到,es 写入的总延时等于写入主节点的时间+max(写入从节点的时间)。


Shard 写入流程 ElasticSearch 全流程,看这篇我也懂了比较重要的三个概念


refreshflushfsync todo:是否会丢数据写入优化使用 bulk api 批量操作调整 refresh_interval 的间隔,es 在每一次 refresh 时都会创建 lucene 的 segment,并尝试进行 segment 的合并,开销较大,若对搜索的实时性要求不高,可以适当的调大 refresh_interval 的大小不需要索引的字段指定 index 属性为 not_analyzedSSD(经典性能不行,硬件来凑)读取 Search 使用 search api 可以很方便的实现数据的检索。es 提供了很多 search api,例如 match_query,term_query 等等,可以很方便的组装 query DSL(Domain Specific Language),且开发人员不需要考虑 DSL 中 query 的顺序,dsl 中 query 的顺序不会影响最后的执行效率,真正的执行顺序会在 CBO(Cost Based Optimizer)后进行重排。


term index 使用 FST(Finite State Machines) -> 定位倒排链 ElasticSearch 全流程,看这篇我也懂了 SkipList -> 合并倒排链 AggregationMetrics 将 query 命中的数据集进行 count,max 等操作,是一个单一的数值 Bucket 将 query 命中的数据集再按条件分为更小的数据集合,再在这些小集合上执行 Metrics,可以类比于 sql 中的 group bySort 不要使用 text 字段作为排序字段,text 字段一般用分析器进行分词,对 text 字段做排序往往得不到预期的结果


ES 返回的 doc 默认会按照_score(文档相关性)降序排列,即算分后的分数值,如果指定了其他的 Sort 字段,就会按照指定的字段排序。同样支持 script,来构造比较复杂的排序规则。


_score,评分的计算依赖于不同的 query 方式,例如对于 fuzzy 查询会计算与检索词拼写的相关程度,term 查询会计算内容和关键词间的百分比等等。但是一般意义上我们说的全文搜索是指计算内容与关键词的相关程度,ElasticSearch 的相似度算法使用 TF/IDF,即词频/逆文档频率,包括以下内容:


词频:检索词在该字段出现的频率。出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。逆文档频率:每个检索词在索引中出现的频率。频率越高,相关性越低。 检索词出现在多数文档中会比出现在少数文档中的权重更低, 即检验一个检索词在文档中的普遍重要性。字段长度准则 : 字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段相关性更高。Page1.基于 offset 的分页


from + size,from 指定偏移量,size 指定要取的数据条数执行原理:ElasticSearch 全流程,看这篇我也懂了 client 发起请求,收到请求的 shard 成为协调节点,负责后续请求数据的合并执行 query,取到 from+size 大小的结果集,协调节点本地构建构建大小为 from+size 的 priority queue ,协调节点将请求分发到其他 shard 其他 shard 同样执行 query,取到 from+size 大小的结果集,将集合返给协调节点协调节点合并结果集,最后得到 from+size 大小的 priority queue,将后 size 个数据返给 client 特点: 支持随机分页访问 不适合用在 feed 无限下拉场景,在分页的边界可能存在数据重复的可能性 随着 from 的增大,开销也逐渐增大,不适合深度分页的场景 2.基于 cursor 的分页 scroll


针对这次请求将符合条件的所有结果汇集到协调节点缓存起来,后续直接从协调节点的缓存中取出由于缓存的存在,文档后续的变更并不会同步到缓存中,并不适合实时请求同样因为缓存的数据量为 query 命中的所有 doc,所以 scroll 的堆内存开销是非常大的适用于索引的重建/数据的迁移等非实时、低频的场景 3.search_after


使用上一页的检索结果来帮助检索下一页,排序字段里要包括 doc 的唯一标识,以保证 search_after 的一致性每一个 shard 请求的数据集大小为 size 不支持随机分页访问实时处理,若 doc 有变更且影响到了排序因子,有可能出现重复数据读取优化没有范围查找需求的 number 类型字段,类型定义为 keyword 慎用 wildcard query,尽量使用分词后的结果使用 match query,有使用 wildcard query 的需求,注意字符转义搜索词的长度要做限制 feed 流场景使用 search_after 不需要得分的字段用 filter context 替换 query content,query 和 filter 区别

用户头像

还未添加个人签名 2021.10.14 加入

还未添加个人简介

评论

发布
暂无评论
啥是ElasticSearch全流程,看这篇我也懂了