概述
文章目录
- 一. 起因
- 二. 方案
- 三.代码
- 四. 执行
一. 起因
集群环境,挂载到/
目录下的磁盘空间普遍较小.
即使在有监控的情况下,也很容易出现磁盘空间占用过高.
甚至磁盘写满导致节点故障的场景:No space left on device
如下图:
主要痛点有两点:
- 磁盘问题发现处理往往不够及时,风险很大
- 人工清理磁盘费时费力,应该把精力投入到更有意义的事情上去
因此决定开发一套自动清理磁盘空间的机制,减少运维操作,并降低生产风险
二. 方案
经分析发现:
- 核心数据盘空间足够,只有挂载根目录为
/
的磁盘资源紧张 - 磁盘空间紧张的罪魁祸首在于
/var/log
(用于存放集群各个服务的日志)目录过于臃肿,且增量数据较大 - 其它的目录存在一些关键文件.不能随意清理
所以在我们的业务场景下,自动清理/var/log
目录下的文件是最好的解决方案
清理策略如下:(默认策略)
- 定期自动清理(12小时清理一次 crontab)
- 磁盘空间占用超过70%才进行清理
- 清理超过150M的大文件(但最近3天内修改过的文件不清理,否则可能影响问题定位)
- 清理最近15天没有修改过的日志文件
三.代码
包含两个脚本:
clear_log.sh
: 主要用于清理日志的脚本分发,以及crontab的配置(通过ssh)
clear_host_log.sh
:用于在各个节点上按照二. 方案
中提供的策略清理日志
clear_log.sh
脚本
#!/bin/bash
log_path=~/emr/logs
log_file=$log_path"/clear_log.log"
script_path=~/emr/script
time=`date +%Y-%m-%d %H:%M:%S`
check_path() {
if [ ! -d "$log_path" ];then
echo "Create log directory!"
mkdir -p "$log_path"
echo "$time Create log file" >> $log_file
fi
if [ ! -d "$script_path" ];then
echo "Create script directory!"
mkdir -p "$script_path"
fi
}
# 我这里的/etc/hosts文件格式类似如下: ip hostname.***.com hostname 中间以空格分割,所以这里采用该方案解析
check_host() {
echo "$time download clear_host_log.sh" >> $log_file
hosts=$(cat /etc/hosts | cut -d ' ' -f 2)
for host in $hosts
do
ssh $host -p $ssh_port "mkdir -p $script_path"
ssh $host -p $ssh_port "mkdir -p $log_path"
ssh $host -p $ssh_port "rm -rf $script_path/clear_host_log.sh"
scp -P $ssh_port clear_host_log.sh root@$host:$script_path/
ssh $host -p $ssh_port "chmod +x $script_path/clear_host_log.sh"
ssh $host -p $ssh_port "crontab -l > /tmp/crontab.conf && echo '* */12 * * * sh -x $script_path/clear_host_log.sh 70 150 15 >> $log_path/clear_host_log.log' >> /tmp/crontab.conf && crontab /tmp/crontab.conf && rm -f /tmp/crontab.conf"
done
}
main() {
# script parameters
# Parameter Description: Param1: github branch, param2: github username, param3: github token, param4: date (format :yyyymmdd)
ssh_port=$1
echo "Script parameters is: " $@
if [ $# -lt 1 ];then
echo "Wrong number of parameters. Please check"
exit 1
fi
check_path
check_host
}
main $@
clear_host_log.sh
脚本代码
#!/bin/bash
log_path=~/emr/logs
log_file=$log_path"/clear_host_log.log"
time=`date +%Y-%m-%d %H:%M:%S`
check_path() {
if [ ! -d "$log_path" ];then
echo "Create log directory!"
mkdir -p "$log_path"
echo "$time Create log file" >> $log_file
fi
}
clear_log() {
# 获取输出倒数第二列,也就是磁盘占用百分比(不包含百分号)
percent=`df -k | grep -w / |awk '{print int($5)}'`
# 磁盘占比超过设定阈值时才进行清理
if [ "$percent" -gt "$threshold" ];then
echo "$time begin clear disk log" >> $log_file
# 1. 第一种场景: 清理最后变更时间距今超过3天的大文件(这是为了防止清理到正在用的日志文件,导致生产定位问题失败)
files=`find /var/log -size +150`
for file in $files
do
time_difference $file 3
done
# 2. 第二种场景: 清理最后变更时间距今超过指定时间的文件
traverse_directory "/var/log"
fi
}
# 递归遍历linux目录下的文件
traverse_directory(){
dir=$1
files=`ls -a $dir`
for file in $files
do
if [ -d $dir/$file ]
then
if [[ $file != '.' && $file != '..' ]]
then
traverse_directory $dir/$file
fi
else
time_difference $dir"/"$file $days
fi
done
}
# 对比时间差异,并清空在配置时间范围内没有更改的文件
time_difference() {
timestamp=`date +%s`
filepath=$1
if [ -f $filepath ];then
file_timestamp=`stat -c %Y $filepath`
time_diff=$[$timestamp - $file_timestamp]
seconds=`expr 60 * 60 * 24 * $2`
if [ $time_diff -gt $seconds ];then
echo "$time begin clear file $filepath" >> $log_file
echo "" > $filepath
fi
fi
}
main() {
# script parameters
# 参数说明 参数1: 磁盘空间占比超过多少时清理 参数2: 清理多大的文件(M) 参数3: 清理多久之前的文件(天)
threshold=$1
filesize=$2
days=$3
echo "Script parameters is: " $@
if [ -z $threshold ];then
threshold=70
fi
if [ -z $filesize ];then
filesize=150
fi
if [ -z $days ];then
filesize=15
fi
check_path
clear_log
}
main $@
四. 执行
首先将clear_log.sh
,clear_host_log.sh
两个脚本上传到集群的主节点下(可以免密ssh到其它节点)
首次清理需要执行下述命令
该命令执行结束后,会将清理日志脚本分发到集群各个节点,并配置定时调度
# Param1: ssh端口号,具体根据实际环境呢
sh -x clear_log.sh $ssh_port
执行完上述命令后,集群中的各个节点会每隔12
小时,在磁盘空间占用超过70%
的情况下,
清理/var/log
目录下超过150M
的日志文件.以及最近15天
没有进行任何修改的日志文件
也可以再各个节点上执行以下脚本手动清理:
# 参数1,当磁盘空间占比超过多少的时候进行清理,不传为70%
# 参数2,清理超过多少M的日志文件,不传为150M(最近3天的大文件不会被清除)
# 参数3,清理多久之前的日志,不传为15天
sh -x ~/emr/script/clear_host_log.sh $1 $2 $3
执行结束之后,可以在~/emr/logs/clear_host_log.log
文件中查看有哪些日志被清理
如下图:
查看相关的日志文件,可以发现内容已经被成功清空,磁盘空间得到释放
最后
以上就是耍酷人生为你收集整理的linux自动清理磁盘日志的一种方案一. 起因二. 方案三.代码四. 执行的全部内容,希望文章能够帮你解决linux自动清理磁盘日志的一种方案一. 起因二. 方案三.代码四. 执行所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复