Elasticsearch生命周期策略ilm_policy、索引模板template管理(一)

生命周期和模板都是为了优化ES性能的,假如ES是一个小学校,数据是一个个入学的小学生,那么生命周期就是一二三年级,用生命周期制定的规则来管理学生何时进入下一个年级,1年级新学生允许他们随意玩耍,支持数据写入、读取,而6年级的老学生要冷静一点,就只支持读取,以此优化整个ES服务的性能,好钢用到刀刃上。至于模板就是学生课桌,保证每次进来新同学,教室座位顺序不乱。

另:此篇单纯讲解生命周期和模板创建,如果要建立ES集群模式,同步参考下篇文章:Elasticsearch7.×集群搭建,生命周期策略ilm_policy、索引模板template管理

(以下命令行均以ES7.0版本及以上操作,7.0以下涉及到文档操作注意添加“_doc”才能正确执行,另外演示代码块中的中文注释部分删掉后才可以执行,别直接复制粘贴运行呀!

一、生命周期策略管理 

可以PUT命令创建,也可以在kibana中创建(推荐)

PUT创建方式

//设定生命周期
PUT /_ilm/policy/article_ilm_policy(自定义生命周期名称)
{
    "policy":{
        "phases":{
            "hot":{
                "actions":{
                    "rollover":{
                        "max_docs":"50000000"(最大文章数上限)
                    }
                }
            },
            "warm":{
                "min_age":"15d",
                "actions":{
                    "allocate":{
                        "include":{
                            "box_type":"warm"
                        },
                        "number_of_replicas":0
                    },
                    "forcemerge":{
                        "max_num_segments":1
                    }
                }
            },
            "cold":{
                "min_age":"30d",
                "actions":{
                    "allocate":{
                        "include":{
                            "box_type":"cold"
                        }
                    }
                }
            },
            "delete":{
                "min_age":"60d",
                "actions":{
                    "delete":{

                    }
                }
            }
        }
    }
}

kibana编辑/创建 生命周期策略

Elasticsearch生命周期策略ilm_policy、索引模板template管理(一)_第1张图片

二、索引模板管理

查看当前所有模板

GET _template

查看指定模板规则

GET _template/article_ilm_template

创建模板

//设定索引模板
PUT /_template/article_ilm_template
{
    "index_patterns":[
        "article*"(索引匹配规则,满足article为前缀的索引以此模板创建,这个要写好,瞎写或者写复杂了容易导致索引找不到模板)
    ],
    "aliases": {
      "article": {}(规定新索引的别名,这里有bug,如果写上这个索引别名,但滚动索引会跟下面rollover_alias重复冲突,引起rollover失败,建议不写这个配置,第一个索引采用手动创建别名)
    },
    "settings":{
        "number_of_shards":9,(主分片数)
        "number_of_replicas":1,(副本数)
        "index.lifecycle.name":"article_ilm_policy",(规定索引遵从哪个生命周期)
        "index.lifecycle.rollover_alias":"article",(规定rollover索引别名)
        "index.routing.allocation.include.box_type":"hot",(让所有符合命名规则索引的 Shard 都将被分配到 Hot Nodes 节点上,如果不需要指定分配,可以去掉)
    },
     "mappings":{
        "properties":{
            "id":{
                "type":"integer"
            },
            "appChannel":{
                "type":"long"
            },
            "channleId":{
                "type":"integer"
            },
            "content":{
                "type":"text",
                "index":false,
                "copy_to":[
                    "fulltext"
                ]
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd'T'HH:mm:ss.SSSZZ||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            },
            "wordCount":{
                "type":"keyword",
                "index":false
            }
        }
    }
}

当然模板中settings不仅下面这些属性配置,还可指定分词器analysis、过滤器等 

        "index.max_ngram_diff":5,
        "analysis" : {
          "analyzer" : {
            "ngram_analyzer" : {
              "tokenizer" : "ngram_tokenizer"
            }
          },
          "tokenizer" : {
            "ngram_tokenizer" : {
              "filter" : [
                "lowercase"
              ],
              "min_gram" : "1",
              "type" : "ngram",
              "max_gram" : "3"
            }
          }
        }

 

三、别名

说一下别名问题,我们代码程序查询、添加文档到索引时,需要指定索引名称,但是这种方式扩容的索引需要统一的别名,根据别名进行操作,查询别名就会查询别名下的所有索引,同样添加文档到别名,就会添加到此别名下最新索引,当然最新索引必须满足"is_write_index":true也就是支持写入,集群只能规定一个写入的索引,如果不是请注意修改调整。

//写入和读取,都是根据共同的别名article进行的,他们别名一样
//设置别名,如果别名不对的话,就无法查询到此article-test索引
//设置允许写入写入"is_write_index":true ,否则无法写入数据,集群只能规定一个写入的索引

//创建索引,指定别名
PUT article-test(需要修改的索引)
{
    "aliases":{
        "article(别名)":{
            "is_write_index":true
        }
    }
}

//另一种写法,修改别名,指定索引:

POST /_aliases
{
    "actions":[
        {
            "add":{
                "index":"article-test",(需要修改的索引)
                "alias":"article",(别名)
                "is_write_index":true
            }
        }
    ]
}

四、Rollover 新建索引扩容

当时一个索引达到生命周期所规定的扩容条件后就可以进行Rollover 扩容,我上面创建的生命周期规定的是"rollover":{                "max_docs":"50000000"(最大文章数上限) },也可以去kibana中根据内存大小、文档数量、存活时间进行设置。

Elasticsearch生命周期策略ilm_policy、索引模板template管理(一)_第2张图片

Rollover不是完全自动的,还是需要命令简单执行,如果达到完全自动的方式,可以通过程序编写定时任务或者服务器定时脚本执行命令。

POST article(别名)/_rollover/
{
  "conditions": {
    "max_docs":  2
  }
}

或者

POST article(别名)/_rollover/article-05(指定rollover后的索引名称)
{
  "conditions": {
    "max_docs":  50000000
  }
}


或者强行rollover

POST article(别名)/_rollover/

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

扩展问题:

公司ES有个article索引,设定索引生命周期:5千万文档后Rollover新建下一个索引。初始索引名为article-01,后续新增的依次为article-02,article-03等,他们的别名都叫article,这样查询和写入索引都按照别名进行。

有一天公司突然发现从Kibana的discover查不到ES中article数据了,程序中也不能查到最新的数据,但根据id细查还是能查到,并且也有文档数据进来。

原因:

排查后发现是自动新增的索引article-04中的字段crawTime不是data类型,而是text,导致discover设置的根据crawTime为条件的查询失效,并且导致程序查询中无法根据crawTime过滤筛选查询,也就查不到最新article-04中的数据。

根本原因:

索引模板未生效,新索引没有匹配到模板,也就没有预先设定好所需要的字段类型。

解决办法:

首先解决现有问题让网站系统恢复了,再修改模板,避免再出现此问题。

 首先已经创建的索引字段是无法更改的,所以要新建索引article-test,并为其创建好正确的字段类型,将article-04数据转移到article-test。先设定新索引字段类型

//设置当前索引的字段及字段类型
PUT article-test/_mapping/_doc
{
    "_doc":{
        "_source":{
            "enabled":true
        },
        "_routing":{
            "required":true
        },
        "properties":{
            "id":{
                "type":"integer"
            },
            "appChannel":{
                "type":"long"
            },
            "channleId":{
                "type":"integer"
            },
            "content":{
                "type":"text",
                "index":false,
                "copy_to":[
                    "fulltext"
                ]
            },
            "createTime":{
                "type":"date",
                "format":"yyyy-MM-dd'T'HH:mm:ss.SSSZZ||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            },
            "wordCount":{
                "type":"keyword",
                "index":false
            }
        }
    }
}

转移数据到新索引

//转移数据,从article-04到article-test
POST _reindex                   
{
  "source": {
    "index": "article-04",
    },
  "dest": {
    "index": "article-test"
  }
}

删除原出错的索引,如果有必要的话

DELETE article_04

由于别名的存在,所以article-test就已经可以代替article-04使用了,但我是强逼症,就想恢复到原样,所以重新创建了article-04再重复上述转移数据的步骤折腾回去。

数据和功能恢复了,下一步修复模板,避免article-05也出现这样的问题,首先想一想为什么模板没生效?再看下这个模板

Elasticsearch生命周期策略ilm_policy、索引模板template管理(一)_第3张图片感觉也没问题呀,该有的都有,是因为这个模板权重order太低了吗,有重名的模板?被其他模板取代了吗?那我重新编辑模板,添加权重"order":10000试试,发现也不行,那看来就是这个模板本身的问题了。

{
    "order":10000,(添加权重)
    "index_patterns":[
        "article-*"
    ],
    "settings":{
        "number_of_shards":9,
        "number_of_replicas":1,
        "index.lifecycle.name":"article_ilm_policy",
        "index.lifecycle.rollover_alias":"article",
        "index.routing.allocation.include.box_type":"hot",
        "analysis":{
            "analyzer":{
                "ngram_analyzer":{
                    "tokenizer":"ngram_tokenizer"
                }
            },
            "tokenizer":{
                "ngram_tokenizer":{
                    "type":"ngram",
                    "min_gram":1,
                    "max_gram":3,
                    "filter":[
                        "lowercase"
                    ]
                }
            }
        }
    },
    "properties":{
        "websiteId":{
            "type":"integer"
        },
        "weixinBiz":{
            "type":"keyword"
        },
        "wordCount":{
            "type":"keyword",
            "index":false
        }
    }
}

那我匹配简单的名称行不行,名称匹配不搞那么复杂了,将 "article-*换成 "a*",然后去创建索引article-test01发现成功了!!!能够按照模板规则创建索引的属性等信息。

"index_patterns":[
        "a*"
    ]

结果就是证明索引根据名称没匹配到期望的模板。最后将匹配规则 "article-*"去掉横杠"-"变为"article*"也能匹配上,所以模板匹配名称不要写太复杂,能匹配上又不会冲突就够了。

你可能感兴趣的:(Elasticsearch,es,ES,Kibana)