獲取redis實例綁定cpu的情況


redis是一個單線模型的nosql類型的數據庫,而目前接觸到的服務器大都是多核的,比如8c,16c,32c,64c等等。為了充分利用主機,在一台主機上必然會部署多個redis實例,默認情況cpu會隨機選擇,但經過觀察自動選擇的時候很大情況下會選擇同一邏輯cpu,這樣導致cpu使用不均衡,撐得死了,餓的餓死了,怎么破。

 

其實可以對指定的進程id進行cpu綁定,綁定前的情況如下:

 

27001 instance bind on cpu  0-7
27002 instance bind on cpu  0-7
27003 instance bind on cpu  0-7
27004 instance bind on cpu  0-7
27005 instance bind on cpu  0-7
27007 instance bind on cpu  0-7
27008 instance bind on cpu  0-7

 

生成綁定的命令

ps aux|grep redis-server |grep -v grep |awk 'BEGIN {i=0}{i++}{print "taskset -pc " i, $2}'

  

綁定后的情況如下:

27001 instance bind on cpu  1
27002 instance bind on cpu  2
27003 instance bind on cpu  3
27004 instance bind on cpu  4
27005 instance bind on cpu  5
27007 instance bind on cpu  6
27008 instance bind on cpu  7

 

綁定后獲取cpu綁定情況的確認腳本如下:

ps -ef |grep redis-server |grep -v grep | awk '$NF~/cluster/{print $2,$(NF-1);next}{print $2,$NF}' > pid_instance

cat pid_instance | while read line
do
	pid=$(echo $line | awk '{print $1}')
	port=$(echo $line | awk -F':' '{print $2}')
	echo "$port instance bind on cpu `taskset -pc $pid | awk -F':' '{print $2}'`"
done
rm -rf pid_instance

 

如果有很多台redis實例,可以通過ansible分發該腳本到對應的主機上,然后跑一下sh redis_cpu.sh xxx腳本,xxx文件中是以all為分組的redis主機列表,例如:

cat >redis_cpu.sh <<EOF
#!/bin/bash

ansible -i $1 all -m copy -s -a "src=./get_redis_bind_cpu.sh dest=/tmp/get_redis_bind_cpu.sh"
ansible -i $1 all -m shell -s -a "sh get_redis_bind_cpu.sh"
EOF

cat >get_redis_bind_cpu.sh <<EOF
#!/bin/bash

ps -ef |grep redis-server |grep -v grep | awk '$NF~/cluster/{print $2,$(NF-1);next}{print $2,$NF}' > pid_instance

cat pid_instance | while read line
do
        pid=$(echo $line | awk '{print $1}')
        port=$(echo $line | awk -F':' '{print $2}')
        echo "$port instance bind on cpu `taskset -pc $pid | awk -F':' '{print $2}'`"
done
rm -rf pid_instance
EOF

 

添加一下輸出優化,直觀看出來是不是綁定了cpu

ps -ef |grep redis-server |grep -v grep | awk '$NF~/cluster/{print $2,$(NF-1);next}{print $2,$NF}' > pid_instance

cat pid_instance | while read line
do
        pid=$(echo $line | awk '{print $1}')
        port=$(echo $line | awk -F':' '{print $2}')
		bind_current=$(taskset -pc $pid | awk -F':' '{print $2}')
		total=$(cat /proc/cpuinfo |grep processor |wc -l)
		start=0
		let end=total-1
		bind_default="$start-$end"
		if [[ $bind_current -ne $bind_default ]];then
			echo "$port instance bind on cpu $bind_current ok"
		else
			echo "$port instance not set bind cpu default $bind_default,please check!!!"
		fi
done
rm -rf pid_instance

 

如果沒有綁定:

[root@testdb1 ~]# sh c.sh
6379 instance not set bind cpu default 0-23,please check!!!
29009 instance not set bind cpu default 0-23,please check!!!
29095 instance not set bind cpu default 0-23,please check!!!
27000 instance not set bind cpu default 0-23,please check!!!
27001 instance not set bind cpu default 0-23,please check!!!
29001 instance not set bind cpu default 0-23,please check!!!
29002 instance not set bind cpu default 0-23,please check!!!
29003 instance not set bind cpu default 0-23,please check!!!
29004 instance not set bind cpu default 0-23,please check!!!
29005 instance not set bind cpu default 0-23,please check!!!
29006 instance not set bind cpu default 0-23,please check!!!
29007 instance not set bind cpu default 0-23,please check!!!
29008 instance not set bind cpu default 0-23,please check!!!
29000 instance not set bind cpu default 0-23,please check!!!

 

如果有綁定

27183 instance bind on cpu  1 ok
27184 instance bind on cpu  2 ok
27185 instance bind on cpu  3 ok
27186 instance bind on cpu  4 ok
27187 instance bind on cpu  5 ok
27188 instance bind on cpu  6 ok
27189 instance bind on cpu  7 ok
27190 instance bind on cpu  8 ok
27191 instance bind on cpu  9 ok
27192 instance bind on cpu  10 ok
27193 instance bind on cpu  11 ok
27194 instance bind on cpu  11 ok
27195 instance bind on cpu  10 ok
27196 instance bind on cpu  9 ok
27197 instance bind on cpu  8 ok

 

@20190509

cat >get_redis_bind_cpu.sh <<EOF
#!/bin/bash
 
ps -ef |grep redis-server |grep -v grep | awk '\$NF~/cluster/{print \$2,\$(NF-1);next}{print \$2,\$NF}' > pid_instance
 
cat pid_instance | while read line
do
        pid=\$(echo \$line | awk '{print \$1}')
        port=\$(echo \$line | awk -F':' '{print \$2}')
        bind_current=\$(taskset -pc \$pid | awk -F':' '{print \$2}')
        total=\$(cat /proc/cpuinfo |grep processor |wc -l)
        start=0
        let end=total-1
        bind_default="\$start-\$end"
        if [[ \$bind_current -ne \$bind_default ]];then
            echo "\$port instance bind on cpu \$bind_current ok"
        else
            echo "\$port instance not set bind cpu default \$bind_default,please check!!!" >> no_bind.log
        fi
done
rm -rf pid_instance
EOF


cat >redis_cpu.sh <<EOF
#!/bin/bash
 
ansible -i \$1 all -m copy -s -a "src=./get_redis_bind_cpu.sh dest=/tmp/get_redis_bind_cpu.sh" > /dev/null
ansible -i \$1 all -m shell -s -a "cd /tmp;sh get_redis_bind_cpu.sh" > /dev/null
ansible -i \$1 all -m shell -s -a "ls -l /tmp/no_bind.log 2>/dev/null"

EOF
 

PS:
1.執行前確保ansible到目標所有redis實例的機器可以跑通。
2.執行sh redis_cpu.sh redis_host  |grep -v FAILED
3.有輸出的即是對應主機上redis實例存在沒有綁定cpu的,具體實例端口在對應機器的/tmp/no_bind.log

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM