filebeat占用文件句柄磁盘满


filebeat作为日志采集客户端,相比较于java编写的fluent,有着低功耗的特性。但在一些极端情况下,忽视filebeat的一些特性配置,可能会带来灾难。之前发过一篇关于filebeat内存占用的案例和分析,今天再说下filebeat占用文件句柄、耗费主机磁盘甚至导致磁盘满的案例。


案例1: 某某通信日志系统建设


案例描述:通信公司A日志量很大,需要搭建一套自己的日志管理系统,方式是基于ELK做,日志采集agent使用filebeat(5.3.2)。系统数据规模是400+esc,日增2T。主机端部署了filebeat后,12小时内所有主机触发磁盘使用率告警。排查后发现,filebeat持有大量被deleted的文件句柄不释放,把filebeat进程停掉后磁盘告警恢复,被占用的deleted文件句柄被释放。故障现象见下图:


filebeat占用文件句柄磁盘满


排查过程:

1.检查filebeat日志,发现日志里打了大量的io timeout,表明日志传输受阻,可能日志的生产速度>>采集速度;

2.检查filebeat的registry文件,发现registry里累积了超过1000+没有传输完成的文件;

3.检查所采集文件的滚动策略,约10s钟滚动切换一次,test.log->test.20180816.log;

4.发现宿主机配置crontab每分钟清理所有已被滚动不再更新的日志如test.20180816.log;


结论:

filebeat所采集的日志量大切滚动迅速,filebeat未能及时发送所采集的日志,未传输完成的日志文件的句柄被filebeat长期持有直到传输完成,如此以来原有crontab清理日志的机制失效,加上宿主机的磁盘本来就不富裕,累积一定事件后触发磁盘使用率告警。


根因分析:

默认配置下filebeat对日志的采集是贪心的,只要发现了日志就会坚持把日志采集完,否则会永久持有文件句柄不会“放手”,即使文件被删除。


解决方案:

1. 优化filebeat的配置项, 涉及到的filebeat配置项如下:


### State options

# Files for the modification data is older then clean_inactive the state from the registry is removed
# By default this is disabled.
#clean_inactive: 0

# Removes the state for file which cannot be found on disk anymore immediately
#clean_removed: true

# Close timeout closes the harvester after the predefined time.
# This is independent if the harvester did finish reading the file or not.
# By default this option is disabled.
# Note: Potential data loss. Make sure to read and understand the docs for this option.
#close_timeout: 0

# Defines if prospectors is enabled
#enabled: true


(1)close_inactive: 1m

       没有新日志采集后多长时间关闭文件句柄,默认5分钟,设置成1分钟,加快文件句柄关闭;

(2)close_timeout: 3h

       传输了3h后荏没有传输完成的话就强行关闭文件句柄,这个配置项是解决以上案例问题的key point;

       注意了,开了这个配置项旨在避免以上案例的问题,但是有丢数据的风险哦。鱼与熊掌不可兼得也。


(3)clean_inactive: 72h

        这个配置项也应该配置上,默认值是0表示不清理,不清理的意思是采集过的文件描述在registry文件里永不清理,在运行一段时间后,registry会变大,可能会带来问题。

(4)ignore_older: 70h

        设置了clean_inactive后就需要设置ignore_older,且要保证ignore_older < clean_inactive


完美收官!下期再见!



上一篇:MacOS Java+golang build protoc gRPC 代码生成


下一篇:用浏览器测试几种闭包占用内存的情况