深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之列存(二)

Elasticsearch,作为当下最流行的开源搜索和分析引擎之一,其内部的数据结构和存储机制对于确保高效搜索和快速响应查询至关重要。在这其中,列存储(Doc Values)扮演了一个核心角色。本文将深入探讨Doc Values是什么、它们如何工作,以及为什么它们对Elasticsearch的性能如此关键。

深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)

什么是 Doc Values

Doc Values 是 Elasticsearch 中的一个内部数据结构,用于在字段级别存储排序和聚合所需的数据。与传统的行存储(将文档的每个字段值作为文档的一部分存储)不同,Doc Values 采用列式存储,这意味着它们按字段组织数据,而不是按文档。这种结构优化了读取性能,特别是当执行排序、聚合或脚本计算等操作时。

为什么需要Doc Values

在Elasticsearch中,排序和聚合操作对于处理和分析大量数据至关重要。然而,传统的倒排索引,尽管在全文检索时表现出色,但在执行这些操作时却显得力不从心。这是因为倒排索引是为快速查找包含特定词项的文档而设计的,而不是为收集特定文档集中的所有词项而优化的。

当我们对某个字段进行排序或聚合时,Elasticsearch需要访问每个匹配到的文档,以获取该字段的值。例如,考虑一个倒排索引,其中列出了不同词项及其所在的文档:

Term      | Doc_1 | Doc_2 | Doc_3  
------------------------------------  
brown     |   X   |   X   |  
dog       |   X   |       |   X
  • 在这个结构中,快速找到包含“brown”的文档(Doc_1和Doc_2)是很容易的,因为倒排索引直接映射了词项到文档的关系。但是,如果我们想进一步分析这些文档,比如找出这些文档中所有唯一的词项,以便进行聚合,倒排索引就不那么高效了。

  • 问题在于,为了使用倒排索引收集Doc_1和Doc_2中的所有词项,我们必须遍历索引中的每个词项,检查它是否属于这两个文档。这个过程随着词项和文档数量的增加而变得越来越慢,因为每次检查都需要在倒排列表中进行查找。

  • 为了解决这个问题,Elasticsearch引入了Doc Values。Doc Values是一种列式的数据结构,它存储了每个文档字段值的完整、排序好的列表。与倒排索引不同,Doc Values不是将词项映射到文档,而是将文档映射到它们所包含的词项。这种结构使得按文档收集字段值变得非常高效。

以下是Doc Values如何表示数据的一个示例:

Doc      | Terms  
-----------------------------------------------------------------  
Doc_1    | brown, dog, fox, jumped, lazy, over, quick, the  
Doc_2    | brown, dogs, foxes, in, lazy, leap, over, quick, summer

在这个Doc Values结构中,每个文档都有一个与之直接关联的词项列表。因此,当需要收集Doc_1和Doc_2中所有唯一的词项时,我们只需直接访问这两个文档的词项列表,并执行集合的并集操作。这比使用倒排索引要快得多,因为无需遍历整个索引来收集特定文档的词项。

Doc Values 的工作原理

在 Elasticsearch 中,当索引一个文档时,除了将字段值存储在倒排索引中以支持全文搜索外,还会为需要排序或聚合的字段生成 Doc Values。这些 Doc Values 是字段值的压缩、列式表示,它们与倒排索引分开存储,并且针对快速、随机访问进行了优化。

