转载自:http://www.furion.info/14.html
先说下背景:我们线上用的squid,根据经验值如果长时间运行则缓存目录下的swap.state会慢慢变大,一旦超过60M,squid的性能就会急剧下降,因此需要定时去清理大于60M的swap.state文件。
由此引出需求,查找cache目录下的所有大于60M的swap.state文件并清除,即:
1.查找cache目录下的所有swap.state文件
2.判断是否大于60M
3.大于60M则清空
相关squid配置如下:
cache_dir coss /data/cache1/coss 120000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100
cache_dir aufs /data/cache1 30000 128 128 min-size=1000000
cache_dir coss /data/cache2/coss 180000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100
cache_dir aufs /data/cache2 50000 128 128 min-size=1000000
cache_dir coss /data/cache3/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100
cache_dir aufs /data/cache3 50000 128 128 min-size=1000000
cache_dir coss /data/cache4/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100
cache_dir aufs /data/cache4 50000 128 128 min-size=1000000
cache_dir coss /data/cache5/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100
cache_dir aufs /data/cache5 50000 128 128 min-size=1000000
cache_dir coss /data/cache6/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100
这里稍微说下,由于我们配置了coss,所有swap.state主要是在coss目录下,同时我们采用了多进程squid,因此coss目录下存在squid1-squid6等目录。
第一想到的则是常用的du -sh命令: du -sh /data/cache*/coss/squid*/swap.state ,输入如下:
[root@CRN-JZ-2-36X ~]# du -sh /data/cache*/coss/squid*/swap.state 2.7M /data/cache1/coss/squid1/swap.state
270k /data/cache1/coss/squid2/swap.state
2.7M /data/cache1/coss/squid3/swap.state
2.7M /data/cache1/coss/squid4/swap.state
53M /data/cache1/coss/squid5/swap.state
35M /data/cache1/coss/squid6/swap.state
5.6M /data/cache2/coss/squid3/swap.state
4.6M /data/cache2/coss/squid4/swap.state
122M /data/cache2/coss/squid5/swap.state
4.4M /data/cache3/coss/squid4/swap.state
97M /data/cache3/coss/squid5/swap.state
75M /data/cache3/coss/squid6/swap.state
5.4M /data/cache4/coss/squid1/swap.state
74M /data/cache4/coss/squid6/swap.state
…
可以发现,/data/cache4/coss/squid6/swap.state 等大于60M的swap.state为我们需要清理的目标。
当时就很自然的采用如下方案去实现:
du -sh /data/cache*/coss/squid*/swap.state | awk ‘ { print $1 } ‘ | awk -F’M’ ‘ { print $1 } ‘
思路如下:使用du -sh 查找大于swap.state的大小,同时使用awk 过滤第一个字段,接着为了过滤掉M、只保留数字,再次使用awk 制定”M”作为分界符过滤出文件大小。
输入如下:
270k
2.7
2.7
53
35
5.6
4.6
122
4.4
97
75
5.4
74
可以看出du -sh这种方案的缺点,du -sh 的 输入会自动转换单位,K、M、G,只过滤M会导致部分文件大小无法正常获取,例如第一个的270k。同时使用了多个管道较为繁琐,
且管道过滤之后的只有文件大小,相对应的文件名丢失,后续的处理较麻烦,当然也可以使用数组等解决。故放弃此方案。
问了个朋友有没有好点的方法去处理,他提示我说不要使用带单位的输出,直接ls -l 的输出就可以作为相应的数据源。ls -l输出的结果以字节为单位,简单,容易处理。
这里同时考虑到第一个方案的缺点,因此加了两个临时变量去存储相应的文件名、文件大小。附上最后的方案:
#! /bin/bash
ls -l /data/cache*/coss/squid*/swap.state | while read i;
do
size=`echo $i | awk ‘ { print $5 }’`; file=`echo $i | awk ‘ { print $9 }’`;
#here the 61865984 byte is equal to 60M
if [ $size -gt 61865984 ] ;
then
echo $file; echo $size
#clean it
echo >$file
fi
done
好吧,其实这篇博客最主要的内容就是我犯了个很傻很天真的错误,采用du -sh这种带自动单位换成的命令去处理,麻烦多多。有时候还是简单的ls 好啊。
后续的引申可以再将次脚步稍微整理下,加上简单的清理日志记录,同时挂上计划任务,这样就可以自动去清理了。同时类似的,以后类似的需求,
均可以由此脚本简单修改而实现。