Loading

Elasticsearch:ILM

概述

我们可以通过配置索引生命周期管理ILM(Index Lifecycle Management)策略,来自动管理索引以达到某些效果:

  • Rollover:当索引达到一定大小、创建超过一定时间或文档达到一定数量时,创建一个新索引;
  • Shrink:减少索引中主分片的数量;
  • Force merge:手动触发合并以减少索引中每个分片中的segment数,并释放已删除文档所使用的空间;
  • Freeze:将索引设为只读,最大程度地减少其内存占用量;
  • Delete:永久删除索引,包括其所有数据和元数据。

举例来说,我们要一台ATM的指标数据索引到Elasticsearch中,那么便可以配置相关的ILM策略:

  • 当索引主分片的总大小达到50GB时,创建新索引;
  • 将旧索引标记为只读,并将其缩小为单个分片;
  • 7天后,将索引移至较便宜的硬件上;
  • 30天后,删除索引。

索引的生命周期

索引的生命周期共分为4个阶段(Phase):

  • Hot:索引正在不断更新且可以被搜索到;
  • Warm:索引不再更新但可以被搜索到;
  • Cold:索引不再更新且很少被搜索。虽然依然可以被搜索,但是搜索速度可能会变慢;
  • Delete:索引不再被需要,可以安全地将其删除。

当某阶段中的所有动作均完成(Phase execution)且超过了最小持续时间,ILM便会将索引转换到下一个阶段(Phase transitions)。每个阶段默认的最小持续时间为0,因此我们在配置ILM策略时,一般会为每个阶段设置一个最小持续时间。由于Elasticsearch只能在健康状况为绿色的集群上执行某些清理任务,所以ILM可能会在健康状况为黄色的集群中失效。

ILM控制每个阶段执行动作的顺序和与每个动作相关的索引操作的步骤。

数据层

数据层(data tier)是Elasticsearch集群中保存相同类型索引的节点集合。此处索引的类型是根据其生命周期划分的,因此对应的数据层分别为:Hot tier,Warm tier 和Cold tier。上述三种数据层常用来保存如日志、指标等时间序列数据,而对产品目录、用户档案等需要持久化存储的数据进行生命周期管理是没有意义的,因此Elasticsearch引入Content tier来存放这种长时间内相对恒定的数据。

  • 当文档被直接写入到指定的索引时,它们会无限期地保留在Content tier节点上;
  • 当文档被写入到数据流(data stream)时,它们最初位于Hot tier节点上。随后根据ILM策略移动到其他数据层节点上;
  • 节点位于的数据层可以在elasticsearch.yml文件中的node.roles参数中进行配置;
  • 索引的index.routing.allocation.include._tier_preference参数可以指定索引被分配到的数据层。

阶段动作(Phase action)

每个阶段中支持的动作如下:

                              Hot                              Warm                            Cold                              Delete                      
Set Priority ☑️ ☑️ ☑️
Unfollow ☑️ ☑️ ☑️
Rollover ☑️
Read-Only ☑️ ☑️
Shrink ☑️ ☑️
Force merge ☑️ ☑️
Allocate ☑️ ☑️
Migrate ☑️ ☑️
Freeze ☑️
Searchable Snapshot ☑️ ☑️
Wait For Snapshot ☑️
Delete ☑️

Set Priority

一旦索引进入相应阶段,就为其设置优先级(priority)。如果节点重新启动,将先恢复优先级级别更高的索引。通常,处于Hot阶段的索引应具有最高值,而处于Cold阶段的索引应具有最低值。每个索引的priority默认值为1。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "warm": {
        "actions": {
          "set_priority" : {
            "priority": 50
          }
        }
      }
    }
  }
}

Unfollow

涉及到跨集群复制( Cross-cluster replication),详见跨集群复制(CCR)深度解析

Rollover

当索引达到一定大小、创建超过一定时间或文档达到一定数量时,创建一个新索引并接收文档写入。注意,只有带有别名的索引(index alias)和数据流(data stream)支持Rollover动作。对于带有别名的索引,必须符合下列条件:

  • 索引名称的格式符合^.*-\d+$,如my-index-000001;
  • 参数settings.index.lifecycle.rollover_alias必须被定义。

由于创建的新索引(如my-index-000002)的别名与旧索引相同,因此Elasticsearch引入参数aliases.<alias-name>.is_write_index来表示当前正在写入文档的索引(write index)。例如,初始索引my-index-000001的该参数为true。当它执行Rollover动作后,创建了新索引my-index-000002。那么新索引my-index-000002is_write_index参数为true,旧索引的则自动变为false

我们创建一个索引my-index-000001,别名为my_data。进行下列配置后便能够支持Rollover动作:

PUT my-index-000001
{
  "settings": {
    "index.lifecycle.name": "my_policy",
    "index.lifecycle.rollover_alias": "my_data"
  },
  "aliases": {
    "my_data": {
      "is_write_index": true
    }
  }
}

上文提到,ILM执行Rollover动作的条件为:索引达到一定大小、创建超过一定时间或文档达到一定数量,它们所对应的参数分别为:max_sizemax_agemax_docs。常见的Rollover配置如下:

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover" : {
            "max_age": "7d",
            "max_size": "100GB"
            "max_docs": 100000000
          }
        }
      }
    }
  }
}