Doc Values 的关键优势在于它们能够直接提供字段值,而无需重新解析存储的原始 JSON 文档(通常存储在 _source 字段中)。这是因为 Doc Values 是在索引时预先计算和存储的,因此它们可以非常快速地加载到内存中,并直接用于排序和聚合操作。以下是 Doc Values 的工作原理的详细解释:

  • 数据生成与存储
    当文档被索引到 Elasticsearch 时,除了生成倒排索引外,还会为文档的每个字段生成 Doc Values。这些 Doc Values 是字段值的列式存储,按文档顺序排列。
    对于不需要进行全文检索的字段(如数字、日期或枚举类型),Doc Values 通常是这些字段值的直接存储形式。而对于需要进行全文检索的文本字段,Doc Values 可能会存储该字段的一个或多个分词结果。
  • 内存与磁盘使用
    Doc Values 通常被序列化到磁盘上,以节省 JVM 堆内存的使用。由于它们是按列存储的,因此可以高效地加载到操作系统的文件系统缓存中(OS cache)。
    当执行排序或聚合操作时,Elasticsearch 会尽可能地从 OS cache 中读取 Doc Values,从而减少对磁盘的直接 I/O 操作,提高性能。
  • 查询过程
    当执行排序或聚合查询时,Elasticsearch 需要收集特定文档集中的字段值。使用 Doc Values,它可以直接访问这些文档的字段值列表,而无需遍历整个倒排索引。
    Doc Values 的列式存储结构使得对这些值的操作(如排序、去重或聚合计算)非常高效,因为它们已经按文档顺序排列好了。
  • 性能优化
    由于 Doc Values 是为快速读取而设计的,它们通常比从倒排索引中收集字段值要快得多。这是因为倒排索引是为快速查找文档而优化的,而不是为收集字段值而优化的。
    Elasticsearch 还利用 Doc Values 来执行某些类型的过滤操作,如地理位置过滤,因为这些操作需要快速访问文档的字段值。
  • 与倒排索引的关系
    Doc Values 并不是要替代倒排索引,而是作为其补充。倒排索引仍然用于全文检索和快速查找包含特定词项的文档。

Doc Values 和倒排索引一起工作,使得 Elasticsearch 能够在处理大量数据时提供高效的检索、排序和聚合功能。
通过了解 Doc Values 的工作原理,可以更好地理解 Elasticsearch 如何优化排序和聚合操作,并在实际应用中更有效地使用这些功能。

Doc Values 的类型及存储

es 支持多种类型的 Doc Values,包括数字、日期、IP 地址和二进制等。每种类型都有其特定的编码方式,以优化存储空间和查询性能。例如,数字类型的 Doc Values 可能会使用高效的压缩算法来减少存储空间,而日期类型的 Doc Values 则可能会存储为可快速比较的长整型时间戳。

持久化(Persistence)

Doc Values 是在索引文档时与倒排索引一同生成。Doc Values 基于每个段(per-segment)且是不可变的,这意味着一旦创建,它们就不会再改变。为了高效地存储和访问这些数据,Doc Values 会被序列化并持久化到磁盘上。

这样做的好处是可以充分利用操作系统的内存,而不是仅仅局限于 JVM 的 Heap 内存。当工作集(working set)远小于系统的可用内存时,系统会自动将 Doc Values 加载到内存中,使其读写操作非常快速。然而,当工作集远大于可用内存时,操作系统会根据需要将 Doc Values 从磁盘读取到内存中,或者将其写入磁盘。这种方式确保了 Doc Values 的大小不再受到服务器内存的限制,同时也避免了因为 JVM Heap 内存不足而导致的程序崩溃问题。

然而,需要注意的是,当工作集所需的内存空间非常大时,Doc Values 可能会被操作系统从内存中置换出去,这可能会导致访问速度的降低。

压缩(Compression)
Doc Values 的列式存储结构非常适合进行压缩,尤其是数字类型的字段。这种压缩不仅可以减少磁盘空间的使用,还可以提高数据的访问速度。Doc Values 在压缩过程中会使用多种策略,例如:

  • 如果所有数值都各不相同(或缺失),它会设置一个标记并记录这些值。
  • 如果这些值小于 256,它将使用一个简单的编码表。
  • 如果这些值大于 256,它会检测是否存在一个最大公约数,这有助于进一步压缩数据。例如,如果所有数字都是 100 的倍数,那么可以通过除以 100 来减小数值的大小,从而减少存储所需的位数。
  • 如果没有最大公约数,它会从最小的数值开始,统一计算偏移量进行编码。
  • 对于字符串类型的字段,Doc Values 也可以通过顺序表对字符串进行数字编码,然后再对数字类型构建 Doc Values。这种方式间接地支持了字符串类型的压缩。

综上所述,Doc Values 的持久化机制确保了其可以灵活地处理不同大小的工作集,而压缩机制则有助于减少存储空间的占用并提高数据访问的效率。这些特性共同使得 Doc Values 成为 Elasticsearch 中优化排序和聚合操作性能的关键组件。

使用 Doc Values

Doc Values 默认对所有非分词字段生效,因为分词字段会产生大量 tokens,而 Doc Values 对其效果有限。如果确定不需要对某个字段进行聚合、排序或脚本操作,可以选择关闭该字段的 Doc Values,以节省磁盘空间并提高索引速度。

