如今的高性能服務器上運行著更多的處理器伐脖,運行在其上的虛擬機擁有的vCPU數(shù)量也越來越多。傳統(tǒng)的單virtio-net隊列中乐设,由于網絡性能無法隨著vCPU的數(shù)量動態(tài)的伸縮讼庇,導致客戶機的協(xié)議棧規(guī)模受限,單一的收發(fā)隊列也使得虛擬機無法并行傳輸數(shù)據(jù)報文近尚,網絡性能受限蠕啄。openstack對網卡多隊列的支持應運而生。
openstack環(huán)境下的網卡多隊列使用
openstack在默認設置中并未啟動image的多隊列屬性戈锻。需要通過如下命令修改image屬性歼跟。
glance image-update --property hw_vif_multiqueue_enabled=**true** ${IMAGE_ID}
libvirt API driver |
---|
hw_vif_multiqueue_enabled |
If true, this enables the virtio-netmultiqueue feature. In this case, the driver sets the number of queues equal to the number of guest vCPUs. This makes the network performance scale across a number of vCPUs. |
true / false |
這里需要注意的是對鏡像屬性的修改并不會影響到已經使用該鏡像創(chuàng)建的虛擬機。用戶需要重建原有使用該鏡像的虛擬機或者新建使用該鏡像的虛擬機格遭,對應屬性才會生效哈街。
如果用戶需要修改已經處于運行狀態(tài)的虛擬機,可以通過virsh edit 虛擬機的xml文件實現(xiàn)虛擬機支持網卡多隊列拒迅。
docker **exec** -it -uroot nova_libvirt bash
virsh list
virsh edit instance-xxx
###這里將隊列數(shù)修改為8
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
<driver name='vhost' queues='8'/>
</interface>
virtsh shutdown instance-xxx
virtsh start instance-xxx
理論上修改后該鏡像啟動的虛擬機隊列長度固定為虛擬機的核數(shù)骚秦。但針對宿主機內核版本的不同,實際虛擬機的可用隊列存在上限(3.X為8個璧微,4.X為256個)骤竹。在實際應用中虛擬機的網卡多隊列也是會消耗宿主物理機的CPU性能的。尤其當CPU超配嚴重時往毡,開啟網卡多隊列并不一定是個好的選擇蒙揣。
/*3.X內核代碼*/
#define DEFAULT_MAX_NUM_RSS_QUEUES (8)
/* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for
* the netdevice to be fit in one page. So we can make sure the success of
* memory allocation. TODO: increase the limit. */
#define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES
/*4.X內核代碼*/
/* MAX_TAP_QUEUES 256 is chosen to allow rx/tx queues to be equal
* to max number of VCPUs in guest. */
#define MAX_TAP_QUEUES 256
網卡多隊列設置
網卡多隊列需要硬件和驅動同時支持。上一章節(jié)闡述了openstack控制層及虛擬化層對網卡多隊列的相應支持开瞭,本節(jié)將從虛擬機內部觀察多隊列網卡的相應設置信息懒震。
查看網卡pci設備
yum install pciutils –y
lspci
lspci -vvvs 00:03.0
MSI-X Capability中斷機制與MSI Capability的中斷機制類似罩息。PCIe總線引出MSI-X機制的主要目的是為了擴展PCIe設備使用中斷向量的個數(shù),同時解決MSI中斷機制要求使用中斷向量號連續(xù)所帶來的問題个扰。當出現(xiàn)MSI-X:Enable瓷炮,可以判斷該網卡支持網卡多隊列。
查看修改網卡多隊列信息
查看網卡的多隊列信息递宅,圖示顯示當前使用隊列數(shù)為1娘香,最大可用隊列數(shù)為4。
ethtool -l eth0
修改當前網卡使用隊列數(shù)办龄。
ethtool –L eth0 combined 4
中斷平衡
每個網卡隊列對應的中斷默認并沒有跟相應的CPU做綁定烘绽,也就是說默認情況下這些中斷都是沒有綁定的,那么按內核默認的處理策略俐填,對于沒有綁定的中斷安接,默認都會在CPU0上運行,這樣會導致CPU占用不均衡英融。過多的網卡收包和發(fā)包中斷集中在一個CPU上盏檐,在系統(tǒng)繁忙時,CPU對網卡的中斷無法響應驶悟,這樣導致了服務器端的網絡性能降低胡野。解決這種不均衡通常使用人為綁定中斷和啟動irqblance。
人為綁定網卡隊列中斷
通過下述命令查看網卡隊列中斷痕鳍,從截圖可以分析出網卡的4個隊列Tx/Rx分別占據(jù)了25-32這8個中斷向量號给涕。
cat /proc/interrupts
通過下述命令可以查看具體某個中斷的CPU親和性。圖示顯示中斷34綁定在CPU2上额获。(hex04 = bin100,按位分別對應CPU0,CPU1,CPU2)
Smp_affinity與Smp_affinity_list 顯示的是同一項信息恭应。不過前者以十六進制顯示抄邀,后者以十進制顯示
#該命令查看中斷34的CPU綁定關系
cat /proc/irq/34/smp_affinity
cat /proc/irq/34/smp_affinity_list
通過下述命令可以修改某個中斷與CPU的綁定關系。
#該命令將中斷34與CPU1綁定
echo 2 > /proc/irq/34/smp_affinity
irqbalance
irqbalance是一個開源項目(https://github.com/Irqbalance/irqbalance)昼榛。在該項目主頁上描述道:Irqbalance is a daemon to help balance the cpu load generated by interrupts across all of a systems cpus.
irqbalance的基本原理很簡單:就是周期計算各個CPU上的中斷數(shù)量境肾,發(fā)現(xiàn)不均衡時,動態(tài)通過/proc接口設置指定中斷的CPU親和性胆屿,進行綁定奥喻。當只有一個中斷時,無論將這個中斷綁定到哪個CPU非迹,都會不均衡环鲤。irqbalance進行均衡的粒度為不同的中斷,當系統(tǒng)中有很多不同類型的中斷憎兽,基本有用冷离,但在上述的情況下吵冒,只有一個中斷(或者少量中斷),此時irqbalance無能為力西剥。當系統(tǒng)處于 Power-save mode時,irqbalance 會將中斷集中分配給第一個 CPU,以保證其它空閑 CPU 的睡眠時間,降低能耗痹栖。
irqbalance根據(jù)系統(tǒng)中斷負載的情況,自動遷移中斷保持中斷的平衡瞭空,同時會考慮到省電因素等等揪阿。 但是在實時系統(tǒng)中會導致中斷自動漂移,對性能造成不穩(wěn)定因素咆畏,在高性能的場合建議關閉南捂。
查看irqbalance狀態(tài)
systemctl status irqbalance.service
停止
systemctl stop irqbalance.service
RPS/RFS
目前服務器的CPU越來越強勁,CORE數(shù)量也達到了數(shù)十乃至上百的級別鳖眼。而實際物理網卡的隊列數(shù)量往往與龐大的CPU核心數(shù)量不能匹配黑毅。當網卡硬件隊列數(shù)量遠小于CPU核心數(shù)量時,即便設定了網卡的中斷親和钦讳,實際在處理網卡中斷請求時矿瘦,軟硬中斷依舊局限在少量的CPU核心之上。此時就可以通過RPS/RFS這兩個特性進一步分散網卡中斷請求愿卒。
RPS(Receive Packet Steering)
RPS特性把收到的報文依據(jù)一定的hash規(guī)則(根據(jù)IP四元組SIP缚去,SPORT,DIP琼开,DPORT)給hash到不同的CPU上去易结,以達到各個CPU負載均衡的目的。 這里只是把軟中斷做負載均衡柜候,不去改變硬中斷搞动。因而對網卡沒有任何要求。實際該功能也適用于單隊列網卡多核CPU的環(huán)境渣刷。
RPS本身并不能減少CPU的軟中斷次數(shù)鹦肿,而是將軟中斷從執(zhí)行硬中斷的CPU核心上分離至其他空閑CPU核心,減少單一CPU核心的中斷次數(shù)辅柴,降低軟中斷執(zhí)行時間箩溃。
Linux通過配置文件的方式指定哪些cpu核參與到報文的分發(fā)處理,配置文件存放的路徑是:/sys/class/net/(dev)/queues/rx-(n)/rps_cpus碌嘀。下屬命令設置核0涣旨,2,4股冗,6參與對rx-0的分發(fā)處理霹陡。
echo 55 > /sys/**class**/net/eth0/queues/rx-0/rps_cpus
RFS(Receive Flow Steering)
RPS將數(shù)據(jù)包軟中斷均衡至不同CPU,若處理數(shù)據(jù)包的應用程序所在CPU與軟中斷處理報文的CPU不一致,將大大降低CPU cache效率穆律。這里就需要通過RFS特性進行彌補吵瞻。RFS需要依賴于RPS丈氓,它跟RPS不同的是不再簡單的依據(jù)網絡報文來做hash,而是根據(jù)flow的特性,即application在哪個核上來運行去做hash癌压,從而使得有更好的數(shù)據(jù)局部性募强。所以RFS相比于RPS浪感,主要差別就是在選取分發(fā)處理報文的目標CPU上更卒,而RFS還需要依靠RPS提供的機制進行報文的后續(xù)處理。
Linux下RFS是默認關閉的洛口。開啟RFS需要修改下面兩個文件矫付。在一個8核環(huán)境下,rps_flow_cnt設置為4096第焰,則rps_sock_flow_entries設置為4096*8买优。對于內存充裕的環(huán)境可以適當調大相應參數(shù)設置。
echo 32768 **>** /proc/sys/net/core/rps_sock_flow_entries
echo 4096 **>** /sys/class/net/device/queues/rx-0/rps_flow_cnt
參考鏈接
http://aspirer.wang/?p=820
http://laoar.github.io/blog/2017/05/07/rps/
https://www.slideshare.net/gokzy/rpsrfs
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/network-rfs
https://tqr.ink/2017/07/09/implementation-of-rps-and-rfs/