赞
踩
生命周期和模板都是为了优化ES性能的,假如ES是一个小学校,数据是一个个入学的小学生,那么生命周期就是一二三年级,用生命周期制定的规则来管理学生何时进入下一个年级,1年级新学生允许他们随意玩耍,支持数据写入、读取,而6年级的老学生要冷静一点,就只支持读取,以此优化整个ES服务的性能,好钢用到刀刃上。至于模板就是学生课桌,保证每次进来新同学,教室座位顺序不乱。
另:此篇单纯讲解生命周期和模板创建,如果要建立ES集群模式,同步参考下篇文章:Elasticsearch7.×集群搭建,生命周期策略ilm_policy、索引模板template管理
(以下命令行均以ES7.0版本及以上操作,7.0以下涉及到文档操作注意添加“_doc”才能正确执行,另外演示代码块中的中文注释部分删掉后才可以执行,别直接复制粘贴运行呀!)
可以PUT命令创建,也可以在kibana中创建(推荐)
- //设定生命周期
- 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":{
-
- }
- }
- }
- }
- }
- }
查看当前所有模板
GET _template
查看指定模板规则
GET _template/article_ilm_template
创建模板
- //设定索引模板
- PUT /_template/article_ilm_template
- {
- "index_patterns":[
- "article*"(索引匹配规则,满足article为前缀的索引以此模板创建,这个要写好,瞎写或者写复杂了容易导致索引找不到模板)
- ],
- "aliases": {
- "article-template": {}(设置要与索引关联的别名。此别名不同于索引别名)
- },
- "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":{ "max_docs":"50000000"(最大文章数上限) },也可以去kibana中根据内存大小、文档数量、存活时间进行设置。
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也出现这样的问题,首先想一想为什么模板没生效?再看下这个模板
感觉也没问题呀,该有的都有,是因为这个模板权重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*"也能匹配上,所以模板匹配名称不要写太复杂,能匹配上又不会冲突就够了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。