標籤:
原文 http://rfyiamcool.blog.51cto.com/1030776/1335700
簡單的說就是,每個硬體裝置(如:硬碟、網卡等)都需要和 CPU 有某種形式的通訊以便 CPU 及時知道發生了什麼事情,這樣 CPU 可能就會放下手中的事情去處理應急事件,硬體裝置主動打擾 CPU 的現象就是硬體中斷。
關於SMP IRQ affinity?
新的核心, Linux改進了分配特定中斷到指定的處理器(或處理器組)的功能. 這被稱為SMP IRQ affinity, 它可以控制系統如何響應各種硬體事件. 允許你限制或者重新分配伺服器的工作負載, 從而讓伺服器更有效工作. 以網卡中斷為例,在沒有設定SMP IRQ affinity時, 所有網卡中斷都關聯到CPU0, 這導致了CPU0負載過高,而無法有效快速的處理網路資料包,導致了瓶頸。 通過SMP IRQ affinity, 把網卡多個中斷分配到多個CPU上,可以分散CPU壓力,提高資料處理速度。
irqbalance的一些個介紹
irqbalance 用於最佳化中斷分配,它會自動收集系統資料以分析使用模式,並依據系統負載狀況將工作狀態置於 Performance mode 或 Power-save mode.處於 Performance mode時irqbalance 會將中斷儘可能均勻地分發給各個CPU以充分利用 CPU 多核,提升效能.處於 Power-save mode時,irqbalance 會將中斷集中分配給第一個 CPU,以保證其它空閑 CPU 的睡眠時間,降低能耗。
在沒有配置SMP IRQ affinity,也沒有開啟irqbalance的時候~
在配置了SMP IRQ affinity,啟動了RPS,關閉irqbalance
在作網路程式的時候, 經常需要瞭解interrupts和非強制中斷的平衡情況, 需要知道每秒有多少中斷髮生,發生在哪個cpu上.
Linux下中斷來源資訊可以從 /proc/interrupts 中瞭解到~
大家會看到他的頻率是一樣的,因為我們這邊已經開了 irqbalance ,這個東西在負載不大的情況下,是個很不錯的服務,他的主要功能是可以合理的調配使用各個CPU核心,特別是對於目前主流多核心的CPU,簡單的說就是能夠把壓力均勻的分配到各個CPU核心上,對提升效能有很大的協助。
[[email protected] ~]# service irqbalance statusirqbalance (pid 21745) is running...[[email protected] ~]#
首先我們可以通過訪問/proc/cpuinfo的資訊查看到cpu的具體資訊。
擷取eth0網卡的中斷irq號,並且賦值給shell變數
關閉irqbalance自動分配服務,好讓咱們手動分配插斷要求`
/etc/init.d/irqbalance stop
指定CPU來處理對應網卡的插斷要求
我這裡是選擇cpu2來處理這個網卡中斷~
這裡的4是cpu的16進位運算式
CPU Binary oct
CPU 0 00000001 1
CPU 1 00000010 2
CPU 2 00000100 4
CPU 3 00001000 8
這裡分享一個指令碼,直接算就可以了~
#!/bin/bash#echo "統計cpu的16進位"[ $# -ne 1 ] && echo ‘$1 is Cpu core number’ && exit 1CCN=$1echo “Print eth0 affinity”for((i=0; i<${CCN}; i++))doecho ==============================echo "Cpu Core $i is affinity"((affinity=(1<<i)))echo "obase=16;${affinity}" | bcdone
要是cpu是8核心的~
要是16個核心的~
[[email protected] ~]# sh run.sh 16統計cpu的16進位“Print eth0 affinity”==============================Cpu Core 0 is affinity1==============================Cpu Core 1 is affinity2==============================Cpu Core 2 is affinity4==============================Cpu Core 3 is affinity8==============================Cpu Core 4 is affinity10==============================Cpu Core 5 is affinity20==============================Cpu Core 6 is affinity40==============================Cpu Core 7 is affinity80==============================Cpu Core 8 is affinity100==============================Cpu Core 9 is affinity200==============================Cpu Core 10 is affinity400==============================Cpu Core 11 is affinity800==============================Cpu Core 12 is affinity1000==============================Cpu Core 13 is affinity2000==============================Cpu Core 14 is affinity4000==============================Cpu Core 15 is affinity8000
然後對於 smp_affinity的配置,根據16進位的cpu數目來算的,你要是輸入5的話,那意思就是說 cpu0 和cpu2都參與進去了。
大家還會注意到,目錄下還有個 smp_affinity_list ,他是十進位的表達方式
兩個配置是相通的,smp_affinity_list使用的是十進位,相比較smp_affinity的十六進位,可讀性更好些。
echo 3,8 > /proc/irq/31/smp_affinity_listecho 0-4 > /proc/irq/31/smp_affinity_list
利用watch查看切換後的效果
[[email protected] ~]# watch -n 2 "cat /proc/interrupts |grep eth"
好了,需要說明的是:
對單隊列網卡而言,smp_affinity和smp_affinity_list配置多CPU是沒有效果的。這話也不是絕對的,咱們可以用 RPS 來搞定。
該功能主要針對單隊列網卡多CPU環境,如網卡支援多隊列則可使用SMP irq affinity直接綁定硬中斷,要是不支援多隊列,那就用RPS解決網路非強制中斷的負載平衡,即單個網卡的非強制中斷分散到多個CPU處理,避免單個CPU負載過大導致效能瓶頸。
如何確定你的網卡支援多隊列~
最右面的那些就是多隊列的資訊了
這個是4隊列的~
這個是8隊列的~
這裡用的機型是IBM x3630 m3
網卡是MSI-X的
事實上在一個大量小包的系統上,irqbalance最佳化幾乎沒有效果,而且還使得cpu消耗分配的不均衡,導致機器效能得不到充分的利用,這個時候需要把它給結束掉。然後咱們用手動的方法配置下。
不管怎麼說,在同等條件下強烈大家選用多隊列的網卡,常見的有Intel的82575、82576,Boardcom的57711等。
多隊列網卡是一種技術,最初是用來解決網路IO QoS 問題的,隨著網路IO的頻寬的不斷提升,單核CPU不能完全處滿足網卡的需求,通過多隊列網卡驅動的支援,將各個隊列通過中斷綁定到不同的核上。其實用bonding網卡綁定在一定程度也可以做中斷負載平衡,兩個網卡中斷號可以綁定在不同的cpu核心上。
由於RPS只是單純把資料包均衡到不同的cpu,這個時候如果應用程式所在的cpu和非強制中斷處理的cpu不是同一個,此時對於cpu cache的影響會很大,那麼RFS確保應用程式處理的cpu跟非強制中斷處理的cpu是同一個,這樣就充分利用cpu的cache.
有兩種配置的方法:
把每個隊列連到一個cpu上
/proc/sys/net/core/rps_sock_flow_entries 32768/sys/class/net/eth0/queues/rx-0/rps_cpus 00000001/sys/class/net/eth0/queues/rx-1/rps_cpus 00000002/sys/class/net/eth0/queues/rx-2/rps_cpus 00000004/sys/class/net/eth0/queues/rx-3/rps_cpus 00000008/sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096/sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096/sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096/sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096
另一種是推薦的方法: 這個方法在多方面測試下,可以很好的均衡下來。
/sys/class/net/eth0/queues/rx-0/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-1/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-2/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-3/rps_cpus 000000ff/sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096/sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096/sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096/sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096/proc/sys/net/core/rps_sock_flow_entries 32768
總結下:
RPS/RFS主要是針對單隊列網卡多CPU環境。雖然有這些虛擬隊列的支撐,但是畢竟是軟體類比的。 強烈推薦用支援多隊列的網卡。
多隊列多重中斷的網卡在使用了smp affinity之後也可以再使用該RFS RPS的功能,在這裡他更像是個接收方的調解員,最大程度的提高cpu cache。
自己的一些理解,要是有不對的地方,請朋友們噴之 !
這兩天會把測試的結果貼上來,6樓的庫房停電了,從哥們拿申請了幾個R720xd的測試機器都連不上了 !
這邊的網路測試用的是 netperf ~
tar -xzvf netperf-2.5.0.tar.gzcd netperf-2.5.0./configuremakemake install
用法:
根據作用範圍的不同,netperf的命令列參數可以分為兩大類:全域命令列參數、測試相關的局部參數,兩者之間使用--分隔:Netperf [global options] –-[test-specific options]其中:全域命令列參數包括如下選項:-H host :指定遠端運行netserver的server IP地址。-l testlen:指定測試的時間長度(秒)-t testname:指定進行的測試類型,包括TCP_STREAM,UDP_STREAM,TCP_RR,TCP_CRR,UDP_RR測試相關的局部參數包括如下選項:-s size 設定本地系統的socket發送與接收緩衝大小-S size 設定遠端系統的socket發送與接收緩衝大小-m size 設定本地系統發送測試分組的大小-M size 設定遠端系統接收測試分組的大小-D 對本地與遠端系統的socket設定TCP_NODELAY選項
102 是請求端,可以看到他的網卡跑滿是118M左右。
101是服務端 ~
咱們看看用戶端的結果:
1)遠端系統(即server)使用大小為229376位元組的socket接收緩衝
2)本地系統(即client)使用大小為65507位元組的socket發送緩衝
3)測試經曆的時間為120秒
4)輸送量的測試結果為961 Mbits/秒
1)遠端系統(即server)使用大小為87380位元組的socket接收緩衝
2)本地系統(即client)使用大小為16384位元組的socket發送緩衝
3)測試經曆的時間為120秒
4)輸送量的測試結果為941 Mbits/秒
密集負載下的網卡中斷負載平衡smp affinity及單隊列RPS