[译]Elasticsearch _source Doc_values And Store Performance

原文地址
https://sease.io/2021/02/field-retrieval-performance-in-elasticsearch.html

在这篇博文中,我想从性能的角度探讨 Elasticsearch 为我们存储字段和查询时检索字段提供了哪些可能性。 事实上,Lucene(Elasticsearch 和 Solr 构建的基础库)提供了两种存储和检索字段的方法:存储字段(stored fields)和文档值(docvalues)。 此外,Elasticsearch 默认使用 _source 字段,这是一个大 JSON,其中包含在索引时作为输入给出的文档的所有字段。

为什么 Elasticsearch 使用 _source 字段作为默认值?从性能的角度来看,所有这些可能性有什么区别? 让我们来看看吧!

Stored And Docvalues Fields In Lucene

当我们在 Lucene 中索引文档时,已索引的原始字段的信息会丢失。 根据模式配置对字段进行相应的分析、转换和索引。 在没有任何额外数据结构的情况下,当我们搜索文档时,我们得到的是搜索到的文档的 id,而不是原始字段。 为了获取这些信息,我们需要额外的数据结构。 Lucene 为此提供了两种可能性:存储字段和文档值。

STORED FIELDS

存储字段的目的是存储字段的值(不进行任何分析)以便在查询时检索它们。

DOCVALUES

引入文档值是为了加速分面、排序和分组等操作。 文档值还可用于在查询时返回字段值。 我们唯一的限制是我们不能将它们用于文本字段。

存储字段和文档值在 Lucene 库中实现,它们可以在 Solr 和 Elasticsearch 中使用。

我写了一篇博客文章,其中比较了 Solr 中存储字段和文档值的字段检索性能:

DocValues VS 存储字段:Apache Solr 功能和性能 SmackDown

在那里您可以找到有关存储字段和文档值、其利用率和约束的更详细描述。

Field Retrieval In Elasticsearch

如果我们在映射中显式定义存储字段和文档值,则可以在 Elasticsearch 中使用它们:

"properties" : {
 "field": {
  "type": "keyword",
   "store": true,
  "doc_values" true
 }
}

默认情况下,每个字段的存储设置为 false。 相反,所有支持文档值的字段都默认启用它们。

独立于存储和文档值配置,在查询时返回查询命中的文档中每个字段的值。 发生这种情况是因为 Elasticsearch 使用另一个工具进行字段检索:elasticsearch _source 字段。

ELASTICSEARCH _SOURCE FIELD

源字段是在索引时传递到 Elasticsearch 的 JSON。 该字段在 Elasticsearch 中默认设置为 true,并且可以通过以下方式使用映射来禁用:

"mappings": {
  "_source": {
   "enabled": false
  }
}

查询时默认返回所有字段。 您甚至可以仅指定要在响应中返回的源中的字段子集。 这应该可以加快响应在网络上的传输速度。

通过正确的配置,某些字段可以被源字段排除:

PUT logs
{
 "mappings": {
  "_source": {
   "excludes": [
    "meta.description",
     "meta.other.*"
   ]
  }
 }
}

从源中排除字段将减少磁盘空间使用量,但排除的字段永远不会在响应中返回。

禁用 elasticsearch _source 字段将导致无法在不从头开始重新索引的情况下更新文档(Disabling the elasticsearch _source field will make it impossible to update a document without reindexing that from scratch)。 事实上,为了更新文档,我们需要从旧文档中获取字段的值。 从逻辑上讲,使用存储的字段或文档值从旧文档中获取字段的值应该是可行的(这就是 Solr 中原子更新的工作方式)。 但是,由于设计决策,Elasticsearch 中不允许这样做,如果您需要更新文档,则必须在 Elasticsearch 索引配置中启用 _source 字段。

RETRIEVING FIELDS

在 Elasticsearch 中,您可以启用或禁用 _source 字段并使字段存储和/或文档值。 但是我们如何在查询时检索字段呢?

