警告
本文最后更新于 2022-07-15 14:26,文中内容可能已过时。
操作步骤
实战为主,没有讲相关概念
- 创建policy,定义不同阶段对应的不同动作
- 创建索引模板并和生命周期策略绑定
- 创建索引
- 测试ILM执行
一、创建policy
这里根据日志的场景来做配置,一般只考虑三个阶段热、暖或冷、删除,下面用了warm没有用cold
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
| PUT _ilm/policy/test-logs
{
"policy": {
"phases": {
"hot": {
"min_age" : "0m",
"actions": {
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "1m",
"actions": {
"set_priority" : {
"priority": 50
},
"allocate" : {
"number_of_replicas": 0,
"require" : {
"box_type": "warm"
}
},
"forcemerge" : {
"max_num_segments": 1,
"index_codec": "best_compression"
}
}
},
"delete": {
"min_age": "2m",
"actions": {
"delete": {}
}
}
}
}
}
|
对于min_age参数的理解: 设置为1m的时候代表索引被创建至少1m才会进入当前阶段执行后续动作,否则还会处于上一个阶段。
hot: 索引被创建后立刻进入热阶段(因为min_age=0ms),进入后执行action,设置索引优先级为100。
warm: 进入warm阶段需要索引的min_age=1m,满足后执行动作,设置索引优先级为50,设置副本为0,索引分配给warm节点(需要自行设置node.attr.box_type),执行ForceMerge操作将segment合并为1个,并且使用best_compression压缩数据,这个比默认的LZ4压缩比更高,但搜索性能差
delete: 等待索引创建至今满足2m(min_age=2m)后,进入delete阶段,执行删除索引操作
二、创建索引模板
下面仅用于测试,生产建议根据自己实际情况修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| PUT _index_template/test-log
{
"index_patterns": [
"test-log-*"
],
"template": {
"settings": {
"index": {
"routing.allocation.require.box_type": "hot",
"lifecycle": {
"name": "test-logs"
},
"number_of_shards": "5",
"number_of_replicas": "1"
}
}
}
}
|
三、创建索引
创建前可以先准备一下测试脚本,方便查看结果
1
| PUT %3Ctest-log-%7Bnow%2Fd%7D%3E
|
四、测试
官方的API
1
| GET test-log-*/_ilm/explain
|
临时写了个脚本用来测试执行是否符合预期,要使用的话需要修改用户名密码,es地址
grep -Ev 'es-0[1-3]'
是过滤我的hot节点,改成过滤你的hot节点即可
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
48
49
50
| #!/bin/bash
index_name="${1:-default}"
index_exits(){
code=$(curl -s -o /dev/null -w %{http_code} -u elastic:xxx 10.10.101.226:9200/$index_name)
[[ $code == 404 ]] && return 1 || return 0
}
watch_hot(){
create_time=$(curl -s -u elastic:xxx "10.10.101.226:9200/$index_name/_settings" | jq -r ".\"$index_name\".settings.index.creation_date" | sed 's#...$##')
echo "$(date -d "@$create_time" '+%F %H:%M:%S') >> 索引被创建"
}
watch_warm(){
while true;
do
curl -s -u elastic:xxx 10.10.101.226:9200/_cat/shards/$index_name | awk '$3=="p"{print $NF}' | grep -Ev 'es-0[1-3]' &> /dev/null
if [[ $? -eq 0 ]]
then
echo "$(date '+%F %H:%M:%S') >> 分片被分配到warm节点"
break
fi
sleep 1
done
}
watch_delete(){
while true;
do
index_exits
if [[ $? -eq 1 ]]
then
echo "$(date '+%F %H:%M:%S') >> 索引被删除"
break
fi
sleep 1
done
}
index_exits
if [[ $? -eq 0 ]]
then
watch_hot
watch_warm
watch_delete
else
echo "索引不存在"
fi
|
执行脚本
1
| sh es_ilm_watch.sh test-log-2022.07.07
|
最终效果
PS:
可能你测试下来会发现并不符合预期,因为我也碰到了。
是什么原因导致的呢?这里需要修改一个参数indices.lifecycle.poll_interval
,这是一个集群级别的配置,用来控制ILM多久检查一次索引是否符合ILM策略的频率,默认是10m。
一般情况不需要修改这个参数,但是我上面设置的参数远小于10m,所以要想测试成功,还需要手动将检查间隔改为1s来测试
1
2
3
4
5
6
| PUT /_cluster/settings
{
"transient" : {
"indices.lifecycle.poll_interval" : "1s"
}
}
|
测试没问题就可以关掉了
1
2
3
4
5
6
| PUT /_cluster/settings
{
"transient" : {
"indices.lifecycle.poll_interval" : null
}
}
|