PUT my_index
{"mappings": {"my_type": {"properties": {"session_id": {"type":       "string","index":      "not_analyzed","doc_values": false}}}}
}

设置doc_values: false,这个字段将不再支持据聚合、排序和脚本执行(Script);

同时也可以对倒排索引做类似的配置:

PUT my_index
{"mappings": {"my_type": {"properties": {"customer_token": {"type":       "string","index":      "not_analyzed","doc_values": true,"index": "no"}}}}
}

这个可以支持聚合,但不支持查询,因为不会对这个字段生成倒排索引。

结论

Doc Values 是 Elasticsearch 性能优化的关键组成部分,它们通过预先计算和存储字段值,以及采用列式存储结构,大大提高了排序和聚合等查询操作的性能。对于需要处理大量数据和复杂查询的 Elasticsearch 集群来说,理解和优化 Doc Values 的使用至关重要。

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

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

相关文章

HTTP 超文本传送协议

1 超文本传送协议 HTTP HTTP 是面向事务的 (transaction-oriented) 应用层协议。 使用 TCP 连接进行可靠的传送。 定义了浏览器与万维网服务器通信的格式和规则。 是万维网上能够可靠地交换文件(包括文本、声音、图像等各种多媒体文件)的重要基础。 H…

HarmonyOS 开发学习笔记

HarmonyOS 开发学习笔记 一、开发准备1.1、了解ArkTs语言1.2、TypeScript语法1.2.1、变量声明1.2.2、条件控制1.2.3、函数1.2.4、类和接口1.2.5、模块开发 1.3、快速入门 二、ArkUI组件2.1、Image组件2.2、Text文本显示组件2.3、TextInput文本输入框组件2.4、Button按钮组件2.5…

json模块(高维数据的存储与读取)

json模块是 Python 标准库中的一个模块,用于处理 JSON(JavaScript Object Notation)格式的数据。JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。模块提供了在 Python 中进行 JSON 编码&…

开源个人订阅跟踪器Wallos

本文软件由网友 P家单推人 推荐; 什么 Wallos ? Wallos 是一款功能强大、开源且可自我托管的网络应用程序,旨在让您轻松管理财务。告别复杂的电子表格和昂贵的财务软件–Wallos简化了跟踪费用的过程,帮助您更好地控制财务生活。 软…

C++ | KMP算法模板

next数组初始化 char a[1000006];//原串 char p[1000006];//子串 int pmt[1000006];void getNext(int m){int j0;pmt[0]0;for(int i1;i<m;i){while(j>0 && p[i]!p[j])jpmt[j-1];if(p[i]p[j])j;pmt[i]j;} }以下实例基于上述getNext函数及数据结构执行&#xff1a…

java实战:生成会议通知Word文件

本文将介绍如何使用Java和Apache POI库来生成包含标题、正文、时间、会议地点、参会人等信息的会议通知Word文件。包含如何设置文本格式、添加标题和段落&#xff0c;以及如何将生成的Word文件保存到磁盘。看完这篇文章&#xff0c;可以掌握使用Java操作Word文档的基本技能。 …

DockerPodman save

DockerPodman save docker image save docker save docker image save 参数只有一个 -o 或 --output ,后接输出文件, 也可以写成 > , 但> 输出文件只能写在最后 , -o和--outpu可以写在前面也可以写在后面 用途: 将Image镜像保存为tar文件 为标准输出流生成一个 tar…

LeetCode---383周赛

题目列表 3028. 边界上的蚂蚁 3029. 将单词恢复初始状态所需的最短时间 I 3030. 找出网格的区域平均强度 3031. 将单词恢复初始状态所需的最短时间 II 一、边界上的蚂蚁 这题没什么好说的&#xff0c;模拟就行&#xff0c;本质就是看前缀和有几个为0。 代码如下 class S…

Spring Cloud Hystrix 参数配置、简单使用、DashBoard

Spring Cloud Hystrix 文章目录 Spring Cloud Hystrix一、Hystrix 服务降级二、Hystrix使用示例三、OpenFeign Hystrix四、Hystrix参数HystrixCommand.Setter核心参数Command PropertiesFallback降级配置Circuit Breaker 熔断器配置Metrix 健康统计配置Request Context 相关参数…