当指定多个参数时,只要有一个条件满足,ILM就会执行Rollover动作。

Read-Only

将索引变为只读模式。另外,若想在Hot阶段执行该动作,必须存在Rollover动作的配置,否则将被ILM拒绝。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "warm": {
        "actions": {
          "readonly" : { }
        }
      }
    }
  }
}

Shrink

将索引设置为只读,并将其收缩为一个具有更少主分片数的新索引,新索引的名称为shrink-<original-index-name>。Shrink动作将所有主分片全部分配到一个节点上,并在执行完毕后将与原索引关联的别名转换为新索引。与Read-Only动作相同,若想在Hot阶段执行该动作,必须存在Rollover动作的配置,否则将被ILM拒绝。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "warm": {
        "actions": {
          "shrink" : {
            "number_of_shards": 1
          }
        }
      }
    }
  }
}

Force merge

将索引强制合并为指定的segement数,该操作将使索引变为只读。同样,若想在Hot阶段执行该动作,必须存在Rollover动作的配置,否则将被ILM拒绝。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "warm": {
        "actions": {
          "forcemerge" : {
            "max_num_segments": 1
          }
        }
      }
    }
  }
}

Allocate

更改索引分片分配的节点和副本的个数。可选参数如下:

  • number_of_replicas:索引副本数
  • include:将分片分配到至少有一个参数符合配置的节点上
  • exclude:将分片分配到参数不符合配置的节点上
  • require:将分配分配到参数全部符合配置的节点上
PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "warm": {
        "actions": {
          "allocate" : {
            "number_of_replicas": 2,            // 分片的副本数更改为2
            "include" : {
              "box_type": "cold"                // elasticsearch.yml文件中的node.attr.box_type字段
            },
            
         
        }
        }
      }
    }
  }
}

Migrate

在生命周期的阶段转换时,通过更新索引设置中的index.routing.allocation.include._tier_preference参数,将索引移动到与当前阶段对应的数据层节点上。

  • 如果Warm和Cold阶段中没有指定Allocate动作,那么ILM将会自动执行Migrate动作;
  • 如果在Allocate动作中仅修改了分片副本数,那么ILM会在执行Migrate动作前减少副本数;
  • 可以将enabled参数设置为false从而禁用ILM自动执行的Migrate动作。

Freeze

Freeze动作将索引的内存占用量降低到最低,该索引被搜索时的响应变慢(原理参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/frozen-indices.html)。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "cold": {
        "actions": {
          "freeze" : { }
        }
      }
    }
  }
}

Searchable Snapshot

为索引拍摄快照,并将其挂载为可搜索快照。想在Hot阶段执行该动作,必须存在Rollover动作的配置,否则将被ILM拒绝。若在Hot阶段执行Searchable Snapshot,则在后续阶段中无法定义任何Shrink, Force merge和Freeze动作。默认情况下,当索引在Delete阶段被删除后,相应的快照也随之删除。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "cold": {
        "actions": {
          "searchable_snapshot" : {
            "snapshot_repository" : "backing_repo"    // 指定存储快照的仓库为backing_repo
          }
        }
      }
    }
  }
}

Wait for snapshot

等待指定的快照生命周期管理SLM(Snapshot Lifecycle Management)策略执行后再删除索引,这样可以确保已删除索引有快照可用。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "delete": {
        "actions": {
          "wait_for_snapshot" : {
            "policy": "slm-policy-name"    // 名为slm-policy-name的SLM策略执行完毕后才会删除索引
          }
        }
      }
    }
  }
}

Delete

永久删除索引。如果该索引执行过Searchable Snapshot动作且delete_searchable_snapshot参数为false,则索引被删除后快照依然保留。

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "delete": {
        "actions": {
          "delete" : { }
        }
      }
    }
  }
}

为索引配置ILM

在Elastic Cloud创建ILM策略是非常方便的:Tutorial: Customize built-in ILM policies

而将已创建的ILM策略关联到索引的方法有以下几种:

  • 通过在索引模板中添加ILM策略来关联索引
PUT _index_template/my_template
{
  "index_patterns": ["my-index-*"],                           
  "template": {
    "settings": {
      "index.lifecycle.name": "my_ilm_policy",       // 将名称开头为"my-index-"的索引关联到ILM策略my_ilm_policy
      "index.lifecycle.rollover_alias": "test-alias" 
    }
  • 直接修改现有索引的设置
PUT my-index-*/_settings 
{
  "index": {
    "lifecycle": {
      "name": "my_ilm_policy"                   // 将名称开头为"my-index-"的索引关联到ILM策略my_ilm_policy
    }
  }
}
  • 在创建新索引时直接在设置中指定ILM策略
PUT new-index
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1,
    "index.lifecycle.name": "my_ilm_policy"     // 将new-index关联到ILM策略my_ilm_policy
  }
}
posted @ 2021-03-12 01:03  koktlzz  阅读(1238)  评论(0编辑  收藏  举报