ElasticSearch索引架构与存储

关于ES官网的介绍:

Elasticsearch provides near real-time search and analytics for all types of data. Whether you have structured or unstructured text, numerical data, or geospatial data, Elasticsearch can efficiently store and index it in a way that supports fast searches. You can go far beyond simple data retrieval and aggregate information to discover trends and patterns in your data. And as your data and query volume grows, the distributed nature of Elasticsearch enables your deployment to grow seamlessly right along with it.

可以看到ES具有一下特点:

  1. 近实时
  2. 用于检索和分析:OLAP型数据库
  3. 支持非结构化数据存储:NoSQL数据库
  4. 分布式:支持无缝横向扩展

ES主要的使用场景如下:

  1. 日志、指标等数据的存储和分析;
  2. 复杂查询:如电商系统的商品检索、github站内检索;
  3. 作为冗余数据提供多样化查询方式:如SQL分库分表无法支持非分片键字段的查询,使用ES冗余数据支持多样化查询;
  4. 跨库关联查询:将跨库数据关联冗余至ES,关联查询直接查ES,同时解决了跨库分页的问题。

关于ElasticSearch的基本概念和原理可以参看:

  • 分布式文档存储
  • ElasticSearch Docs
  • 从原理到应用,Elasticsearch详解
  • Elasticsearch 教程

官方讨论社区:discuss.elastic.co

官方博客:elastic.co/cn/blog

本文介绍了ES索引的存储架构和数据结构。

ES Index Storage Architecture

ES底层搜索使用的仍然是Lucene引擎,但Lucene只支持单节点搜索,不具备扩展性,ES在其基础上提供了分布式环境下的支持。

在这里插入图片描述

关于Lucene Index:

index in Lucene means “a collection of segments plus a commit point”

关于Segment:

A shard in Elasticsearch is a Lucene index, and a Lucene index is broken down into segments.

在我们变更document时,实际上document会生成一系列数据写入Segment中,Segment中存放了Doc,Doc包含多个Field, Field包含多个Term。

写入的过程是先写入文件系统缓存(内存中)再刷到磁盘,放到文件系统缓存中即可被检索到,这个文件系统缓存刷新(refresh)间隔默认为1秒 (注意:只针对30秒内有查询的索引生效),所以说ES准实时。同时,会有translog保证文件写入磁盘时的数据一致性,如果刷盘期间发生故障,可以通过translog进行数据恢复,等到真正把 segment 刷到磁盘(flush),且 commit 文件进行更新的时候, translog 文件才清空。

索引数据的一致性通过 translog 保证。那么 translog 文件刷盘本身如何保证一致性 ? 类比MySQL等关系数据库的处理,这里肯定有同步/异步刷盘策略,默认情况下,Elasticsearch 每 5 秒,或每次每次 index、bulk、delete、update结束前,会强制刷新 translog 日志到磁盘上。

索引查询时会依次检索各个Segment,同时后台也会有线程执行Segment合并动作,也可以手动执行强制合并,提升Segment检索效率。一般索引会按时间周期性新建,老的索引不再写入,这些不再写入的索引可以进行强制段合并操作,提升查询性能(一个Shard中多个Segment是串行查询的)。

  • 分片内部原理
  • Understanding Segments in Elasticsearch
  • segment、buffer和translog对实时性的影响
  • Near real-time search
  • ElasticSearch中使用Index Template、Index Alias和Rollover 维护索引
  • segment merge对写入性能的影响
  • 段合并优化及注意事项

ES Index

首先明确两个概念:正排索引倒排索引。正派索引是根据文档(文档id)找到文档的value, 倒排索引是拿着文档的value找到对应的文档(文档id)。

在这里插入图片描述

ES中根据不同的字段类型和查询方式, 底层会使用不同的数据结构进行倒排索引存储,这些索引存在于内存中。

字段类型:

类型类别类型
Common typesbinary, boolean, Keywords(keyword constant_keyword wildcard), Numbers(long double), Dates(date date_nanos), alias
Objects and relational typesobject, flattened, nested, join
Structured data typesRange(long_range double_range date_range ip_range), ip, version, murmur3
Aggregate data typesaggregate_metric_double, histogram
Text search typestext, match_only_text, annotated_text, completion, search_as_you_type, semantic_text, token_count
Document ranking typesdense_vector, sparse_vector, rank_feature, rank_features
Spatial data typesgeo_point, geo_shape, point shape
Other typesArrays, Multi-fields

查询Context可分为:

  • Query Context : How well does this document match this query clause? 查询结果根据 relevance score 排序;
  • Filter Context : Does this document match this query clause? 不参与打分,且结果会被缓存。

查询方式:

