elasticsearch lifecycle management

elasticsearch lifecycle management

索引生命周期管理功能是elasticsearch 在 6.7.0 引入的。此功能主要是用于管理时间序列数据的索引。

对于时间序列的索引,生命周期有4个阶段:

  1. hot: 索引被频繁写入和查询
  2. warm: 索引不再写入,但是仍在查询
  3. cold: 索引很久不被更新,同时很少被查询。但现在考虑删除数据还为时过早,仍然有需要这些数据的可能,但是可以接受较慢的查询响应。
  4. delete: 索引不再需要,可以删除。

一个index将在热的阶段开始,然后是温,冷,最后是删除阶段,生命周期策略控制索引如何在这些阶段中转换以及在每个阶段对索引执行的操作。

创建生命周期策略

下面是一个创建生命周期的例子,策略不一定需要为索引配置每个阶段,该策略将在写入的索引达到50GB或已使用7天后对其进行滚动。这些条件之一为真时,将发生翻转。索引将在滚动90天后被删除。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
PUT _ilm/policy/full_policy      //full_policy 策略名
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": { // 滚动索引
"max_age": "7d",
"max_size": "50G"
},
"set_priority": {
"priority": 100 // 优先加载
}
}
},
"warm": {
"min_age": "30d",
"actions": {
"forcemerge": {
"max_num_segments": 1 // force merge
},
"shrink": { // 压缩shard
"number_of_shards": 1
},
"allocate": {
"number_of_replicas": 2 // 分配副本
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "60d",
"actions": {
"freeze" : {} // 冷冻
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}

时间参数

索引根据时间参数min_age进入生命周期阶段,若未设置,默认是0ms。min_age通常是从创建索引的时间开始计算,如果索引是通过滚动索引生成的,那么min_age是从索引滚动开始计算。注意,在检查min_age参数并进入下一个阶段前,当前阶段的操作必须完成。

默认情况下,索引生命周期管理每10分钟检查一次符合策略标准(例如min_age)的索引。您可以使用集群设置 indices.lifecycle.poll_interval 来控制检查频率。

action

阶段\action 优先级设置 取消跟随 滚动索引 分片分配 只读 强制段合并 收缩索引 冻结索引 删除
hot × × × × × ×
warm × × ×
cold × × × × ×
delete × × × × × × × ×

优先级设置

这个action等同于设置索引属性index.priority的值。具有较高优先级的索引将在节点重启后优先恢复。通常,热阶段的指数应具有最高值,而冷阶段的指数应具有最低值。未设置此值的指标的隐含默认优先级为1。索引的优先级。必须为0或更大。也可以设置为null以删除优先级。

1
2
3
4
5
{
"set_priority" : {
"priority": 50
}
}

滚动索引

使用滚动索引有几个注意事项:

  1. 索引命名必须^.*-\\d+$
  2. 索引必须设置index.lifecycle.rollover_alias为滚动的别名。索引还必须是别名的写入索引。
1
2
3
4
5
6
7
8
9
10
11
12
PUT logs-000001
{
"settings": {
"index.lifecycle.name": "my_policy",
"index.lifecycle.rollover_alias": "logs_write"
},
"aliases": {
"logs_write": {
"is_write_index": true // true表示索引是别名的当前写入索引。
}
}
}
名称 描述
max_size 索引所有主分片最大存储大小
max_docs 滚动前索引要包含的最大文档数
max_age 索引创建后的最长时间

只有当一个条件满足后,rollover action 才会结束。这会阻塞其他进行中的生命周期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PUT /_ilm/policy/rollover_policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50G"
}
}
},
"delete": {
"min_age": "1d",
"actions": {
"delete": {}
}
}
}
}
}

上面例子中的policy,将会在索引滚动一天后,删除索引。而不是在创建一天后删除。

分片分配

通过“分配”操作,您可以指定允许哪些节点托管索引的分片并设置副本数。

名称 描述
number_of_replicas 要分配给索引的副本数
include 为具有至少一个属性的节点分配索引
exclude 为没有任何属性的节点分配索引
require 为具有所有属性的节点分配索引

只读索引

该操作实际上是修改了索引的index.blocks.write设置为true。

1
2
3
4
5
6
7
8
9
10
11
12
PUT _ilm/policy/my_policy
{
"policy": {
"phases": {
"warm": {
"actions": {
"readonly" : { }
}
}
}
}
}

强制合并

使用强制合并时,索引将变成只读。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PUT _ilm/policy/my_policy
{
"policy": {
"phases": {
"warm": {
"actions": {
"forcemerge" : {
"max_num_segments": 1 //合并后的shard里的lucene segments数,
}
}
}
}
}
}

收缩索引

使用收缩索引时,索引将变成只读。收缩索引API允许您将现有索引缩减为具有较少主分片的新索引。目标索引中请求的主分片数必须是源索引中分片数的一个因子。如果索引中的分片数是素数,则只能缩小为单个主分片。

新索引将有一个新名称:shrink-<origin-index-name>。因此,如果原始索引称为“logs”,则新索引将命名为“shrink-logs”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PUT _ilm/policy/my_policy
{
"policy": {
"phases": {
"warm": {
"actions": {
"shrink" : {
"number_of_shards": 1
}
}
}
}
}
}

冻结索引

为了使索引可用且可查询更长时间但同时降低其硬件要求,它们可以转换为冻结状态。一旦索引被冻结,它的所有瞬态分片内存(除了映射和分析器)都会被移动到持久存储。

1
2
3
4
5
6
7
8
9
10
11
12
PUT _ilm/policy/my_policy
{
"policy": {
"phases": {
"cold": {
"actions": {
"freeze" : { }
}
}
}
}
}

