【发布时间】:2014-01-29 10:37:10
【问题描述】:
我编写了一个收集一些系统统计信息的脚本。这与压力测试一起运行,以便可以收集有关系统的 sats。收集的统计数据包括 CPU 使用率(使用 sar)、内存使用率(使用 free)、中断等。正在收集的每个数据点都通过将其置于后台而产生到单独的进程中。进行了一些后处理以将此数据移动到 csv 文件,以便可以在电子表格中打开它。后期处理也发生在衍生过程中。该脚本在收集的样本之间有一个睡眠间隔。但是,在此时间间隔内,后台进程仍在运行。
我观察到,当这个脚本运行很长时间时,单独这个脚本的 CPU 使用率逐渐从 3% 左右增加到几乎 100% 。这是一个令人不安的场景,因为不允许分析脚本占用如此多的 CPU 时间。 (我使用“top”来记录每个进程的 CPU 使用情况”)。
另一个有趣的观察是,在压力测试中运行的重型进程占用的 CPU 时间比这个脚本要少(在它的使用率超过 90% 之后)。
如何解决?我在这里缺少什么吗?请指教。
在下面添加一些代码位。以下是主循环。
while true
do
if [ $exitstatus = 0 ]
then
exitScript
fi
let itr++
echo -e "\n Interation: $itr\n"
if [ "$3" = "ALL" ]
then
export CALC_INTERRUPTS=1
printTitle "sar"
processCommand "sar" &
#printTitle "free"
processCommand "free" &
printTitle "interrupts"
processCommand "interrupts" &
printTitle "underflows"
processCommand "underflows" &
#printTitle "clocktree"
processCommand "clocktree" &
else
if [ $itr -eq 1 ]
then
shift 2
fi
for com in "$@"
do
printTitle "$com"
processCommand "$com" &
done
fi
#printTimestamp > $TEMP_LOC/sys.log
cat /var/log/syslog > $TEMP_LOC/sys.log
if [ $exitstatus = 0 ]
then
exitScript
fi
sleep $interval
#Wait for background jobs from the last iteration to finish
for job in `jobs -p`
do
wait $job
done
cat $TEMP_LOC/*.temp >> $TEMP_LOC/monitor.log
rm -f $TEMP_LOC/*.temp
if [ $(($itr % 180)) -eq 0 ]
then
takeDump
fi
done
fi
以下是CPU使用率的记录和后期处理(使用sar)-
processCommand()
{
case "$1" in
sar)
printTimestamp>> $TEMP_LOC/$1.temp
#echo -n " Logging CPU stats............ "
exe="sar -P ALL 1 1"
$exe > $TEMP_LOC/temp_sar
echo -e "\n\n Processes using more than 1% of CPU time: " >> $TEMP_LOC/$1.temp
top -b -n 1 > $TEMP_LOC/temp_top
#delete all lines except current CPU statistics
sed -i "5,8! d" $TEMP_LOC/temp_sar
#replace all spaces with commas
sed -i 's/[[:space:]]\+/,/g' $TEMP_LOC/temp_sar
Cpu=0
while [ -s $TEMP_LOC/temp_sar ]
do
#if file does not exist then add the header
if [ ! -f $TEMP_LOC/Cpu$Cpu.csv ]
then
printf "time,$Cpu.us,$Cpu.ni,$Cpu.sy,$Cpu.wa,$Cpu.st,$Cpu.id,$Cpu.total\n" >> $TEMP_LOC/Cpu$Cpu.csv
fi
#remove CPU number
stats=`sed -n '1p' $TEMP_LOC/temp_sar | cut -d ',' --complement -f 2`
idle=`echo $stats | cut -d ',' -f 7`
#calculate totale CPU usage as 100-idle
total_usage=$(bc <<< "100.00-$idle")
echo "$stats,$total_usage" >> $TEMP_LOC/Cpu$Cpu.csv
sed -i '1d' $TEMP_LOC/temp_sar
let Cpu++
done
;;
代码的其他部分也类似地工作。定期拍摄该参数的快照并对其进行一些后期处理。
【问题讨论】:
-
能发一下脚本内容吗
-
您是否将所有数据都保存在内存中?您是覆盖 CSV 文件还是只是追加新数据?
-
线程数逐渐增加?另请注意,总 CPU% 是 top 中的 CPU%/CPU-cores。
-
@choroba,是的,所有数据都在内存中。我挂载 RAMFS 并将所有临时数据保存在上面。
-
@krampstudio,脚本很大(大约 500 行左右)。要我粘贴整个内容吗?