大数据技术学习——ElasticSearch

举报
slx_share 发表于 2023/03/02 10:44:38 2023/03/02
【摘要】 ElasticSearch(简称ES)是分布式实时全文搜索引擎和实时文件存储数据库。

1       一句话介绍

ElasticSearch(简称ES)是分布式实时全文搜索引擎和实时文件存储数据库

2       ES架构


  • EsMaster:集群中只能有一个主节点,管理集群级别的一些变更, 例如决定分片的分配、新建或删除索引、增加或移除节点等。主节点不参与文档级别的变更或搜索。
  • EsClient:协调节点,只处理路由请求、搜索,及分发索引等操作。自身不存储数据,也不管理集群。
  • EsNode:数据节点,主要是存储索引数据,对文档进行增删改查、聚合等操作。节点上每个EsNode进程对应一个目录,存放该EsNode管理的索引分片。
  • Gateway:集群索引底层存储方式,如本地文件系统,HDFS(性能太差,基本不用)等。

3       ES数据存储结构

3.1       重要概念

  • Index:索引是文档的集合,类似于关系型数据库的table()。分布式文件存储中,索引仅仅是一个指向分片的逻辑命名空间,实际提供搜索服务的是位于节点上的分片。Indexing意思就是存储文档。
  • Document:文档是一次插入的一系列键值对的集合(Json序列),类似于关系型数据库的Row()
  • Shard:分片是一个独立的Lucene实例(Lucene index),实际存储数据,并能提供完整搜索服务能力。
  • Segment:分片由大量的Segment()文件构成,段直接提供搜索功能。
  • Field:即Json字符串中Key,类似于关系型数据库的列。
  • Mapping:定义文档包含多少个字段,字段类型等
  • Term:对text类型的Value进行分词后的最小单元。

3.2       倒排索引

即从所有文档中抽取Term,构建Term与文档ID的映射关系。例如:

两个文档如下:

  • The quick brown fox jumped over the lazy dog
  • Quick brown foxes leap over lazy dogs in summer

则倒排索引如下:

倒排索引非常适合于搜索包含特定关键词(Term)的文档。

3.3       DocValues(正排索引)

即将倒排索引转置(列存储)如下:

DocValues非常适合于聚合操作。

3.4       数据物理存储

ES中插入一个文档,可存储如下几个文件:

  • Lucene&Segment&Field元数据文件:Segment个数,Segment包含文件列表,Field类型、是否存储、是否索引、是否分词等等。
  • 数据存储文件:插入数据的原始Json文档,存储在_source字段下,可通过"_source": {"enabled": false}禁用。
  • 倒排索引文件:可持久化到磁盘,但不可变,如需修改只能重建。
  • DocValues:正排索引数据结构,如字段没有聚合的需求,可以通过设置doc_values: false禁用。

ES数据以分片为粒度,可设置多个复制分片。集群状态显示与分片的关系如下:

4       ES重要字段

  • objectnested类型

object: 默认字段类型,包含下一级字段的字段,直观理解该字段的value是一个{}

nested: 一种特殊的object字段,需要显式指明字段类型为“nested”,能将{}里面多个[]当成一个整体来搜索,而不是像object那样将内部嵌套的{}扁平化。例如:

该条数据中content以及username的实际存储方式如下,失去了contentname的关联。这时如果关联搜索"good""li si",同样能返回搜索结果。

若事先显示指定comment字段类型为nested,这时如果关联搜索"good""li si",则返回搜索结果为空。

注:text支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;keyword不进行分词,直接索引,支持模糊、支持精确匹配,支持聚合、排序操作。

  • 固定名称字段

properties: 显示地为objectnested类型字段添加属性字段。

fields: 为同一个字段赋予别名,并为别名赋予不同的数据类型,以便进行不同的操作

  • 文档的元数据字段(下划线开头)

_index: 文档归属索引

_type: mapping typeES6已取消

_id: 文档ID,可手动或自动指定

 _source: 存储文档原始Json字符串,可以禁用

5       ES读写流程

5.1       索引()流程


  • 客户端将索引请求发送任意节点Node1上主分片P1
  • 节点通过判断数据应该存在Node3上主分片P0
  • P0若执行成功会将请求同步给其他节点上的复制分片R0R0执行成功后会将结果返回给P0P0将返回success给客户端
  • 文档会根据路由算法分配到特定的分片上:

shard=hashrouting%number_of_primary_shards

routing默认是文档id。

  • 新写入数据时,数据先写入内存缓存区(in-memory buffer)以及事务日志(Translog)中,此时并不能检索到,需要从内存缓存区refresh到Segment(可以通过设置refresh_interval决定refresh时间间隔)才能被检索到。每次refresh会形成新的Segment,ES内部会开启一个新的线程进行段合并,从而提升IO性能。

5.2       搜索流程


  • 客户端将请求发给任意一个节点Node3
  • Node3将请求发送给index下的所有分片(可以从主分片或复制分片下任意选择一个)每个分片将查询结果排序存在本地
  • 所有分片将查询到的结果统一发送给Node3(此时承担协调节点的角色)进行合并,再转发给客户端

6       翻页方案

  • from+size方案:适合实时查询场景

类似于SQLlimitfrom定义跳出的文档条数(hits),size定义每页展示的文档条数。ES默认的分页深度(max_result_window)是10000,也就是说from+size超过10000就会报错。深度分页非常耗时、耗内存,因为需要从每个主分片获取from+size条文档条数再在协调节点合并。

  • search after方案:适合海量查询场景

利用实时游标解决实时滚动的问题,简单来说前一次查询的结果会返回一个唯一的字符串,下次查询带上这个字符串,进行下一页的查询。基于排序唯一标识,每个分片仅返回size条文档,效率高。

  • scroll方案:适合一次性返回海量数据的非实时场景

首次查询时生成一个 scrollId,并将所有符合搜索条件的搜索结果的doc_id缓存起来。后续查询时,携带上一次查询返回的 scrollId

各个方案的优缺点对比如下:(摘自:https://juejin.cn/post/7103848212154286087

7       参考

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。