一、doc_values介绍

doc values是一个我们再三重复的重要话题了,你是否意识到一些东西呢?

  • 搜索时,我们需要一个“词”到“文档”列表的映射
  • 排序时,我们需要一个“文档”到“词“列表的映射,换句话说,我们需要一个在倒排索引的基础上建立的“正排索引”

这里的“正排索引”结构通常在其他系统中(如关系型数据库)被称为“列式存储”。本质上,它是在数据字段的一列上存储所有value,这种结构在某些操作上会表现得很高效,比如排序。

在ES里这种“列式存储”就是我们熟悉的“doc values”,默认情况下它是被启用的,doc values在index-time(索引期)被创建:当一个字段被索引时,ES会把“词”加入到倒排索引中,同时把这些词也加入到面向“列式存储”的doc values中(存储在硬盘上)。

doc values通常被应用在以下几个方面:

  • 基于一个字段排序
  • 基于一个字段聚合
  • 执行某些filter上(如:geolocation filter)
  • 在script(脚本)中引用了一个或多个字段

由于doc values在索引期被序列化到硬盘上,我们可以利用操作系统去快速的访问它们,关于doc values在磁盘上是如何被管理的,后面会讲到。

大多数的字段默认情况下都会被索引,这使得他们可以被搜索到,倒排索引允许一个查询基于一个词表排序,也可以快速访问包含某个词的文档列表。

排序、聚合,和在脚本中访问一些字段值时都需要另一种不同的访问方式,因为倒排索引不支持这种访问,所以我们需要一种结构能查询到文档到词的映射。

doc values是在索引期创建基于磁盘的数据结构,这种结构使得上述访问成为可能。doc values支持绝大部分字段类型,除了“analyzed”类型的string字段。(因为对于string的列存储会先转换为数字id再存)

所有的字段都默认支持doc values,如果你确定你不需要在某个字段上排序或者聚合或者在脚本中访问,你可以disable掉:

  1. status_code字段默认开启doc_values
  2. session_id字段禁用了doc_values,虽然被禁用但是还是可以被查询

TIP:doc_values可以在同一个索引的同名字段上设置不同值,它也可以基于一个已存在的字段使用put mapping api来禁用它。

看如下的倒排索引结构:


如果我们想为每一个包含“brown”的文档编辑一份完整的词列表,我们可能会用如下查询:

看上面的查询部分。倒排索引通过词条排好了序,所以我们首先找到包含“brown”的词条列表,然后跨列扫描所有包含“brown”的文档,这里我们很幸运的找到了“Doc_1”和“Doc_2”。

然后在聚合部分,我们需要找Doc_1和Doc_2中找到所有的词,在倒排索引的去做这个操作很非常昂贵的:意味着我们不得不迭代索引中的每一个词,看它们是否包含在doc_1和doc_2中,这个过程是非常缓慢的,而且也是非常傻逼的:因为随着文档词量的增加,我们聚合的执行时间也会增加。

让我们看看下面的结构:

有了这个结构我们就会很容易得到doc_1和doc_2所包含的词条,我们只需要通过上面的结构把两个集合合并起来就行了。
因此,查询和聚合是非常复杂的,查询文档使用的是倒排索引,聚合文档使用的是正排索引(doc_values)

note:doc values不仅仅是用在聚合中,还被用在排序、脚本、子父文档关系(这里暂不做介绍)。

二、深入Doc Values

前面讲到的doc values给我们几个印象:快速访问、高效、基于硬盘。现在我们来看看doc values到底是如何工作的?

doc values是在“索引期“随着倒排索引一起生成的,也就是说doc values是基于每个索引段生成且是不可改变的(immutable),和倒排索引一样,doc values也会被序列化到磁盘上,这使得它具有了高效性和可扩展性。

通过序列化一个数据结构到磁盘上,我们可以依赖操作系统的file system cache 替代JVM的堆内存,当我们的“工作集”小于OS可用内存时,操作系统会自然的加载这些doc values到内存。这时doc values的性能和在JVM堆内存中表现是一样的。

但是当工作集大于操作系统可用内存时,操作系统将会按需加载doc values,这种情况下的访问速度会明显的慢于全量加载doc values的时候。但这种操作使得我们的服务器内存利用率远超过服务器最大内存限制。试想一下,如果全量加载到doc values到内存中势必会造成ES OutOfMemery。

NOTE:由于doc values不受JVM堆内存管理,所以我们可以把ES对内存设置得小一点,把更多的内存留给操作系统来换出(doc values),同时这也可以使JVM的GC工作在更小的堆内存上,更快更高效的执行GC。
通常,我们配置JVM的堆内存基本和操作系统内存各占一半(50%),由于引进了doc values所以我们可以考虑把JVM的堆内存设置得小一些,比如我们可以在一个64G的服务器上设置JVM堆内存为4 – 16GB比设置堆内存为32G更加高效。

三、Column-store compression(列式存储压缩)

本质上doc values是一个被序列化的面向“列式储存”的结构,我们前面讨论过列式存储在某些查询操作上是有优势的,不仅如此它们也更擅长数据压缩,特别是数字,这对磁盘存储和快速访问来说是及其重要的。

为了了解它是如何压缩数据的,我们看下面简单的doc values结构

像上面这种每行一条数据的形式,我们可以得到连续的数字块,如:[100,1000,1500,1200,300,1900,4200]。因为我们知道它们都是数字值可以被排列在一起通过一个一致的偏移量。

跟深层次的,这里有几种压缩方法可以运用在这些数字上。你可能知道上面的数字都是100的倍数,如果索引段上所有的的数字都共享一个“最大公约数”,那么就可以用这个最大公约数去压缩数据。如上面的数字我们可以除以100,得到的数据是[1,10,15,12,3,19,42]。这样这些数字会变得小一些,存储时占用的比特数也会小一些。