查询类别类型
Compound queriesbool(must, filter, should, must_not), boosting, constant_score, dis_max, function_max
Full text queriesintervals, match, match_bool_prefix, match_phrase, match_phrase_prefix, multi_match, combined_fields, query_string, simple_query_string
Geo queriesgeo_bounding_box, geo_distance, geo_grid, geo_polygon, geo_shape
Shape queriesshape
Joining queriesnested, has_child has_parent
Match allmatch_all match_none
Span queriesspan_containing, span_field_masking, span_first, span_multi, span_near, span_not, span_or, span_term, span_within
Specialized queriesdistance_feature, more_like_this, percolate, knn, rank_feature, script, script_score, wrapper, pinned, rule
Term-level queriesexists, fuzzy, ids, prefix, range, regexp, term, terms, terms_set, wildcard
Othertext_expansion, minimum_should_match, regexp, query_string

Segment存储

Segment中存储了以下内容(既包含正向信息,也有反向信息):

  • Segment info: This contains metadata about a segment, such as the number of documents, what files it uses,
  • Field names: This contains the set of field names used in the index.
  • Stored Field values: This contains, for each document, a list of attribute-value pairs, where the attributes are field names. These are used to store auxiliary information about the document, such as its title, url, or an identifier to access a database. The set of stored fields are what is returned for each hit when searching. This is keyed by document number.
  • Term dictionary: A dictionary containing all the terms used in all the indexed fields of all the documents. The dictionary also contains the number of documents which contain the term, and pointers to the term’s frequency and proximity data.
  • Term Frequency data: For each term in the dictionary, the numbers of all the documents that contain that term, and the frequency of the term in that document, unless frequencies are omitted (IndexOptions.DOCS_ONLY)
  • Term Proximity data: For each term in the dictionary, the positions that the term occurs in each document. Note that this will not exist if all fields in all documents omit position data.
  • Normalization factors: For each field in each document, a value is stored that is multiplied into the score for hits on that field.
  • Term Vectors: For each field in each document, the term vector (sometimes called document vector) may be stored. A term vector consists of term text and term frequency. To add Term Vectors to your index see the Field constructors
  • Per-document values: Like stored values, these are also keyed by document number, but are generally intended to be loaded into main memory for fast access. Whereas stored values are generally intended for summary results from searches, per-document values are useful for things like scoring factors.
  • Live documents: An optional file indicating which documents are live.

对应存储的文件如下:

在这里插入图片描述

可以参看:

  • A Dive into the Elasticsearch Storage
  • Apache Lucene - Index File Formats

Inverted Index

输入文本建立倒排索引的过程如下:

  1. 文本预处理:去除stop words,词干提取,规范化(stemming, lemmatization);
  2. tokenized: 将文本划分为多个terms;
  3. 建立term到doc的倒排索引,如下图所示。

在这里插入图片描述

Term Index + Term Dictionary + Posting List

输入查询多个Terms,会对每个Term依次从 Term Index -> Term Dictionary -> Posting List 找到对应的DocId

在这里插入图片描述

Posting List

PostingList 包含文档 id、词频、位置等多个信息,这些数据之间本身是相对独立的,因此 Lucene 将 Postings List 被拆成三个文件存储:

  • .doc 后缀文件:记录 docId 信息和 Term 的词频
  • .pay 后缀文件:记录 Payload 信息和偏移量信息
  • .pos 后缀文件:记录位置信息

基本所有的查询都会用 .doc 文件获取文档 id,且一般的查询仅需要用到 .doc 文件就足够了,只有对于近似查询等位置相关的查询则需要用位置相关数据。

.doc 文件中,每个 Term 都包含一对 TermFreqs 和 SkipData 结构,TermFreqs中 docId 和 该Term的词频,SkipData为跳表辅助信息,用于内部跳转:

在这里插入图片描述

TermFreqs 存储docId及其在该doc内的词频,分别使用int值表示,但Lucene使用 PackedBlock 和 VIntBlocks 结构 压缩存储:

  • PackedBlock : PackedInts 结构将一个 int[] 压缩打包成一个紧凑的 Block。它的压缩方式是取数组中最大值所占用的 bit 长度作为一个预算的长度,然后将数组每个元素按这个长度进行截取,以达到压缩的目的。
  • VIntBlock : 采用 VInt 来压缩 int 值,对于绝大多数语言,int 型都占 4 个字节,不论这个数据是 1、100、1000、还是 1000,000。VInt 采用可变长的字节来表示一个整数。数值较大的数,使用较多的字节来表示,数值较少的数,使用较少的字节来表示。每个字节仅使用第 1 至第 7 位(共 7 bits)存储数据,第 8 位作为标识,表示是否需要继续读取下一个字节。

