创建合适的索引不仅可以节约存储资源, 还可以优化我们的查询,减少内存的使用。
存储优化方式如下:
去除多余的字段
每一个字段都会占用硬盘资源,越少字段的索引,数据占用的存储空间就少。文档量少也许还看不出效果,当文档量几亿的时候,节约的硬盘空间还是很客观的。
尽量type不用text类型
text类型的字段相比与keyword,date,long等占用更多的存储空间不说,查询,排序,聚合都没有其他类型高效。所以在不使用分词效果的时候,字段尽量使用其他类型。
type为text的字段优化
1. norms
会消耗许多磁盘空间,来计算在一个字段上,文档的相关性(_scoring)。如果该字段只是用来filtering或者聚合(aggregation) ,就可以设置为false。
2. fielddata
要用到聚合的text字段,必须把fielddata设置为true. 排序或者聚合的时候,fielddata会把所有内容加载到内存,一旦分析字符串被加载到 fielddata ,他们会一直在那里,直到被驱逐(或者节点崩溃),所以会比较消耗内存。优化手段如下:
- fielddata_frequency_filter:过滤部分内容,减少内存的使用
- min: 至少在本段文档中出现超过 百分之多少 的项才会被加载到内存中
- max: 最多在本段文档中出现超过 百分之多少 的项才会被加载到内存中
- min_segment_size: 忽略某个大小以下的段。 如果一个段内只有少量文档,它的词频会非常粗略没有任何意义。 小的分段会很快被合并到更大的分段中,某一刻超过这个限制,将会被纳入计算。
- 配置文件(elasticsearch.yml)中增加配置
- indices.fielddata.cache.size: 20% //最多使用使用20%的内存来存储fielddata。会用到LRU为新数据提供空间
- indices.breaker.fielddata.limit:40% // fielddata 大小是在数据加载 之后 检查的。如果一个查询试图加载到 fielddata的信息超过内存的40%,就会 触发 断路器,查询会被中止并返回异常。
一个索引的例子
curl -XPUT 'localhost:9200/index-test' -H 'Content-Type: application/json' -d'
{
"mappings": {
"doc": {
"properties": {
"sql": {
"type": "text",
"fielddata": true,
"fielddata_frequency_filter": {
"min": 0.01,
"min_segment_size": 300
},
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"lock_time": {
"type": "double"
},
"rows_sent": {
"type": "long"
},
"host": {
"type": "text",
"norms": false
},
"time_local": {
"type": "date"
},
"user": {
"type": "keyword"
}
}
}
}
}
'