【java】12:封装

面向对象编程三大特征 1.基本介绍 面向对象编程有三大特征&#xff1a;封装、继承和多态。 2.封装介绍 封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起&#xff0c;数据被保护在内部&#xff0c;程序的其它部分只有通过被授权的操作[方法]&am…

开局一个破碗的故事例子

在一个寒冷的冬日&#xff0c;一个瘦弱的小姑娘拿着一个破碗&#xff0c;孤独地走在被白雪覆盖的街道上。她的名字叫小梅&#xff0c;她的父母早逝&#xff0c;留下她一个人在这个世界上艰难地生活。 小梅的破碗里只有几个铜板&#xff0c;那是她前一天沿街乞讨所得&#xff0c…

林浩然与杨凌云的Java世界奇遇记:垃圾回收大冒险

林浩然与杨凌云的Java世界奇遇记&#xff1a;垃圾回收大冒险 The Java Adventure Chronicles of Lin Haoran and Yang Lingyun: Garbage Collection Odyssey 在一个充满0和1代码森林的世界里&#xff0c;住着两位勇敢的程序员侠侣——林浩然和杨凌云。林浩然是个身怀Java绝技的…

【vue】axios 如何调用 htttp 接口

安装依赖&#xff1a; npm install core-js导入 core-js &#xff1a; import core-js/modules/web.url-search-params;通过调用 new URLSearchParams &#xff0c;然后 append 来准备好要传入的参数&#xff1a; let param new URLSearchParams() param.append(content, 啦…

深度学习模型与神经网络可视化工具

很多时候&#xff0c;我们需要对神经网络本身的结构有一个了解&#xff0c;并且进行一定程度的可视化&#xff0c; 这里推荐一个优秀的工具 Zetane Engine Zetane Insight Engine: Accelerate Data Analysis with AI-Powered Insights. Free download of most-detailed visu…

springboot/ssm档案管理系统公司设备管理系统Java系统企业配件系统

springboot/ssm档案管理系统公司设备管理系统Java系统企业配件系统 开发语言&#xff1a;Java 框架&#xff1a;springboot&#xff08;可改ssm&#xff09; vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysq…

Lua Packages

Lua 并没有提供明确的机制来实现 packages。然而&#xff0c;我们通过语言提供的基本的机制很容易实现他。主要的思想是&#xff1a;像标准库一样&#xff0c;使用表来描述 package。 基本示例 package的简单方法就是对包内的每一个对象都加包名作为前缀。官方示例代码用comp…

sheng的学习笔记-docker部署数据库oracle,mysql

部署目录&#xff1a;sheng的学习笔记-部署-目录-CSDN博客 docker基础知识可参考 sheng的学习笔记-docker部署&#xff0c;原理图&#xff0c;命令&#xff0c;用idea设置docker docker安装数据库 mac版本 安装oracle 下载oracle镜像 打开终端&#xff0c;输入 docker s…

Python网络通信

目录 基本的网络知识 TCP/IP IP地址 端口 HTTP/HTTPS HTTP HTTPS 搭建自己的Web服务器 urllib.request模块 发送GET请求 发送POST请求 JSON数据 JSON文档的结构 JSON数据的解码 下载图片示例 返回所有备忘录信息 此文章讲解如何通过Python访问互联网上的资源&a…

《CSS 简易速速上手小册》第7章:CSS 预处理器与框架(2024 最新版)

文章目录 7.1 Sass&#xff1a;更高效的 CSS 编写7.1.1 基础知识7.1.2 重点案例&#xff1a;主题颜色和字体管理7.1.3 拓展案例 1&#xff1a;响应式辅助类7.1.4 拓展案例 2&#xff1a;深色模式支持 7.2 Bootstrap&#xff1a;快速原型设计和开发7.2.1 基础知识7.2.2 重点案例…

ueransim关于ue侧nas层相关代码解读

一.在文件UERANSIM\UERANSIM-3.2.6\src\ue\nas中enc.cpp中完成了NAS&#xff08;非接入层&#xff09;信令的加密和解密是通过NAS_ENC模块实现的。NAS_ENC模块负责将NAS信令消息进行加密&#xff0c;以确保其传输过程中的安全性。 具体来说&#xff0c;当UE发送NAS信令消息时&…