ES字段类型与内存管理
一、ES常见字段类型:
1、 概述
字段是数据存储的最小微粒,根据数据的性质不同将数据分成不同的字段类型,熟悉不同字段类型的特性,对索引的Mapping设计、查询调优都极其重要。
2、 关键参数
Index:定义字段的分析类型以及检索方式
no | 将无法通过检索查询到该字段 |
not_analyzed | 将整个字段存储为关键字,常用于汉字短语、邮箱等复杂的字符串 |
analyzed | 将会通过默认的standard分析器进行分析 |
store:定义了字段是否存储
false(默认) | 将原始文本存储在_source(除非已关闭)里面 |
ture | 将独立存储该字段,频繁使用的字段可以设置,可加快解析,但加大存储负担 |
boost:用于设置字段的权重,设置后不重建索引,权重无法修改
copy_to:用于配置自定义的_all字段,就是对各字段合并为一个超级字段。
doc_values:是为了加快排序、聚合操作,在建立倒排索引的时候,额外增加一个列式存储映射,是一个空间换时间的做法。默认是开启的,对于确定不需要聚合或者排序的字段可以关闭。
format:用于格式化日期
fields:让同一文本有多种不同的索引方式,比如一个String类型的字段,可以使用text类型做全文检索,使用keyword类型做聚合和排序。
properties:Object或者nested类型,可以通过properties参数指定
3、元数据
_index | 文档所属的索引名 |
_type | 文档所属的类型名 |
_id | 文档唯一ID |
_source | 文档的原始json数据 |
_all | 整合所有内容到该字段(字符串类型,以空格做分隔符) |
_version | 文档的版本信息 |
_score | 相关性打分 |
4、字段类型
ES中的字段类型大致可以分为两类:确切值(exact value)及全文文本(full text)
数据类型 | ||
Text | 字符串类型 | 用于全文搜索,不拥有排序,很少用于聚合 |
Keyword | 字符串类型 | 适合用于结构化字段的精确值搜索,可排序,聚合 |
Date | 日期类型 | "strict_date_optional_time||epoch_millis" |
integer/long | 整数类型 | 确切值 |
double/float/half_float | 浮点类型 | 满足需求尽量选范围小的数据类型 |
IPv4 & IPv6 | IP类型 | |
object | 对象类型 | 内部对象被处理成扁平键值对结构 |
nested | 嵌套类型 | 内部文档被保留在两个文档中,查询时做join处理 |
token_count | 用于统计词频 | |
boolean | 逻辑类型 | |
array | 数组类型 | Es中无专用的数组类型,字段包含的多值需同类型 |
父子文档:
ES 提供了类似关系型数据库中 Join 的实现。使用 Join 数据类型实现,可以通过 Parent / Child 的关系,从而分离两个对象
父文档和子文档是两个独立的文档
更新父文档无需重新索引整个子文档。子文档被新增,更改和删除也不会影响到父文档和其他子文档。
二、内存管理
1、ES缓存主要分成三大类(占用堆内存空间):
A、 Node Query Cache(Filter Context)
每个节点有一个Node Query缓存,由该节点所有的Shard共享,只缓存Filter Context相关内容
需要在每个Data Node节点上配置(Node Level:indices.queries.cache.size:”10%”;Index Level:index.queries.cache.enabled:true)
此类缓存保存的时Segment级缓存命中的结果。Segment被合并后,缓存失效
B、 Shard Query Cache(Cache Query的结果)
缓存每个分片上的查询结果(只缓存设置size的查询对应的结果,不缓存hits。)
配置在每个节点上(indice.requests.cache.size:”1%”)
分片Refresh时,Shard Request Cache会失效。如果Shard对应的数据频繁发生变化,该缓存的效率会很差。
C、 Fielddata Cache
除Text类型,默认都采用doc_values,节约内存。
Text类型字段需要打开Fileddata才能对其进行聚合排序(Text分词后,排序和聚合效果一般,一般建议不使用)
可通过Indices.fielddata.cache.size进行控制(默认无限制)
Segment被合并后会失效
2、内存管理最佳实践
内存一半分给JVM(不超过32G),一半留给操作系统,缓存索引文件
查看各个节点内存状况常用命令:
GET _cat/nodes?v
GET _nodes/stats/indices?pretty
GET _cat/nodes?v&h=name,queryCacheMemory,queryCacheEvictions.requestCacheEvictions,requestCacheMemory,requestCacheHitCount,request_cache.miss_count
GET _cat/nodes?h=name,port,segmetns.memory,segments.index_writer_memory,fielddata.memory_size,query_cache.memory_size,request_cache.memory_size&v
3、关于熔断器
断路器可以避免不合理操作引发的OOM,每个断路器可以指定内存使用的限制
Parent circuit breaker | 设置索引的断路器可以使用的内存的总量 |
Fielddata circuit breaker | 加载fielddata所需要的内存 |
Request circuit breaker | 防止每个请求级数据结构超过一定的内存(例如聚合计算的内存) |
In filght circuit breaker | Request中的断路器 |
Accounting request circuit breaker | 请求结束后不能释放的对象所占用的内存 |
断路器查询命令:
GET /_nodes/stats/breaker?