Lucene 会每处理某个 Term 的 128 个doc,其中的DocId 数组和 TermFreq 数组分别处理为 PackedDocDeltaBlock 和 PackedFreqBlock,两者构成一个PackedBlock,不足 128 的文档则采用 VIntBlock 的方式来存储。

在这里插入图片描述

Term Dictionary

Posting List的数据如何定位呢?这就要靠Term Dictionary , Term Dictionary中存储了Term和Term在Posting List中的位置信息:

  • SkipOffset: term 在 .doc 文件中跳表信息的起始位置;
  • DocStartFP: term 在 .doc 文件中的 docId 与词频信息的起始位置;
  • PosStartFP: term 在 .pos 文件中的起始位置;
  • PayStartFP: term 在 .pay 文件中的起始位置。

Term Dictionary 存放在 .tim文件中。

内部采用 NodeBlock 对 Term 进行压缩前缀存储,处理过程会将相同前缀的的 Term 压缩为一个 NodeBlock,NodeBlock 会存储公共前缀,然后将每个 Term 的suffix 以及对应 Term 的 Posting 关联信息放入Entry。

在这里插入图片描述

Node Block 嵌套了 Node Block,因为Term也是嵌套的。

Term Index

当Term越来越多,从Term Dictionary中查找Term定位docId很耗时,所以进一步空间换时间,建立“索引的索引”:Term Index。

Term Index 存放在 .tip 文件中,采用有限状态转换器(Finite State Transducer, FST)数据结构组织。

FST 具有以下特点:

  • 共享前缀,节省空间,适合加载到内存
  • 时间复杂度O(len(inputString))
  • 构建后不可变更

在这里插入图片描述

FST 只可以直接找到对应前缀在Term Dictionary中的NodeBlock在 .tim 文件上具体的File Pointer, 然后还需要在 NodeBlock 中遍历 Entry 匹配后缀进行查找

  • Lucene 倒排索引原理
  • 美团外卖搜索基于Elasticsearch的优化实践
  • Term Dictionary和Index文件 (FST详细解析)
  • Lucene 原理与代码分析完整版
BKD Tree

为了优化数值类型的Range查询操作,ES采用的BKD Tree存储数值类型,其结构如下图:

但这里有一个误区,不是值是数字就应该在ES中被设置为数值类型, 例如订单号这种只有等值查询而没有数值范围查询,应设置为Keyword类型,可以参考:ES数值类型慢查询优化。

  • Introduction to K-D Trees
  • Lucene BKD树-动态磁盘优化BSP树
  • Bkd-Tree: A Dynamic Scalable kd-Tree

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/759285.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍MySQL的索引(下)

索引的使用 同一条数据在未创建索引的情况下耗时: nick字段是未创建索引的 select * from t_user WHERE nick 邹丽;SHOW PROFILES; 耗时为: user_account字段创建了唯一索引 select * from t_user WHERE user_account 13781945844;SHOW PROFILES;…

基于Vue3 + Typescript 封装 Element-Plus 组件

1. 课程简介 项目地址 git clone https://gitee.com/childe-jia/my-message.git 背景: 该课程是基于Vue3 Typescript Vite构建, 教会大家封装Element-Plus组件 具备能力: 最新的 Vue3 及相关技术组件的设计思想大厂的开发模式/代码规范 技术: Vue3 首次渲染 / diff 算法 …

5-linux文件路径与文件目录系统