doc values使用几种手段来压缩数字。

  1. 如果所有的数字值都相等(或者缺失),会设置一个标记来表示该值
  2. 如果所有数字值的个数小于256个,将会使用一个简单的编码表来压缩
  3. 如果大于了256个,看看是否存在最大公约数,存在则使用最小公倍数压缩
  4. 如果不存在最大公约数,则存储偏移量来压缩数字。

如你看到的,你可能会想“这样做对数值型字段做压缩确实很好,那么对字符串类型呢?”,其实字符串压缩也是和数字压缩一样采用同样的方法通过一个序数表来压缩,字符串被去重、排序后被赋予了一个ID,这些ID就是数字,这样就可以采用上面的方案进行压缩了。对于序数表本身也会采用压缩存储。

转自:http://h2ex.com/1631

转载于:https://www.cnblogs.com/bonelee/p/6401531.html

ES doc_values介绍2——本质是field value的列存储,做聚合分析用,ES默认开启,会占用存储空间...相关推荐

  1. 行存储和列存储小介绍

    .定义 1.1定义 Sybase在2004年左右就推出了列存储的Sybase IQ数据库系统,主要用于在线分析.数据挖掘等查询密集型应用.列存储,缩写为DSM,相对于NSM(N-ary storage ...

  2. ES基本介绍(2)(*)

    简介 ES是一个基于RESTful web接口并且构建在Apache Lucene之上的开源分布式搜索引擎. 同时ES还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,能 ...

  3. ElasticSearch(ES)介绍

    前言 为什么学习ElasticSearch? 1.ElasticSearch具备非常强的大数据分析能力.虽然Hadoop也可以做大数据分析,但是ElasticSearch的分析能力非常高,具备Hado ...

  4. ES的Query的DSL语法Filter DSL聚合分析

    1 查询所有(match_all query) GET /lagou-company-index/_search { "query":{ "match_all" ...

  5. 时间序列数据库——索引用ES、聚合分析时加载数据用什么?docvalues的列存储貌似更优优势一些...

    加载 如何利用索引和主存储,是一种两难的选择. 选择不使用索引,只使用主存储:除非查询的字段就是主存储的排序字段,否则就需要顺序扫描整个主存储. 选择使用索引,然后用找到的row id去主存储加载数据 ...

  6. lucene底层数据结构——FST,针对field使用列存储,delta encode压缩doc ids数组,LZ4压缩算法...

    参考: http://www.slideshare.net/lucenerevolution/what-is-inaluceneagrandfinal http://www.slideshare.ne ...

  7. JSP、EL和JSTL-学习笔记03【EL介绍和运算符、EL获取域中存储的数据】

    Java后端 学习路线 笔记汇总表[黑马程序员] JSP.EL和JSTL-学习笔记01[JSP基础语法] JSP.EL和JSTL-学习笔记02[MVC] JSP.EL和JSTL-学习笔记03[EL介绍 ...

  8. es 全量同步mysql_什么时候该用MySQL,什么时候该用ES呢?

    作者:张sir 来源:京东技术 京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常大,造成了订单数据读多写少的情况. 我们把订单数据存储在MySQL ...

  9. CAT分布式监控系统:CAT功能介绍,CAT监控系统是什么,能做什么?

    CAT分布式监控系统(一):CAT监控系统功能介绍        本文概要:              1.CAT监控系统是什么.               2.CAT监控系统能做什么,能监控些什么 ...

最新文章

  1. 解决tomcat was unable to start within问题
  2. 新建Web网站与新建Web应用程序的区别
  3. ORACLE事务提交
  4. atitit.orm的缺点与orm框架市场占有率,选型attilax总结
  5. 【kafka】kafka BindException: Address already in use 一个失误或者愚蠢的问题
  6. hashmap hashtable concurrenthashmap区别
  7. 非基元类型数据结构_Java数据类型–基元和二进制文字
  8. phpstudy升级mysql5.6_phpstudy升级mysql数据库
  9. 【LeetCode每日一题】633. 平方数之和
  10. vue3+vant Failed to resolve import “E:/code3/jianmu-user-yd/node_modules/vant/lib/vant/es/icon/style
  11. c语言中puts的作用是,C语言的字符串输出puts()函数
  12. python去除重复单词_Python程序,用于删除给定句子中的所有重复单词。
  13. 香橙派借助语音模块实现语音刷抖音
  14. mkv视频格式转换mp4格式
  15. Html是网页制作的核心语言吗,html网页设计报告总结.doc
  16. 使用NoteExpress引入参考文献
  17. 腾讯地图标记点击事件
  18. 欧姆龙 PLC 程序NJ ST语言EtherCat总线控制 24个伺服轴大型程序电池生产线 包括PLC NJ-1400和威纶通触摸屏程序
  19. 河南城建学院matlab报告,河南城建学院MATLAB上机实验答案
  20. php日期去掉分秒,Phpcms教程:解决内容页去掉发布时间的小时,分秒问题

热门文章

  1. Windows 7 + Fedora 17 双系统安装详解
  2. mac u盘文件过大 拷贝不进去_使用mac时文件太大无法拷贝怎么办
  3. 试题以文件的形式存在C语言,2016年计算机二级C语言上机题库
  4. 每天一个linux命令目录
  5. mysql的数据类型以及性能优化
  6. linux的命令行操作和shell的区别
  7. php之工作积累 (一)
  8. 2021-08-27 思考:1000瓶药水,1瓶有毒,老鼠毒发24h,如何用最少的老鼠在24h内找出毒药?
  9. debain unable to find the kernel_云改的核心技术:主机虚拟化(TO 政企人员)
  10. 网络推广是做什么的介绍网站内容更新时需要遵循哪些原则?