前言
在采用ELK分布式日志采集平台的时候,一般都会采用ES来存储采集的日志信息。日志信息一般都是持续增长的,是典型的时序数据。
如果不对采集的日志数据做生命周期管理,很容易导致单个索引体积持续增长、查询速度越来越慢、过期的日志信息浪费空间等问题。
本节主要介绍如果通过ES中的索引生命周期管理机制ILM来实现对日志数据的管理。
一、说明
es可以用来存储日志,一般日志存储只是短期保存,超过一定时间日志要是能自动删除最好,这样保证索引文档不会过多,查询时效性也能得到保证。
索引的生命周期分为四个阶段:HOT->WARM->COLD->Frozen->DELETE。
上面除了HOT为必须的阶段外,其他为非必须阶段,可以任意选择配置。
因为日志索引只要满足自己删除功能,所以下文只配置了HOT与DELETE阶段。
三步实现完成es生命周期管理:
配置策略(policy)->索引模版(template)->索引(index)
二、实战
1.配置策略
说明:
创建策略log_policy,包含2个阶段hot和delete。
hot阶段:数据写入首先进入hot阶段,包含一个回滚的动作,当记录条数达到3时滚动一次,创建一个新的后备索引。
delete阶段:滚动发送后30s,执行删除动作。
PUT _ilm/policy/log_policy { "policy": { "phases": { "hot": { "actions": { "rollover": { "max_docs":3 } } }, "delete": { "min_age": "30s", "actions": { "delete": {} } } } } }
2.创建索引模板
PUT _index_template/log_template { "index_patterns": ["log"], "data_stream": { }, "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 1, "index.lifecycle.name": "log_policy" } } }
参数说明:
index_patterns 索引匹配模式
data_stream 声明是一个数据流
template 配置模板的settings和mappings属性
index.lifecycle.name 生命周期策略名称,最核心的属性,要和上文定义的生命周期名称保持一致。
3.创建索引模板
方式一:创建并添加数据
创建数据流timeseries,同时向数据流中写入一条数据。数据中必须包含@timestamp字段信息
POST log/_doc { "message": "logged the request", "@timestamp": "1633677855467" }
方式二:仅创建数据流
PUT _data_stream/log
注意⚠️:
1、数据流名称必须和索引模板中的index_patterns匹配。
2、写入的数据中必须包含@timestamp字段信息
4.获取数据流信息
GET _data_stream/log
结果:
generation 第一代,说明还没有执行滚动
template 采用的索引模板为log_template
ilm_policy 采用的生命周期管理策略为log_policy
{ "data_streams" : [ { "name" : "log", "timestamp_field" : { "name" : "@timestamp" }, "indices" : [ { "index_name" : ".ds-log-000001", "index_uuid" : "kRMp8y_2SYyw0mh1Sm713A" } ], "generation" : 1, "status" : "YELLOW", "template" : "log_template", "ilm_policy" : "log_policy" } ] }
5.生命周期信息拉取频率
集群参数indices.lifecycle.poll_interval 用来控制索引生命周期管理检查符合策略标准的索引的频率,默认为10m。
所以在索引生命周期策略中配置的动作和条件,并不是即使触发的,而且定期检查触发。
打个比方:
尽管在策略中设置了hot阶段索引中数据记录大于3条就进行滚动,但其实并不是超过3条就立刻进行滚动。而且ES集群定期检查,当发现索引满足滚动条件后才进行滚动操作。
这里为了方便验证,将检查频率改为10s。
PUT /_cluster/settings { "transient": { "indices.lifecycle.poll_interval": "10s" } }
6.验证
向数据流中写入4条记录,查看数据流生命周期的变化情况。
GET .ds-log-*/_ilm/explain
结果:
{ "indices" : { ".ds-log-000001" : { "index" : ".ds-log-000001", "managed" : true, "policy" : "log_policy", "lifecycle_date_millis" : 1633763085182, "age" : "4.06m", "phase" : "hot", "phase_time_millis" : 1633763085834, "action" : "rollover", "action_time_millis" : 1633763096800, "step" : "check-rollover-ready", "step_time_millis" : 1633763096800, "phase_execution" : { "policy" : "log_policy", "phase_definition" : { "min_age" : "0ms", "actions" : { "rollover" : { "max_docs" : 3 } } }, "version" : 1, "modified_date_in_millis" : 1633762512190 } } } }
添加数据:
PUT log/_bulk?refresh { "create":{ } } {"message": "logged the request1","@timestamp": "1633677862467"} { "create":{ } } {"message": "logged the request2","@timestamp": "1633677872468"} { "create":{ } } {"message": "logged the request3","@timestamp": "1633682619628"} { "create":{ } } {"message": "logged the request4","@timestamp": "1633682619628"}
再次查看索引生命周期情况:
GET .ds-log-*/_ilm/explain
执行结果:
{ "indices" : { ".ds-log-000001" : { "index" : ".ds-log-000001", "managed" : true, "policy" : "log_policy", "lifecycle_date_millis" : 1633763525979, "age" : "11.91s", "phase" : "hot", "phase_time_millis" : 1633763085834, "action" : "complete", "action_time_millis" : 1633763528120, "step" : "complete", "step_time_millis" : 1633763528120, "phase_execution" : { "policy" : "log_policy", "phase_definition" : { "min_age" : "0ms", "actions" : { "rollover" : { "max_docs" : 3 } } }, "version" : 1, "modified_date_in_millis" : 1633762512190 } }, ".ds-log-000002" : { "index" : ".ds-log-000002", "managed" : true, "policy" : "log_policy", "lifecycle_date_millis" : 1633763525996, "age" : "11.89s", "phase" : "delete", "phase_time_millis" : 1633763527252, "action" : "rollover", "action_time_millis" : 1633763536853, "step" : "check-rollover-ready", "step_time_millis" : 1633763536853, "phase_execution" : { "policy" : "log_policy", "phase_definition" : { "min_age" : "0ms", "actions" : { "rollover" : { "max_docs" : 3 } } }, "version" : 1, "modified_date_in_millis" : 1633762512190 } } } }
过段时间再次查看,发现只有ds-log-000002。ds-log-000001已经被删除。
{ "indices" : { ".ds-log-000002" : { "index" : ".ds-log-000002", "managed" : true, "policy" : "log_policy", "lifecycle_date_millis" : 1633763696125, "age" : "1.45m", "phase" : "hot", "phase_time_millis" : 1633763697292, "action" : "rollover", "action_time_millis" : 1633763706877, "step" : "check-rollover-ready", "step_time_millis" : 1633763706877, "phase_execution" : { "policy" : "log_policy", "phase_definition" : { "min_age" : "0ms", "actions" : { "rollover" : { "max_docs" : 3 } } }, "version" : 1, "modified_date_in_millis" : 1633762512190 } } } }
说明:
执行结果说明,随着日志数据的写入,log索引能够自动滚动生存新的索引,滚动操作后超过30s的索引数据会被删除。
注意⚠️:
索引生命周期管理,控制的粒度是索引级别,而不是索引记录级别。
所以采用_bulk指令批量写入数据时,都是向当前的最新的写索引写入数据。不会出现写了3条数据就自动触发滚动然后向新的索引写入第4条的情况。
查询的时候也会发现所有的数据都是在索引ds-log-000001中。
当触发delete阶段的删除操作后,会直接删除满足条件的整个ds-log-000001。不会说只删除3条,还有一条保留在ds-log-000002中的情况。
总结
本文主要介绍了通过索引生命周期管理ILM机制实现对日志数据的生命周期的自动化管理。
1、索引生命周期管理的控制粒度是索引级别,而不是索引记录级别。
2、索引生命周期的触发并不是实时的,而是定时周期触发检查机制,检查频率大小由indices.lifecycle.poll_interval控制。
3、日志数据满足时序数据、连续不断持续增长,只读属性的特点,适合采用数据流保存。