实现对多核Linux CPU% 的期望占用
This commit is contained in:
183
cpu_scheduler.sh
Executable file
183
cpu_scheduler.sh
Executable file
@ -0,0 +1,183 @@
|
||||
#! /bin/bash
|
||||
#! -*- coding=utf-8 -*-
|
||||
# Author:zhouze03
|
||||
# Date: 2017-08-15
|
||||
|
||||
######
|
||||
# 期望当正经的CPU%使用率 < 期望值时 ; 可以启动额外的任务来提升CPU的使用率;
|
||||
# 备注:
|
||||
# 1. 当前程序作为附加程序,要做到”不得已而用之“;
|
||||
# 2. 本程序会调用一个非常消耗CPU的脚本程序:这个进程暂且称之为”greedy(贪婪的)进程“(死循环脚本)
|
||||
# 3. 服务器其它的进程都认为是online的进程;
|
||||
######
|
||||
|
||||
# 1. 当前CPU总使用率(排除/kill贪婪进程);(CURR_CPU_RATE)
|
||||
# 2. 某进程CPU总使用率:(greedy_process_cpu_rate)(舍弃)
|
||||
# 3. 期望的CPU% 使用百分值;(EXPECT_CPU_RATE)
|
||||
# 4. 逻辑CPU的个数 CPU_LOGI_NUM
|
||||
|
||||
############
|
||||
# 算法:
|
||||
# 无限循环语句:
|
||||
# 0. 每5分钟检查一次;
|
||||
# 1. 由于当前的进程CPU使用率不好获取,因此,使用直接kill贪婪进程的方式(如果有进程),然后获取此刻的CPU使用率(该使用率 = 正经CPU使用率)
|
||||
# 2. 获取当前的CPU% 使用率;
|
||||
# 3. 获取贪婪值:GREEDY_VALUE=(EXPECT_CPU_RATE - CURR_CPU_RATE)
|
||||
# Case1: GREEDY_VALUE > 0; then
|
||||
# 本次贪婪占用核数目 =(CPU核数目 * 贪婪值(0.0-1))向下取整 && 启动与贪婪核数目相同的进程数目;(通过cpulimit 限制贪婪进程最高占用95%CPU)
|
||||
# 备注:
|
||||
# 使用cpulimit 只运行单进程对单核的使用上限为95% 是为了避免超过100%不可预期的异常。(不确定超过100% 是否会造成问题,因此保险起见进行了限制)
|
||||
# 其次,线程可控,该程序脚本的线程上限为CPU的核数目,不会为了打满CPU而创建过的线程的情况,(Linux 用户线程有上限,避免影响线上(正经)的服务)
|
||||
# 备注(重点):
|
||||
# 单个贪婪进程所占用的CPU% :
|
||||
# 1. 如果当前机器总CPU% < 50%; then: 可以使得单贪婪进程CPU% > 80%; (如果一半的CPU逻辑单元被占满不会影响其它服务可以这样设置,否则按下面的方式)
|
||||
# 2. 如果当前服务器上正经的服务对CPU逻辑单元需求很大,则设置单个贪婪进程CPU% <= 50% , 同时贪婪进程个数增加,
|
||||
# 这样虽在表面上看起来两个50% 的进程占用了100%,但是在CPU的并发度上是不同的,其它的进程有机会去获取CPU时间片去执行它们的程序;
|
||||
# 简而言之:
|
||||
# CPU_LIMIT_FOR_GREEDY_PROCESS 确定了贪婪进程的个数与进程所占的比例
|
||||
############
|
||||
|
||||
|
||||
# 设定期望值(改为main参数确定)
|
||||
# EXPECT_CPU_RATE=50
|
||||
# 贪婪进程比例的设定 (改为main参数确定)
|
||||
# CPU_LIMIT_FOR_GREEDY_PROCESS=50
|
||||
|
||||
# 当前CPU%
|
||||
function get_curr_cpu_rate(){
|
||||
local curr_cpu_rate=`env LC_ALL=en_US.UTF8 sar 1 1 | grep ^Average | awk '{print $8}' `
|
||||
curr_cpu_rate=${curr_cpu_rate%.*}
|
||||
CURR_CPU_RATE=`expr 100 - $curr_cpu_rate`
|
||||
echo "CURRENT CPU USAGE RATE="$CURR_CPU_RATE
|
||||
}
|
||||
|
||||
# 当前机器 逻辑CPU数目
|
||||
function get_cpu_logi_num(){
|
||||
CPU_LOGI_NUM=`cat /proc/cpuinfo| grep "processor"| wc -l`
|
||||
echo "CPU LOGI NUM="$CPU_LOGI_NUM
|
||||
}
|
||||
|
||||
# kill 贪婪进程
|
||||
function kill_greedy_pid(){
|
||||
ps -ef | grep ./dead_circle.sh | grep -v grep | awk '{print $2}' | xargs kill -9 > /dev/null
|
||||
}
|
||||
|
||||
# 贪婪start
|
||||
function fire_greedy_process(){
|
||||
echo "GREEDY NUM= "$1
|
||||
for i in `seq 1 $1`
|
||||
do
|
||||
{
|
||||
./cpulimit -l $CPU_LIMIT_FOR_GREEDY_PROCESS bash ./dead_circle.sh > /dev/null &
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
##############################################################################################
|
||||
##################################### 贪婪引擎 ##############################################
|
||||
##############################################################################################
|
||||
|
||||
function greedy_machine(){
|
||||
# 确定CPU核数目:
|
||||
get_cpu_logi_num
|
||||
|
||||
# 贪婪调度器
|
||||
while true
|
||||
do
|
||||
# 1.kill 贪婪进程
|
||||
kill_greedy_pid
|
||||
# 2.获取当前CPU%
|
||||
get_curr_cpu_rate
|
||||
# 3.获取贪婪值
|
||||
GREEDY_VALUE=`expr $EXPECT_CPU_RATE - $CURR_CPU_RATE`
|
||||
echo "GREEDY_VALUE="$GREEDY_VALUE
|
||||
# 4.是否执行贪婪计划
|
||||
if [ $GREEDY_VALUE -gt 0 ]; then
|
||||
# 确定贪婪进程数
|
||||
# greedy_process_num=`expr $CPU_LOGI_NUM \* $GREEDY_VALUE / 100`
|
||||
greedy_process_num=`expr $CPU_LOGI_NUM \* $GREEDY_VALUE / $CPU_LIMIT_FOR_GREEDY_PROCESS`
|
||||
GREEDY_PROCESS_NUM=${greedy_process_num%.*}
|
||||
echo "GREEDY_PROCESS_NUM= "$GREEDY_PROCESS_NUM
|
||||
# 大于0则调度
|
||||
if [ $GREEDY_PROCESS_NUM -gt 0 ]; then
|
||||
fire_greedy_process $GREEDY_PROCESS_NUM
|
||||
fi
|
||||
fi
|
||||
# 休眠1min
|
||||
sleep 60
|
||||
done
|
||||
}
|
||||
|
||||
##############################################################################################
|
||||
##############################################################################################
|
||||
##############################################################################################
|
||||
|
||||
|
||||
|
||||
|
||||
##############################################################################################
|
||||
########################################## main #############################################
|
||||
##############################################################################################
|
||||
|
||||
|
||||
function check_parameters(){
|
||||
|
||||
if [ "x$EXPECT_CPU_RATE" == "x" ]
|
||||
then
|
||||
echo "PARAM ERROR: EXPECT_CPU_RATE IS NULL (-e)" >&2
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [ $EXPECT_CPU_RATE -lt 0 -o $EXPECT_CPU_RATE -gt 100 ]
|
||||
then
|
||||
echo "PARAM ERROR: EXPECT_CPU_RATE value expect [1-100] (-e)" >&2
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [ "x$CPU_LIMIT_FOR_GREEDY_PROCESS" == "x" ]
|
||||
then
|
||||
echo "PARAM ERROR: CPU_LIMIT_FOR_GREEDY_PROCESS IS NULL (-l)"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [ $CPU_LIMIT_FOR_GREEDY_PROCESS -lt 0 -o $CPU_LIMIT_FOR_GREEDY_PROCESS -gt 100 ]
|
||||
then
|
||||
echo "PARAM ERROR: CPU_LIMIT_FOR_GREEDY_PROCESS value expect [1-100] (-e)" >&2
|
||||
exit -1
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
while getopts "e:l:h" opt
|
||||
do
|
||||
case $opt in
|
||||
e)
|
||||
EXPECT_CPU_RATE=$OPTARG
|
||||
echo "EXPECT_CPU_RATE= "$EXPECT_CPU_RATE
|
||||
;;
|
||||
l)
|
||||
CPU_LIMIT_FOR_GREEDY_PROCESS=$OPTARG
|
||||
echo "CPU_LIMIT_FOR_GREEDY_PROCESS= "$CPU_LIMIT_FOR_GREEDY_PROCESS
|
||||
;;
|
||||
*)
|
||||
echo "ERROR don't support this parameter" >&2
|
||||
usage
|
||||
exit -1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
check_parameters
|
||||
greedy_machine
|
||||
|
||||
|
||||
##############################################################################################
|
||||
##############################################################################################
|
||||
##############################################################################################
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user