注意冻结一个索引会close并reopen,这会导致短时间内不可用,集群会变red,直到这个索引的分片分配完毕。

删除索引

在cold 阶段删除索引。

1
2
3
4
5
6
7
8
9
10
11
12
PUT _ilm/policy/my_policy
{
"policy": {
"phases": {
"delete": {
"actions": {
"delete" : { }
}
}
}
}
}

应用策略

  1. 直接应用到索引
1
2
3
4
5
6
7
8
PUT test-index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "my_policy"
}
}

不要将create index API与定义rollover操作的策略一起使用。如果这样做,作为滚动结果的新索引将不会继承该策略。始终使用索引模板来定义具有滚动操作的策略。

  1. 应用到模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PUT _template/my_template
{
"index_patterns": ["test-*"],
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "my_policy",
"index.lifecycle.rollover_alias": "test-alias" // rollover 别名
}
}


PUT test-000001
{
"aliases": {
"test-alias":{
"is_write_index": true
}
}
}

使用策略管理滚动索引

滚动操作使您可以根据索引大小,文档数或使用期限自动滚动到新索引。触发翻转后,将创建新索引,写别名将更新为指向新索引,所有后续更新都将写入新索引。

与基于时间的滚动相比,基于大小,文档数或使用期限滚动至新索引更可取。在任意时间翻转通常会导致许多小的索引,这可能会对性能和资源使用产生负面影响(实际在使用中,基于使用期限的滚动也会产生文档数为空的新滚动索引,如果不是对时间有要求,从性能考虑,最好是基于大小来管理滚动)。

可以通过指定一个或多个过渡参数来控制何时触发过渡动作。一旦满足任何条件,就执行翻转。由于会定期检查标准,因此索引可能会略微超出指定的阈值。要控制检查标准的频率,请指定indices.lifecycle.poll_interval群集设置。

通过过渡创建的新索引不会自动继承旧索引使用的策略,并且默认情况下不会使用任何策略。因此,强烈建议通过索引模板(包括过渡别名设置)为索引应用策略 ,该模板指定要为每个新索引使用的策略。

索引翻转后,索引生命周期管理将使用翻转操作的时间戳而不是索引创建时间来评估何时将索引移至下一个阶段。对于已滚动的索引,min_age 为阶段指定的标准与索引的滚动时间有关。

index.lifecycle.indexing_complete 告诉索引生命周期管理该索引是否已经翻转。如果将其设置为true,则表明该索引已经被翻转,不需要再次翻转。因此,索引生命周期管理将跳过在关联的生命周期策略中为此索引配置的任何rollover操作。如果需要对正常的生命周期策略进行例外处理,并手动将别名切换到其他索引,但是又不想从索引生命周期管理中完全删除该索引,则这很有用。成功完成rollover操作后,ILM 会自动将此设置为true。但是,如果从索引中删除了策略,它将被删除。

如果索引上index.lifecycle.indexing_complete设置为true,则索引生命周期管理将不会对其进行滚动,但是索引生命周期管理将验证该索引不再是所指定别名index.lifecycle.rollover_alias的写入索引。如果缺少该设置,或者索引仍然是该别名的写入索引,则该索引将移至错误步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /_aliases
{
"actions" : [
{
"add" : {
"index" : "log-000002",
"alias" : "log",
"is_write_index" : false
}
}
]
}

PUT log-000002/_settings
{
"settings": {
"index.lifecycle.indexing_complete":true
}
}

更新策略

  1. 如果没有index应用这份策略,那么我们可以直接更新该策略。后续应用了这个策略的索引,将直接使用最新版本的策略。
  2. 如果有index应用了这份策略,那么当前正在执行的阶段不会同步修改,当当前阶段结束后,会进入新版本策略的下个阶段。
  3. 如果更换了策略(修改了index.lifecycle.name对应的值),当前正在执行的阶段不会变化,在结束当前阶段后,将会由新的策略管理下一个生命周期。

策略进度检查

ES 提供了API 用于检查生命周期的进度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
GET /myindex/_ilm/explain
{
"indices": {
"datastream-000001": {
"index": "datastream-000001",
"managed": true, // 受 ILM 管理
"policy": "datastream_policy", // 应用的生命周期策略
"lifecycle_date_millis": 1538475653281,
"age": "30s", // 索引的时间
"phase": "hot", // 当前所在生命周期
"phase_time_millis": 1538475653317,
"action": "rollover", // 当前执行的action
"action_time_millis": 1538475653317,
"step": "attempt-rollover", // 当前步骤
"step_time_millis": 1538475653317,
"phase_execution": {
"policy": "datastream_policy",
"phase_definition": { // 所在生命周期定义
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "30d"
}
}
},
"version": 1, // 应用的生命周期策略版本
"modified_date_in_millis": 1539609701576
}
}
}
}

详细说明见explain api

策略错误处理

当在生命周期策略处理中出现异常时,会进入错误阶段,停止策略的执行。

1
GET /myindex/_ilm/explain

使用上述API可以看到异常的原因,当解决这个问题,并更新策略后,可以通过下面的API进行重试:

1
POST /myindex/_ilm/retry

ilm的启用禁用

ilm的状态查看:

1
2
3
4
GET _ilm/status
{
"operation_mode": "RUNNING"
}
Name Description
RUNNING Normal operation where all policies are executed as normal
STOPPING ILM has received a request to stop but is still processing some policies
STOPPED This represents a state where no policies are executed

开启和关闭:

1
2
POST _ilm/start
POST _ilm/stop
-------------本文结束感谢您的阅读-------------
坚持分享,您的支持将鼓励我继续创作!
0%