ElasticSearch日志系统 缓存管理及性能优化

本文介绍了如何通过Filebeat配置实现日志收集优化,如设置`ignore_older`避免导入旧日志,限制单条日志大小和包含特定内容的日志,以及调整轮询频率等参数减少延迟。同时,文章讲解了定期清理ElasticSearch中过期日志索引的方法,包括编写删除脚本并设置定时任务,确保资源的有效利用。

目标:1. 导入时根据日期判断日志是否存入ElasticSearch中

2. 定期清除过期(老)日志本地缓存

导入时过滤老日志

Filebeat将日志导入时,会有一些导入范围的问题。一些过久之前的日志导入ELK中显得意义不大且浪费计算机资源。通过指定路径下通过通配符号匹配的文件,而又要控制该日志文件对应的日期不要过久,我们可以在收集器 Filebeat 中进行设置从而达到只收集近N天日志的目的。

我们在filebeat.yml配置文件中,Inputs下加入:

ignore_older : 240h

指定 Filebeat 忽略指定时间段以外修改的日志内容,比如240h(十天)或5m(五分钟)

注意:这个ignore_older是针对文件,如果文件最近一次的更新时间超过设定的时间,启动filebeat的时候,就不会去读那个文件,不过如果启动后那个文件又有更新,就会采集更新之后的部分,主要适用用监控一个目录下多个文件的时候。

max_bytes: 204800

限制单条日志的大小为200KB,但在实际过程中,Filebeat 会将 line limit 调整为 4 倍 max_bytes,比该数值大者跳过。

include_lines: ['INFO', 'WARN', 'ERROR']

在实际日志中,偶尔会产生一些“垃圾记录”,比如无标识日志,开发过程中未删除的辅助开发日志,报错日志等等,会占用大量的空间资源,以及导致传送到 Logstash 后,过滤器无法解析而造成系统崩溃。该参数规定单条日志中包括指定中的其中一种字符串,否则跳过。此处指定的为标明日志类型的日志,包括“信息”“警告”“错误”,有该信息的日志才被录入。

Filebeat 并没有采用 Inotify 这样的机制来监听目标文件/目录的状态变化,而是采用非常古老但是实用的方式轮询来采集日志文件。每隔一段时间,Filebeat 就会检查目标路径下是否有可供采集的文件,对于已采集的文件,是否有新的写入。正是由于这个“每隔一段时间”,应用程序写入日志后,采集的工作往往没有接踵而来。之间的时间差就是延迟的主要来源。这些时间上的间隔,为服务器的降低了小压力,使得日志文件读写不那么频繁。

输入的延迟,FIlebeats采用了以下几个参数来控制轮训的行为:

在filebeat.yml配置文件中,Inputs下加入:

#影响多长时间检查一次目标路径下是否有新增文件的出现。虽然这个默认是 10 秒,不过除非发生了 log rotation,一般不会出现新的日志文件。 (最差情况下延迟了10秒才发现新的文件)

scan_frequency: 10s 

#当 Filebeat 采集完一个文件的日志(一直读到文件结尾)时,它会隔一段时间再看看有没有新的日志 append 进来

backoff: 1s 

max_backoff: 10s

#如果 Filebeat 再次查看时依然没有新的日志,那么它会隔 backoff * backoff_factor 也就是默认 2 秒之后才继续查看,直到整个 backoff 的时间达到 max_backoff 也即是 10 秒为止

backoff_factor: 2

除了日志输入部分有延迟,FIlebeats 在做通用的处理时也会引入延迟。这是因为 FIlebeats 会把 event 给缓存到队列中,来追求更高吞吐量的成批输出。

queue:

  mem:

    events: 4096

    flush.min_events: 2048

    flush.timeout: 1s

默认情况下,filebeat 只会在以下两个条件中任一成立时才会刷洗缓存队列:

当前缓存的事件达到 flush.min_events

上一次刷新缓存的操作到现在超过了 flush.timeout

当然,queue 带来的延迟最多也就 1 秒,比起 backoff 带来的开销并不大。

过了“通用的处理”,就是“不同的输出”了。这里也有一点批处理。大部分的输出类型中有 bulk_max_size 这一项,控制每次输出时批次的大小。不过考虑到 bulk_max_size 的值往往小于 queue 的缓存,所以带来的延迟可以忽略。

如果你选择减少 queue 的缓存设置,比如减少 flush.timeout 或者 flush.min_events,那么可能会带来一个意想不到的问题。

filebeat 每完成一个批次的输出后,会更新采集进度文件(在 7.5 里面是 data/data/registry/filebeat/data.json )。如果没有及时更新这一文件,一旦 filebeat 崩溃了,就会丧失采集进度,导致日志的重复采集。如果把 queue 调小了,就会导致一个批次也随之变小,进而让进度文件的保存变得更加频繁了。由于对进度文件的写入都是重新写整个文件,且每次写入都会调用 fsync 保障写入的数据能够落到磁盘上,所以这个操作耗费的时间并不短。

filebeat.registry.flush: 0s

默认情况下,就是每完成一批更新一次进度。但是我们可以设置成每隔几秒更新一次。由于 filebeat 正常退出时也会更新进度文件,另外毕竟这也不是需要保障数据一致性的数据库,所以一般情况下不用太担心丢失几秒的进度。

定期清除日志缓存

需要删除历史日志索引,我们可以执行命令发送请求到 ElasticSearch 提供的 API 即可删除指定的日志索引(即删除该索引对应的缓存文件)

例如:

-XDELETE 'http://127.0.0.1:9200/日志索引名

在我们的 Logstash 中,发送日志至 ElasticSearch 服务器时,以当时日期作为日志索引的命名后缀。

由此,我们在日志生成机中,使用定时任务,定时触发脚本,通过脚本发送根据日期变化的删除索引 API 指令到 ElasticSearch即可。

创建自动删除脚本

在 ElasticSearch 服务机根目录下的opt文件中,创建elk目录,专门存放关于日志系统的相关脚本,编辑 es-index-clear.sh 脚本文件:

mkdir /opt/elk

vim /opt/elk/es-index-clear.sh

在脚本文件中,写入以下脚本内容:

KEEP_DAYS=7  #保留近 N 天

function get_todelete_days()  

{

    # declare -A DAY_ARR

    # DAY_ARR=""

    for i in $(seq 1 10);  # 删除前 N的所有天到 前N+10天的索引

    do

        THIS_DAY=$(date -d "$(($KEEP_DAYS+$i)) day ago" +%Y.%m.%d)

        DAY_ARR=( "${DAY_ARR[@]}" $THIS_DAY)

    done

    echo ${DAY_ARR[*]} 

}

TO_DELETE_DAYS=(`get_todelete_days`)  # 返回数组的写法

for day in "${TO_DELETE_DAYS[@]}"

do

    echo "$day will be delete"  

    curl --user elastic:对应密码 -XDELETE 'http://127.0.0.1:9200/logstash_'${day}   #执行相应的删除动作

done

经测试,通过执行该脚本文件能成功删除指定日期范围内的索引

添加定时任务

在控制台输入

crontab -e

进入crontab任务文件,添加内容:

30 1 * * * /opt/elk/es-index-clear.sh

保存后,即添加了定时任务。每天1点30分运行指定路径下该脚本文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值