問題描述
在使用國產化彈性裸金屬(包括鯤鵬、海光)的過程中,經常會遇到iperf等網絡應用打流性能低的問題。
原因描述
國產化彈性裸金屬(包括鯤鵬、海光)CPU主頻偏低,單個cpu處理性能沒有主頻更高的intel x86服務器強。另外,處理器其他方面存在差異,經常出現cpu負載不均衡,部分cpu的負載過重,成為性能的瓶頸。
解決方案
優化配置一下發包和收包相關的配置,使得收發包的負載均衡的更合理一些,尤其接收負載的中斷、軟中斷能均衡到多個cpu上,避免少部分cpu負載重處理不過來,引起性能下降。
下面是配置的內容
1.提高irqbalance服務執行均衡的頻率
提高執行的頻率到每秒鐘一次,能更加及時的把中斷過多的cpu上的中斷均衡到其他空閑的cpu上去,提高數據包處理性能。
去掉下面參數前面的注釋,并添加"-t 1"參數,重啟服務加載配置
# vim /etc/sysconfig/irqbalance
IRQBALANCE_ARGS="-t 1"
# systemctl restart irqbalance
2.配置rps和rfs
能夠均衡軟中斷負載,避免軟中斷負載過于集中到少量cpu上,同時會保證同一條流的數據包分發給同一個cpu處理、網絡應用和軟中斷使用的cpu,避免跨cpu引起的性能下降。
編輯腳本rps-rfs.sh
#!/bin/bash
# FileName: rps-rfs.sh
rps_flow_cnt=4096
rps_start()
{
total_flow_entries=0
# Get all virtio net interfaces
net_interface=`ls /sys/class/net/ -l |grep pci | awk '{print $9}' | tr ":\n" " "`
for em in ${net_interface[@]}
do
# Get current interface's rx queue number
rq_count=`ls /sys/class/net/$em/queues/rx-* -d | wc -l`
for ((i=0; i< $rq_count; i++))
do
echo $rps_flow_cnt > /sys/class/net/$em/queues/rx-$i/rps_flow_cnt
total_flow_entries=$(($total_flow_entries+$rps_flow_cnt))
done
flag=0
while [ -f /sys/class/net/$em/queues/rx-$flag/rps_cpus ]
do
# Set current rps_cpus to 0xffff...
echo `cat /sys/class/net/$em/queues/rx-$flag/rps_cpus | sed 's/0/f/g'` > \
/sys/class/net/$em/queues/rx-$flag/rps_cpus
flag=$(($flag+1))
done
done
echo $total_flow_entries > /proc/sys/net/core/rps_sock_flow_entries
sysctl -p
}
rps_stop() {
net_interface=`ls /sys/class/net/ -l |grep pci | awk '{print $9}' | tr ":\n" " "`
for em in ${net_interface[@]}
do
rq_count=`ls /sys/class/net/$em/queues/rx-* -d | wc -l`
for ((i=0; i< $rq_count; i++))
do
echo 0 > /sys/class/net/$em/queues/rx-$i/rps_flow_cnt
done
flag=0
while [ -f /sys/class/net/$em/queues/rx-$flag/rps_cpus ]
do
echo 0 > /sys/class/net/$em/queues/rx-$flag/rps_cpus
flag=$(($flag+1))
done
done
echo 0 > /proc/sys/net/core/rps_sock_flow_entries
sysctl -p
}
rps_status() {
ni_list=`ls /sys/class/net/ -l |grep pci | awk '{print $9}' | tr ":\n" " "`
for n in $ni_list
do
rx_queues=`ls /sys/class/net/$n/queues/ | grep "rx-[0-9]"`
for q in $rx_queues
do
# Get current interface rps info
rps_cpus=`cat /sys/class/net/$n/queues/$q/rps_cpus`
rps_flow_cnt=`cat /sys/class/net/$n/queues/$q/rps_flow_cnt`
echo "[$n]" $q "--> rps_cpus =" $rps_cpus ", rps_flow_cnt =" $rps_flow_cnt
done
done
rps_sock_flow_entries=`cat /proc/sys/net/core/rps_sock_flow_entries`
echo "rps_sock_flow_entries =" $rps_sock_flow_entries
}
case "$1" in
start)
echo -n "Starting $DESC: "
rps_start
rps_status
;;
stop)
rps_stop
rps_status
;;
restart|reload|force-reload)
rps_stop
rps_start
;;
status)
rps_status
;;
*)
echo "Usage: $0 [start|stop|status]"
;;
esac
exit 0
腳本放到系統可執行目錄下,并配置到開機啟動
# cp rps-rfs.sh /usr/bin/
# chmod +x /usr/bin/rps-rfs.sh
# echo "rps-rfs.sh start" >> /etc/rc.local
# chmod +x /etc/rc.local
修改熱添加設備調用的udev腳本
# vim /usr/local/sbin/generate-interface-config.sh
...
generate_ifcfg() {
...
/usr/bin/rps-rfs.sh start
}
備注:
rps開啟后所有軟中斷負載會均衡到所有cpu上,在網卡滿負載打流的情況下會偶現ping包延時偏大(3-4ms)的情況。rps默認開啟,有助于提高netperf或iperf等網絡應用的整體帶寬性能,對個別的ping的icmp包的延時增大這一點,可以忽略。
3.提高網絡NAPI收包的budget
能夠提高單次NAPI輪詢收包的數目,避免一次中斷觸發的輪詢接收的數據包過少,引起收到的數據包在軟件緩存中堆積,導致性能下降。
在下面文件末尾追加一行,執行sysctl -p對當前系統生效
# vim /etc/sysctl.conf
...
net.core.netdev_budget=600
# sysctl -p
4.增加傳輸層緩存大小
在下面文件末尾追加下面內容,執行sysctl -p對當前系統生效
# vim /etc/sysctl.conf
...
net.core.rmem_max=16777216
net.core.rmem_default=16777216
net.core.wmem_max=16777216
net.core.wmem_default=16777216
net.ipv4.tcp_rmem=409600 1638400 419430400
net.ipv4.tcp_wmem=409600 1638400 419430400
net.ipv4.tcp_mem=617474700 823299700 1234949400
net.ipv4.udp_mem=597916800 797222700 11958336
# sysctl -p
5.關閉xps
避免將同一條流的數據包分散到不同cpu發送,引起的發送性能下降。
編輯腳本xps-disable.sh
#!/bin/bash
# FileName: xps-disable.sh
xps_disable()
{
# Get all virtio net interfaces
net_interface=`ls /sys/class/net/ -l |grep pci | awk '{print $9}' | tr ":\n" " "`
for em in ${net_interface[@]}
do
# Get current interface's tx queue number
tq_count=`ls /sys/class/net/$em/queues/tx-* -d | wc -l`
# Disable each tx queue xps
for ((i=0; i< $tq_count; i++))
do
echo 0 > /sys/class/net/$em/queues/tx-$i/xps_cpus
done
done
sysctl -p
}
xps_status() {
ni_list=`ls /sys/class/net/ -l |grep pci | awk '{print $9}' | tr ":\n" " "`
for n in $ni_list
do
tx_queues=`ls /sys/class/net/$n/queues/ | grep "tx-[0-9]"`
for q in $tx_queues
do
xps_cpus=`cat /sys/class/net/$n/queues/$q/xps_cpus`
echo "[$n]" $q "--> xps_cpus =" $xps_cpus
done
done
}
case "$1" in
disable)
xps_disable
xps_status
;;
status)
xps_status
;;
*)
echo "Usage: $0 [disable|status]"
;;
esac
exit 0
腳本放到系統可執行目錄下,并配置到開機啟動
# cp xps-disable.sh /usr/bin/
# chmod +x /usr/bin/xps-disable.sh
# echo "xps-disable.sh disable" >> /etc/rc.local
# chmod +x /etc/rc.local
修改熱添加設備調用的udev腳本
# vim /usr/local/sbin/generate-interface-config.sh
...
generate_ifcfg() {
...
/usr/bin/xps-disable.sh disable
}