一. 索引
对于日志系统或者说数据量持续增加的大数据量存储,不建议存储在一个索引里,建议可以每月甚至每天建立一个索引。
如:
index_2019-01-01-000001
index_2019-01-02-000002
index_2019-01-03-000003
大索引设计建议:使用模板+Rollover+Curator
动态创建索引。
索引增量更新原理
一图胜千言。
索引更新的时机是:当原始索引满足设置条件的三个中的一个的时候,就会更新为新的索引。 为保证业务的全索引检索,一般采用别名机制。
在索引模板设计阶段,模板定义一个全局别名:用途是全局检索,如图所示的别名:indexall。 每次更新到新的索引后,新索引指向一个用于实时新数据写入的别名,如图所示的别名:indexlatest。 同时将旧索引的别名 index_latest 移除。
使用 curator 高效清理历史数据,有关介绍:https://blog.youkuaiyun.com/m0_37780228/article/details/87801809
二. Mapping 设计
如果已经建完索引,
- ES 支持增加字段 //新增字段 PUT index_a { "mappings": { "_doc": { "properties": { "status_code": { "type": "keyword" } } } } }
- ES 不支持直接删除字段
- ES 不支持直接修改字段
- ES 不支持直接修改字段类型
索引分为静态 Mapping(自定义字段)+动态 Mapping(ES 自动根据导入数据适配)。
实战业务场景建议:选用静态 Mapping,根据业务类型自己定义字段类型。
好处:
- 可控;
- 节省存储空间(默认 string 是 text+keyword,实际业务不一定需要)。
零散知识点:
1.doc_values 聚合和排序用的数据结构
ElasticSearch中保存字符串将默认被映射成text和keyword类型,字段后面加上.keyword表示访问的是keyword类型
Text: 会分词,然后倒排索引;支持模糊、不支持精确查询;不支持聚合和排序("doc_values": false)
keyword:不进行分词,不会倒排索引;不支持模糊、精确查询;支持聚合和排序("doc_values": true)
对于有些字段使用text类型则浪费了空间,所以如果在es中字段不需要进行分词,可以把字段改成keyword类型 ,不进行倒排索引,节省内存。
如果字段不需要聚合和排序 可以设置doc_values为false节省磁盘空间,提高索引速度
对于索引中字段类型设置:
在创建索引时候可以设置字段类型
PUT school //索引名
{
"settings":{
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings":{
"student":{ //表名
"properties":{
"name":{ //字段名
"type":"text", //字段类型
"doc_values": false
},
"address":{
"type":"keyword"
},
"age":{
"type":"integer"
},
"date":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss|| yyy-MM-dd||epoch_millis"
}
}
}
}
}
如果索引已经有数据,那么有数据的字段就不能修改类型,可以新增一个字段设置类型
PUT testsyc/_mapping/s
{
"properties": {
"iptables": { //新增字段名
"type": "keyword"
}
}
}
2.es中的特殊字段
1)._all:它将所有其他字段的值连接成一个大字符串,使用空格作为分隔符,然后 对其进行分析和索引,但不进行存储。 (6.0+以后版本将不启用,可以使用自定义字段和映射copy_to参数)
GET my_index/_search
{
"query": {
"match": {
"_all": "searchall"
}
}
}
但是_all这个字段会占用额外的cpu和内存,比如在ELK环境中 应该不会进行全文搜索,所以可以禁止_all(必须在创建索引时候设置,索引已经存在无法修改)
PUT school
{
"mappings": {
"syc": {
"_all": {
"enabled": false
}
}
}
}
2)._field_names:用来存储文档中的所有非空字段的字段名,这个字段常用于exists查询或查询所有包含字段的文档。
GET my_index/_search
{
"query": {
"terms": {
"_field_names": [ "body" ]
}
}
}
GET my_index/_search
{
"query": {
"exists" : { "field" : "body" }
}
}
如果不需要查询字段名称,不需要判断字段名是否存在 可以禁用_field_names,能够提升数据的写入速度(必须在创建索引时候设置,索引已经存在无法修改)
PUT school
{
"mappings": {
"syc": {
"_field_names": {
"enabled": false
}
}
}
}
3.es索引模板
如果每次创建索引都设置mapping setting 有点麻烦,可以设置一个模板 如:所有以index开头的索引名都按照这个模板创建索引
PUT _template/temp1
{
"template": "index*",
"settings": {
"number_of_shards": 5
},
"mappings": {
"type1":{
"_source": {
"enabled": false
}
}
}
}
如果想在上面模板基础上以index-a开头的索引多加一个_all禁用,这样创建以index-a开头的索引时,会优先以模板order大的为准(order默认是0),然后再执行符合index开头的模板
PUT _template/temp2
{
"order":1,
"template": "index-a*",
"settings": {
"number_of_shards": 5
},
"mappings": {
"type1":{
"_all": {
"enabled": false
}
}
}
}