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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python--序列化模块json与pickle

什么叫序列化? 将原本的字典、列表等内容转换成一个字符串的过程就 叫做序列化。 多用的两个序列化模块:json与pickle json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 …

springcloud-sentinel 限流组件中文文档

快速开始 欢迎来到 Sentinel 的世界!这篇新手指南将指引您快速入门 Sentinel。 Sentinel 的使用可以分为两个部分: 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境&#xff0c…

星坤Type-A连接器:创新快充技术,引领电子连接!

快速发展的电子时代,消费者对电子设备的性能和便利性有着更高的要求。特别是在充电和数据传输方面,快充技术和高速传输已成为市场的新宠。中国星坤公司推出的Type-A连接器系列,以其卓越的性能和创新的设计,满足了市场对高效、稳定…

Java数据脱敏

数据脱敏 敏感数据在存储过程中为是否为明文, 分为两种 落地脱敏: 存储的都是明文, 返回之前做脱敏处理不落地脱敏: 存储前就脱敏, 使用时解密, 即用户数据进入系统, 脱敏存储到数据库中, 查询时反向解密 落地脱敏 这里指的是数据库中存储的是明文数据, 返回给前端的时候脱…

电阻屏和电容屏

目录 一、电阻屏 1.欧姆定律 2.电阻屏原理 (1)测量 X 坐标 (2)测量 Y 坐标 3.电阻屏数据 二、电阻屏 1.原理 2.电容屏数据 (1)Type A (2)Type B 3.电容屏的实验数据 一、…

Jira实践案例分享:小米集团如何通过API请求优化、数据治理与AI智能客服等,实现Jira系统的高效运维

日前,Atlassian中国合作伙伴企业日活动在上海成功举办。活动以“AI协同 创未来——如何利用人工智能提升团队协作,加速产品交付”为主题,深入探讨了AI技术在团队协作与产品交付中的创新应用与实践,吸引了众多业内专家、企业客户及…

文心智能体平台介绍和应用:制作你的智能体(运维小帮手)

这是我自己制作的智能体 大家可以了解一下! 运维小帮手!https://mbd.baidu.com/ma/s/tE19dqvr 文心智能体平台官网首页 点击跳转!https://agents.baidu.com/ 什么是智能体平台? 文心智能体平台(Wenxin Intelligen…

关于Vite+Vue+Ts WebStorm路径别名的问题

一、准备一个项目 二、在 vite.config.js 中添加 resolve: {alias: {: /src}} 三、tsconfig.app.json中添加代码 //添加代码"baseUrl": ".","paths": {"/*": ["src/*"]}把src的一个文件修改路径为开头 四、安装插件 npm i …

第 11 课:组件介绍与自定义开发

本讲主要介绍了隐语的组件标准、已有的组件能力以及进一步的自定义开发流程。经过本讲的学习,可以为将隐语集成到任意调度系统,基于Kusica/SecretPad进行二次开发,以及参与隐语开放标准共建建立基础。 一、隐语开放标准 隐语提出的适用于隐私…

仓库管理系统

摘 要 随着电子商务的快速发展和物流行业的蓬勃发展,仓库管理成为了企业重要的一环。仓库管理涉及到商品的入库、出库、库存管理等一系列操作,对于企业的运营效率和成本控制具有重要影响。传统的仓库管理方式往往依赖于人工操作和纸质记录,存…

【Windows 常用工具系列 17 -- windows bat 脚本多参数处理】

请阅读【嵌入式开发学习必备专栏】 文章目录 bat 脚本命令行参数使用示例多参数处理使用示例遍历所有参数 bat 脚本命令行参数 在Windows批处理(.bat)脚本中接收命令行参数是一个常见的需求,这样的脚本能够根据提供的参数执行不同的操作。命…

Flutter页面状态保留策略

目的: 防止每次点击底部按钮都进行一次页面渲染和网络请求 1. 使用IndexedStack 简单,只需要把被渲染的组件外部套一层IndexedStack即可 缺点: 在应用启动的时候,所有需要保存状态的页面都会直接被渲染,保存起来. 对性能有影响 2. 使用PageController 实现较为复杂,但是不用…

# 深入理解 Java 虚拟机 (二)

深入理解 Java 虚拟机 (二) Java内存模型 主内存与工作内存 所有的变量存储在主内存(虚拟机内存的一部分)每条线程有自己的工作内存,线程对变量的所有操作(读取、赋值)都必须在工作内存中进行…

Vue移动端动态表单生成组件

FormCreate 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。支持6个UI框架,适配移动端,并且支持生成任何 Vue 组件。内置20种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。 帮助文档 | 源码下载…

数据库系统概论(第5版教材)

第一章 绪论 1、数据(Data)是描述事物的符号记录; 2、数据库系统的构成:数据库 、数据库管理系统(及其开发工具) 、应用程序和数据库管理员; 3、数据库是长期存储在计算机内、有组织、可共享的大量数据的集合&…

【Linux】线程Thread

🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ ​ 线程概述 …

【C语言】解决C语言报错:Double Free

文章目录 简介什么是Double FreeDouble Free的常见原因如何检测和调试Double Free解决Double Free的最佳实践详细实例解析示例1:重复调用free函数示例2:多次释放全局变量指针示例3:函数间传递和释放指针 进一步阅读和参考资料总结 简介 Doub…

nuget 包修改默认存放路径

平时使用 nuget packages 时,都是下载包文件到本地。 默认是在C盘,时间一久容量会高达几十个G,这样会拖慢系统运行效率。 这时需要修改包的下载位置。 打开nuget 包配置文件:Nuget.config 路径在 C:\Users\{UserName}\AppData…

网约车停运损失费:2、协商过程

目录 🍅点击这里查看所有博文 随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记…

鸿蒙开发Ability Kit(程序框架服务):【FA模型切换Stage模型指导】 配置文件差异

配置文件的差异 FA模型应用在[config.json文件]中描述应用的基本信息,一个应用工程中可以创建多个Module,每个Module中都有一份config.json文件。config.json由app、deviceConfig和module三部分组成,app标签用于配置应用级别的属性&#xff…