|NO.Z.00047|——————————|BigDataEnd|——|Hadoop&ElasticSearch.V47|——|ELK.v47|原理剖析|Doc Values机制|
一、DocValues机制
### --- 为什么要有 Doc Values
~~~ ElasticSearch 之所以搜索这么快速,归功于它的 倒排索引的设计,然而它也不是万能的,
~~~ 倒排索引的检索性能是非常快的,但是在字段值排序时却不是理想的结构。
~~~ 下面是一个简单的 倒排索引的结构
### --- Doc Values机制结构
~~~ 如上表便可以看出,他只有词对应的 doc ,但是并不知道每一个 doc 中的内容,
~~~ 那么如果想要排序的话每一个 doc都去获取一次文档内容岂不非常耗时?
~~~ DocValues 的出现使得这个问题迎刃而解。
~~~ 字段的 doc_values 属性有两个值, true、false。默认为 true ,即开启。
~~~ 当 doc_values 为 fasle 时,无法基于该字段排序、聚合、在脚本中访问字段值。
~~~ 当 doc_values 为 true 时,ES 会增加一个相应的正排索引,这增加的磁盘占用,
~~~ 也会导致索引数据速度慢一些
Term Doc_1 Doc_2
-------------------------
quick | | X
the | X |
brown | X | X
dog | X |
dogs | | X
fox | X |
foxes | | X
in | | X
jumped | X |
lazy | X | X
leap | | X
over | X | X
summer | | X
the | X |
------------------------
### --- 举例:
DELETE /person
PUT /person
{
"mappings" : {
"properties" : {
"name" : {
"type" : "keyword",
"doc_values": true
},
"age" : {
"type" : "integer",
"doc_values": false
}
}
}
}

POST _bulk
{ "index" : { "_index" : "person", "_id" : "1" } }
{ "name" : "明明", "age": 22 }
{ "index" : { "_index" : "person", "_id" : "2" } }
{ "name" : "丽丽", "age": 18 }
{ "index" : { "_index" : "person", "_id" : "3" } }
{ "name" : "媛媛", "age": 19 }

POST /person/_search
{
"query": {
"match_all": {}
},
"sort" : [
{"name": {"order": "desc"}}
]
}

POST /person/_search
{
"query": {
"match_all": {}
},
"sort" : [
{"age": {"order": "desc"}}
]
}

POST /person/_search
{
"query": {
"match_all": {}
},
"size":0,
"aggs": {
"max_age": {
"max": {
"field": "age"
}
}
}
}

二、Doc Values 是什么
### --- Doc Values 是什么
~~~ Docvalues 通过转置倒排索引和正排索引两者间的关系来解决这个问题。
~~~ 倒排索引将词项映射到包含它们的文档,
~~~ Docvalues 将文档映射到它们包含的词项:
~~~ 当数据被转置之后,想要收集到每个文档行,获取所有的词项就非常简单了。
~~~ 所以搜索使用倒排索引查找文档,聚合操作收集和聚合 DocValues 里的数据,
~~~ 这就是 ElasticSearch 。
Doc Terms
-----------------------------------------------------------------
Doc_1 | brown, dog, fox, jumped, lazy, over, quick, the
Doc_2 | brown, dogs, foxes, in, lazy, leap, over, quick, summer
Doc_3 | dog, dogs, fox, jumped, over, quick, the
-----------------------------------------------------------------
三、深入理解 ElasticSearch Doc Values
### --- 深入理解 ElasticSearch Doc Values
~~~ DocValues 是在索引时与倒排索引同时生成。
~~~ 也就是说 DocValues 和 倒排索引一样,基于 Segement 生成并且是不可变的。
~~~ 同时 DocValues 和 倒排索引一样序列化到磁盘,这样对性能和扩展性有很大帮助。
~~~ DocValues 通过序列化把数据结构持久化到磁盘,我们可以充分利用操作系统的内存,
~~~ 而不是 JVM 的 Heap 。
~~~ 当workingset 远小于系统的可用内存,系统会自动将 DocValues 保存在内存中,
~~~ 使得其读写十分高速; 不过,当其远大于可用内存时,操作系统会自动把 DocValues 写入磁盘。
~~~ 很显然,这样性能会比在内存中差很多,但是它的大小就不再局限于服务器的内存了。
四、Doc Values 压缩
### --- Doc Values 压缩
~~~ 从广义来说, DocValues 本质上是一个序列化的 列式存储,
~~~ 这个结构非常适用于聚合、排序、脚本操作。
~~~ 而且,这种存储方式也非常便于压缩,特别是数字类型。
~~~ 这样可以减少磁盘空间并且提高访问速度。下面来看一组数字类型的 DocValues :
Doc Terms
-----------------------------------------------------------------
Doc_1 | 100
Doc_2 | 1000
Doc_3 | 1500
Doc_4 | 1200
Doc_5 | 300
Doc_6 | 1900
Doc_7 | 4200
-----------------------------------------------------------------
### --- 你会注意到这里每个数字都是 100 的倍数, DocValues 会检测一个段里面的所有数值,
~~~ 并使用一个 最大公约数 ,方便做进一步的数据压缩。
~~~ 我们可以对每个数字都除以 100,然后得到: [1,10,15,12,3,19,42] 。
~~~ 现在这些数字变小了,只需要很少的位就可以存储下,也减少了磁盘存放的大小。
~~~ DocValues 在压缩过程中使用如下技巧。它会按依次检测以下压缩模式:
~~~ 如果所有的数值各不相同(或缺失),设置一个标记并记录这些值
~~~ 如果这些值小于 256,将使用一个简单的编码表
~~~ 如果这些值大于 256,检测是否存在一个最大公约数
~~~ 如果没有存在最大公约数,从最小的数值开始,统一计算偏移量进行编码
~~~ 当然如果存储 String 类型,其一样可以通过顺序表对 String 类型进行数字编码,
~~~ 然后再把数字类型构建DocValues 。
五、禁用 Doc Values
### --- 禁用 Doc Values
~~~ DocValues 默认对所有字段启用,除了 analyzed strings 。
~~~ 也就是说所有的数字、地理坐标、日期、IP 和不分析( not_analyzed )字符类型都会默认开启。
~~~ analyzed strings 暂时还不能使用 DocValues ,
~~~ 是因为经过分析以后的文本会生成大量的 Token ,这样非常影响性能。
~~~ 虽然 DocValues 非常好用,但是如果你存储的数据确实不需要这个特性,
~~~ 就不如禁用他,这样不仅节省磁盘空间,也许会提升索引的速度。
~~~ 要禁用 DocValues ,在字段的映射(mapping)设置 doc_values:false 即可。
~~~ 例如,这里我们创建了一个新的索引,字段 "session_id" 禁用了 DocValues :
~~~ 通过设置 doc_values:false ,这个字段将不能被用于聚合、排序以及脚本操作
DELETE /my_index
PUT my_index
{
"mappings": {
"properties": {
"session_id": {
"type": "keyword",
"doc_values": false
}
}
}
}

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv025-elk
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」