目录 ①文件路径 目录跳转 绝对路径与相对路径 ②文件目录系统 目录系统组成 目录命名规则 命令补充 ls命令补充 file filename查看文件类型 less查看文本文件 ①文件路径 目录跳转 pwd:查看当前工作目录。 cd:改变目录。 ls:列出目录内容。 [root########## ~]# …

取证工作:怎样解锁 LUKS2 加密磁盘?

对于 LUKS2 密码进行恢复,Elcomsoft Distributed Password Recovery (简称 EDPR) 软件可以构建高性能集群,以更快地破解密码。EDPR 软件提供零开销的可扩展性,并支持 GPU 加速,以加快恢复速度。EDPR 可帮助…

下属无执行力,领导无能为力?用好这3大法则,打造一流行动力

下属无执行力,领导无能为力?用好这3大法则,打造一流行动力 第一个:漏斗法则 在沟通这个领域,有一个漏斗法则,意思就是指:如果你脑袋里面想表达的是100%,那你说出口的会只有80%&…

开发板以电脑为跳板连接互联网

标题 开发板以电脑为跳板连接互联网网络共享方式桥接方式 开发板以电脑为跳板连接互联网 分享下用网线直连电脑的开发板如何以电脑为跳板连接互联网的两个方法。 网络共享方式桥接方式 补充下,我的电脑连接的是无线网络,开发板和电脑是用网线进行连接的…

AI奏响未来乐章:音乐界的革命性变革

AI在创造还是毁掉音乐 引言 随着科技的飞速发展,人工智能(AI)正在逐渐渗透到我们生活的每一个角落,音乐领域也不例外。AI技术的引入,不仅为音乐创作、教育、体验带来了革命性的变革,更为整个音乐产业注入了…

昇思25天学习打卡营第7天|模型训练

模型训练 模型训练一般分为四个步骤: 构建数据集。定义神经网络模型。定义超参、损失函数及优化器。输入数据集进行训练与评估。 前面几天依次学习了前面几个步骤的操作,今天继续学习模型训练。 数据集和神经网络模型这个前面已经有详细的介绍。准确…

生成式AI如何赋能教育?商汤发布《2024生成式AI赋能教育未来》白皮书

生成式AI正在各个行业中展现出巨大的应用前景。在关系国计民生的教育行业,生成式AI能够催生哪些创新模式? 6月28日,商汤科技受邀参加2024中国AIGC应用与发展峰会,并在会上发布《2024生成式AI赋能教育未来》白皮书,提出…

Qt:5.QWidget属性介绍(isEnabled和geometry)

目录 一、 QWidget属性的介绍: 二、Enabled属性: 2.1Enabled属性的介绍: 2.2获取控件当前可用状态的api——isEnabled(): 2.3设置控件当前的可用状态的api—— setEnabled() : 2.4 实例:通过一个按钮&…

【人工智能学习之图像操作(六)】

【人工智能学习之图像操作(六)】 Hough变换直线检测圆检测 图像分割 Hough变换 在图像处理中,霍夫变换用来检测任意能够用数学公式表达的形状,即使这个形状被破坏或者有点扭曲 直线检测 import cv2 import numpy as np image …

Python 基础:用 json 模块存储和读取数据

目录 一、用 json 存储数据二、用 json 读取数据 遇到看不明白的地方,欢迎在评论中留言呐,一起讨论,一起进步! 本文参考:《Python编程:从入门到实践(第2版)》 用户关闭程序时&#…

Redux实现Token持久化

业务背景: Token数据具有一定的时效时间,通常在几个小时,有效时间内无需重新获取,而基于Redux的存储方式又是基于内存的,刷新就会丢失,为了保持持久化,我们需要单独做处理 解决方案: 使用redu…

HTML图片链接缓存问题解决

关于解决HTML使用图片链接出现的缓存问题处理 1、项目上明明替换了图片却没发现更新,得去浏览器设置清除浏览器缓存或者其它一些操作才能解决,这也太麻烦了!加载过一次不会再加载第二次,其实这时候就存在浏览器图片缓存情况&…

1-5题查询 - 高频 SQL 50 题基础版

目录 1. 相关知识点2. 例题2.1.可回收且低脂的产品2.2.寻找用户推荐人2.3.大的国家2.4. 文章浏览 I2.5. 无效的推文 1. 相关知识点 sql判断,不包含null,判断不出来distinct是通过查询的结果来去除重复记录ASC升序计算字符长度 CHAR_LENGTH() 或 LENGTH(…

cpu,缓存,辅存,主存之间的关系及特点

关系图 示意图: ------------------- | CPU | | ------------- | | | 寄存器 | | | ------------- | | | L1缓存 | | | ------------- | | | L2缓存 | | | ------------- | | | L3缓存 | | | ------------- | ----…

2095.删除链表的中间节点

给你一个链表的头节点 head 。删除链表的中间节点 ,并返回修改后的链表的头节点 head。 长度为 n 链表的中间节点是从头数起第 ⌊n / 2⌋ 个节点(下标从 0 开始),其中 ⌊x⌋ 表示小于或等于 x 的最大整数。 对于 n 1、2、3、4 和…

深入理解 Spring MVC:原理与架构解析

文章目录 前言一、MVC二、Spring MVC三、Spring MVC 工作流程四、小结推荐阅读 前言 Spring MVC 是一种基于 Java 的 Web 应用开发框架,它通过模型-视图-控制器(Model-View-Controller, MVC)的设计模式来组织和管理 Web 应用程序。本文将深入…

树莓派3B读写EEPROM芯片AT24C256

AT24C256是一个Atmel公司的EEPROM存储芯片,容量是256K个bit(也就是32K字节),I2C接口,而树莓派正好有I2C接口,如下图蓝框中的4个IO口, 把AT24C256和这4个口接在一起,这样硬件就准备好…

Nginx的11个执行阶段

Nginx的11个执行阶段