默认情况下,如果定义了整个源,则返回整个源。 您可以避免它并仅返回源的子集,如下所示:

 "fields": ["field1", "field2"],
 "_source": false

但是,如果您没有启用源字段,并且想要从存储的或文档值返回字段,则必须以其他方式告诉 Elasticsearch。 对于您使用的每个源,您必须以不同的方式指定字段列表:

 "fields": ["sv1", "sv2",...],
 "docvalue_fields": ["dv1", "dv2",...],
 "stored_fields" : ["s1", "s2",...],

例如,如果您有一个存储字段和文档值字段,您可以选择是否要从文档值或存储字段中检索它。 从功能的角度来看,这是完全相同的,但您的选择可能会影响查询的执行时间。

STORED FIELDS,DOCVALUES AND ELASTICSEARCH_SOURCE INTERNAL REPRESENTATION

在本节中,我只想对存储字段、_source 字段和文档值的内部结构进行简要概述,以便有一些工具来理解使用这些方法进行字段检索的性能期望是什么。

STORED FIELDS INTERNALS

存储的字段以行的方式放置在磁盘上:对于每个文档,我们都有一行连续包含所有存储的字段。

在这里插入图片描述

以上图为例。 要访问文档 x 的 field3,我们必须访问文档 x 的行并跳过 field3 之前存储的所有字段。 跳过字段需要获取其长度。 跳过字段并不像读取字段那么昂贵,但此操作并不是免费的。

DOCVALUES INTERNALS

文档值以列的方式存储。 不同文档的相同字段的值都连续地存储在内存中,并且可以"几乎"直接访问某个文档的某个字段。 计算所需值的地址并不是一项简单的操作,并且具有计算成本,但我们可以想象,如果我们只需要一个字段,那么使用这种访问会更有效。

ELASTICSEARCH _SOURCE FIELD INTERNALS

那 _source 呢? 嗯,如上所述,源是一个大字段,其中包含一个 JSON,其中包含索引时提供给 Elasticsearch 的所有输入。 但是,这个字段是如何存储的呢? 毫不奇怪,Elasticsearch 利用了 Lucene 已经实现和提供的机制:存储字段。 特别是,_source 字段是该行中第一个存储的字段。

在这里插入图片描述

必须读取整个 _source 才能使用它包含的信息。 如果我们要返回文档的所有字段,这个过程直观上是最快的。 另一方面,如果我们只需要返回它包含的信息的一小部分,读取这个巨大的字段可能会浪费计算能力。

Benchmarking

为了对 3 种类型的字段进行基准测试,我在 Elasticsearch 中创建了 3 个不同的索引。 我对来自 Wikipedia 的 100 万份文档建立了索引,对于每个文档,我用三种不同的方法对 100 个包含 15 个字符的字符串字段建立了索引:在第一个索引中,我将字段设置为存储,在第二个索引中将字段设置为文档值。 在这两个索引中,我禁用了源字段。 相反,在第三个索引中,我只是启用了源字段。

文档和查询集合取自此处。 我使用真实的集合来模拟现实场景。

执行详情:

  • CPU:AMD锐龙3600
  • 内存:32GB

对于每个查询,我请求最好的 200 个文档,并重复测试,将要返回的字段数(在我创建的 100 个随机字符串字段中)从 1 更改为 100。

这是基准测试的结果:
在这里插入图片描述

结果完全符合我们的预期。**如果每个文档需要几个字段,则建议使用文档值。**另一方面,当我们想要返回整个文档时,_source字段是最好的字段,而存储字段的使用是其他两个字段之间的完美折衷。

在我执行的基准测试场景中,如果我们只需要一个字段,则 docvalues 的速度几乎是 _source 字段的两倍,而在极端相反的情况下,如果我们想返回所有字段,则图表显示,当我们只需要一个字段时,速度几乎提高了 2 倍。 使用 _source 字段代替 docvalues。

