ElasticSearch索引架构与存储

news2025/4/13 1:48:49

关于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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

django学习入门系列之第三点《案例 商品推荐部分》

文章目录 划分区域搭建骨架完整代码小结往期回顾 划分区域 搭建骨架 /*商品图片&#xff0c;父级设置*/ .slider .sd-img{display: block;width: 1226px;height: 460px; }<!-- 商品推荐部分 --> <!--搭建出一个骨架--> <div class"slider"><di…

openwrt igmp 适配

每弄完一次&#xff0c;过不多久就忘了&#xff0c;这次决心记下来。 openwrt 的igmpproxy 包是干嘛的&#xff1f;原来&#xff0c;组播包并不能穿透路由&#xff0c;也就是我们在wan端播放的组播视频流&#xff0c;lan端是没法收到的&#xff0c;igmpproxy就是用来打通wan端…

【Linux】进程信号_3

文章目录 八、进程信号2. 信号的保存3. 信号的处理 未完待续 八、进程信号 2. 信号的保存 实际执行信号的处理动作称为信号递达(Delivery) 信号从产生到递达之间的状态,称为信号未决(Pending)。 进程可以选择阻塞 (Block )某个信号。 被阻塞的信号产生时将保持在未决状态,直到…

网络问题排障专题-AF网络问题排障

目录 一、数据交换基本原理 1、ARP协议工作原理 数据包如图&#xff1a; 2、二层交换工作原理 简述核心概念&#xff1a; 二层交换原理-VLAN标签 3、三层交换工作原理 二、AF各种部署模式数据转发流程 1、路由模式数据转发流程 三、分层/分组逐一案例讲解 1、问题现…

自然语言处理——英文文本预处理

高质量数据的重要性 数据的质量直接影响模型的性能和准确性。高质量的数据可以显著提升模型的学习效果&#xff0c;帮助模型更准确地识别模式、进行预测和决策。具体原因包括以下几点&#xff1a; 噪音减少&#xff1a;高质量的数据经过清理&#xff0c;减少了无关或错误信息…

redis哨兵模式(Redis Sentinel)

哨兵模式的背景 当主服务器宕机后&#xff0c;需要手动把一台从服务器切换为主服务器&#xff0c;这就需要人工干预&#xff0c;费事费力&#xff0c;还会造成一段时间内服务不可用。这不是一种推荐的方式。 为了解决单点故障和提高系统的可用性&#xff0c;需要一种自动化的监…

【D3.js in Action 3 精译】1.2.2 可缩放矢量图形(一)

译注 由于 1.2.2 小节介绍 SVG 的篇幅过多&#xff0c;为了方便查阅&#xff0c;后续将分多个小节依次进行翻译。为了确保整个 1.2.2 小节的完整性&#xff0c;特意将上一篇包含的 SVG 小节的内容整理出来重新编排。敬请留意。 1.2.2 SVG - 可缩放矢量图形 可伸缩矢量图形&…

Django-开发一个列表页面

需求 基于ListView,创建一个列表视图,用于展示"BookInfo"表的信息要求提供分页提供对书名,作者,描述的查询功能 示例展示: 1. 数据模型 models.py class BookInfo(models.Model):titlemodels.CharField(verbose_name"书名",max_length100)authormode…

【STM32-存储器映射】

STM32-存储器映射 ■ STM32F1-4G地址空间分成8个块■ STM32F1-Block0■ STM32F1-Block1■ STM32F1-Block2■ STM32F1- ■ STM32F1-4G地址空间分成8个块 ■ STM32F1-Block0 有出厂 BootLoader 就可以使用串口下载程序。如Keil5图中IROM地址是0x8000000 开始 就是flash地址 ■ S…

安装vue开发者工具

浏览器控制台提示&#xff1a; 打开网址 GitHub - vuejs/devtools: ⚙️ Browser devtools extension for debugging Vue.js applications. 点击添加 上图地址&#xff1a;Installation | Vue Devtools 安装好了

线上民族传统服饰商城

摘 要 随着互联网的不断发展和普及&#xff0c;电子商务成为了人们生活中不可或缺的一部分。传统的线下购物方式逐渐被线上购物所取代&#xff0c;人们越来越习惯在互联网上购物。而民族传统服饰作为我国丰富多样的民族文化的重要组成部分&#xff0c;具有独特的艺术价值和商业…

不是KVM不支持精简置备的磁盘,而是VMM

正文共&#xff1a;999 字 11 图&#xff0c;预估阅读时间&#xff1a;1 分钟 书接上文&#xff08;不会吧&#xff01;KVM竟然不支持磁盘的精简置备&#xff01;&#xff1f;&#xff09;&#xff0c;我们已经掌握了通过“虚拟系统管理器VMM”创建虚拟机的基本方法&#xff0c…

vscode设置主题的颜色

点击主界面左下角的 展开的菜单中点击“themes” 点击“color themes” 选择颜色

windows USB 设备驱动开发-总章

通用串行总线 (USB) 提供可扩展的即插即用串行接口&#xff0c;确保外围设备的标准、低成本的连接。 USB 设备包括键盘、鼠标、游戏杆、打印机、扫描仪、存储设备、调制解调器、视频会议摄像头等。USB-IF 是一个特别兴趣组 (SIG)&#xff0c;负责维护官方 USB 规范、测试规范和…

浅谈Tomcat

文章目录 一、什么是Tomcat&#xff1f;二、Tomcat的下载安装三、使用tomcat访问资源 一、什么是Tomcat&#xff1f; Tomcat 就是一个 HTTP 服务器。 前面我们聊了HTTP服务器&#xff0c;像我们在网页输入URL&#xff0c;其实就是在给人家的HTTP服务器发送请求&#xff0c;既…

如何使用sr2t将你的安全扫描报告转换为表格格式

关于sr2t sr2t是一款针对安全扫描报告的格式转换工具&#xff0c;全称为“Scanning reports to tabular”&#xff0c;该工具可以获取扫描工具的输出文件&#xff0c;并将文件数据转换为表格格式&#xff0c;例如CSV、XLSX或文本表格等&#xff0c;能够为广大研究人员提供一个…

Renesas MCU使用SCI_I2C驱动HS3003

目录 概述 1 软硬件介绍 1.1 软件版本信息 1.2 认识HS3003 1.2.1 HS3003特性 1.2.2 HS3003寄存器 1.2.2.1 温湿度数据寄存器 1.2.2.2 参数寄存器 1.2.2.3 一个参数配置Demo 1.2.3 温湿度值转换 1.2.4 HS3003应用电路 1.2.4.1 PIN引脚定义 1.2.4.2 sensor 应用电路 …

从零入门激光SLAM(十三)——LeGo-LOAM源码超详细解析3

大家好呀&#xff0c;我是一个SLAM方向的在读博士&#xff0c;深知SLAM学习过程一路走来的坎坷&#xff0c;也十分感谢各位大佬的优质文章和源码。随着知识的越来越多&#xff0c;越来越细&#xff0c;我准备整理一个自己的激光SLAM学习笔记专栏&#xff0c;从0带大家快速上手激…

grpc学习golang版( 四、多服务示例)

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 文章目录 一、前言二、定义proto文件三、编写server服务端四、编写Client客户端五、测试六、示例代码 一、前言 多服务&#xff0c;即一个rpc提供多个服务给外界调用…

js+php 上传文件到服务器

https://andi.cn/page/621473.html