总之,性能并不是我们必须考虑的唯一参数。 正如我们在这篇博文中简要解释的那样,使用一种或另一种方法存在一些限制。 由于您的用例的某些限制,您可能被迫使用这三种方法之一。 即使从表现来看,我们也没有明显的赢家。

如果磁盘空间不是问题,您甚至可以混合使用不同的方法并将字段设置为存储和文档值,并启用源。 在查询时,Elasticsearch 使您能够选择所需的字段列表,以及是否希望从 _source、stored 或 docvalues 返回它们。

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

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

相关文章

详细分析Mybatis与MybatisPlus中分页查询的差异(附Demo)

目录 前言1. Mybatis2. MybatisPlus3. 实战 前言 更多的知识点推荐阅读: 【Java项目】实战CRUD的功能整理(持续更新)java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全) 本章节主要以Demo为例&#xff…

122. Kafka问题与解决实践

文章目录 前言顺序问题1. 为什么要保证消息的顺序?2.如何保证消息顺序?3.出现意外4.解决过程 消息积压1. 消息体过大2. 路由规则不合理3. 批量操作引起的连锁反应4. 表过大 主键冲突数据库主从延迟重复消费多环境消费问题后记 前言 假如有家公司是做餐饮…

3行代码,实现一个取色器

前言 今天发现了一个很好玩的 API ——EyeDropper。 EyeDropper API 提供了一种创建拾色器工具的机制。使用该工具,用户可以从屏幕上取样颜色,包括浏览器窗口之外的区域。 这是 MDN 上对它的介绍,可以取包括浏览器窗口之外的区域。我们一起看看是怎么个事 什么是取色器 取…

24年最新AI数字人简单混剪

24年最新AI数字人简单混剪 网盘自动获取 链接:https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码:0b8x

【C 数据结构-图】2. 图的存储结构

文章目录 【 1. 图的顺序存储结构 】1.1 基本原理1.2 顺序存储结构的 C 实现 【 2. 图的链式存储结构 】2.1 图的临接表存储结构2.1.1 临接表的 基本原理2.1.2 临接表的 链表节点2.1.3 邻接表 各结构体的C实现2.1.4 临接表 计算顶点的出度和入度邻接表计算 无向图的出度和入度邻…

【Fastadmin】后台角色组权限问题(multi,开关switch,控制器新增方法)

1.列表开关类型的权限 如图: 此类开关请求的方法为multi 开关在点击的时候默认是只允许修改数据库的status字段的,如果我们开关不是status字段,我们需要在服务端对应的控制器中定义protected $multiFields"id,name,swith";&#x…

一个物业管理服务项目的思考——智慧停车场无人值守呼叫系统到电梯五方对讲再到呼叫中心

目录 起源智慧停车场无人值守呼叫系统然后电梯五方对讲系统又然后物业呼叫中心集控E控中心怎么做 起源 小区里新装了智慧停车场系统,马上展现出了科技化、现代化的新形象。一个显著的好处是:停车场的出入口,再也看不到司机和保安争吵的场景了…

四川景源畅信:抖音的运营策略有哪些?

在数字营销的大潮中,抖音以其巨大的用户基础和强大的传播力成为众多品牌和商家的必争之地。那么,抖音的运营策略有哪些呢?这个问题涉及到内容创作、用户互动、数据分析和品牌合作等多个方面。 一、内容创作与优化在抖音,内容是吸引用户的关键…

C++ 数据内存分布揭秘:从栈到堆的探索之旅

目录 1. 栈(Stack) 2. 堆(Heap) malloc和new的区别 堆与栈在C中的异同点详解 3. 数据段(Data Segment) 4. 代码段(Code Segment) 5. 动态内存分配的陷阱 当我们谈论C编程时,对内存布局的理解至关重要。本文将深入探讨C中各种变量和数据结构在内存中的分布情况…

这些CTF,不仅学技术,还有巨额奖金!

前言: 不会吧,不会吧,不会还有安全er不知道CTF是什么吧? 在程序员的世界里,也有ACM这样的编程大赛,成为各路编程高手一较高下展示能力的平台。 那在网络安全的圈子里,各路黑客红客白帽子们又…

rag-embeddings基础流程

什么是检索增强的生成模型 LLM 固有的局限性 LLM 的知识不是实时的LLM 可能不知道你私有的领域/业务知识 检索增强生成 RAG(Retrieval Augmented Generation)顾名思义,通过检索的方法来增强生成模型的能力。 类比:你可以把这个…

linux 内核编译

目录 Linux操作系统框架 Linux内核的主要功能: Linux的内核目录结构: 结构图: 详细介绍: uname - a 补充 编译之前 UTC 时间补充 Linux内核编译流程: 方法一: 官方内核编译: 1. 运行 build.sh 脚本, 记得加 sudo 权…

Day 24 数据库管理及数据类型

数据库管理及数据类型 一:数据类型 1.数值类型 整数类型 ​ 整数类型:TINYINT SMALLINT MEDIUMINT INT BIGINT ​ 作用:用于存储用户的年龄、游戏的Level、经验值等 浮点数类型 ​ 浮点数类型:FLOAT DOUBLE ​ 作用&#xf…

linux或ubuntu环境下需要自行安装vivado USB Program下载程序驱动

如果在linux或ubuntu环境下,不安装驱动是无法下载FPGA程序的。在linux或ubuntu环境下安装程序不要自动安装。 johnjohn-wang:~/vitis2021.2/Vivado/2021.2/data/xicom/cable_drivers/lin64/install_script/install_drivers$ sudo ./install_drivers

1天搞定SpringBoot+Vue全栈开发 (7)Axios网络请求

1.Axios的使用 Axios中文文档 | Axios中文网Axios 是一个基于 promise 的网络请求库&#xff0c;可以用于浏览器和 node.jshttps://www.axios-http.cn/ 2.与vue整合 App.vue: <template><div id"app"><Moviev-for"movie in movies":key&qu…

一致性评价政策加速行业仿制药洗牌,惯爱为代表的新锐品牌崭露头角

从印度神油到以形补形&#xff0c;男人的问题&#xff0c;从古至今一直困扰着很多人&#xff0c;大多人都羞于启齿。然而&#xff0c;沉默的背后&#xff0c;隐藏着令人震惊的数据&#xff1a;据统计显示&#xff0c;ED&#xff08;勃起功能障碍&#xff09;是男性生殖系统发病…

9.Java内置锁的核心原理-Synchronized

文章目录 Java内置锁的核心原理-Synchronized1.线程安全问题1.1.自增运算分析1.2.临界区资源和临界区代码片段 2.synchronized关键字2.1.synchronized同步方法2.2.synchronized同步代码块2.3.synchronized同步方法和synchronized同步代码块区别2.4.静态的同步方法2.5.内置锁的释…

18、ESP32 ESP-NOW 点对点通信

ESP-NOW 是乐鑫自主研发的无连接通信协议&#xff0c;具有短数据包传输功能。该协议使多个设备能够以简单的方式相互通信。 ESP-NOW 功能 ESP-NOW 支持以下功能&#xff1a; 加密和未加密的单播通信;混合加密和未加密的对等设备;最多可携带 250 字节 的有效载荷;发送回调功能…

C#修改默认参数settings文件

右击项目在设置中进行修改&#xff1a; 千万不要在这里改。 如果要在自己的项目里添加这个文件&#xff0c;首先新建个文件夹&#xff0c;然后添加.setting文件&#xff0c;然后再像上面说的那样添加属性。

通过 Java 操作 redis -- String 基本命令

关于 redis String 类型的相关命令推荐看 Redis - String 字符串 要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务器&#xff0c;推荐看通过 Java 操作 redis -- 连接 redis 本博客只介绍了一小部分常用的命令&#xff0c;其他的命令根据上面推荐的博客也能很简单…
最新文章