linux的中斷負載均衡和RPS
中斷型別
異常:又叫同步中斷,由cpu產生,只有在一條指令終止後CPU才發出中斷;取決於eip的值,又可分為故障fault,陷阱trap和中止abort;
中斷:硬體外設依照CPU時鐘訊號隨機產生的;分為 可遮蔽和不可遮蔽;
兩者分別又稱為軟體中斷(不是軟中斷)和硬體中斷,本文只描述後一種;
硬體中斷的處理分為兩個階段,為top half和bottom half;
上半部只完成一些比較緊急和必要的功能,比如對中斷的到達進行響應確認,最好情況下(SA_INTERRUPT),同級其他中斷被遮蔽(鎖定當前中斷線),最壞情況下,當前CPU所有中斷被遮蔽;
下半部則是完成其他那些可以延緩處理的部分,在下半部的執行期間其他CPU可以同時響應軟中斷。
下半部最常見為軟中斷softirq和tasklet,softirq為可延遲函式,tasklet建立在其上;
linux 2.6提供6個softirq,而tasklet可使用HI_SOFTIRQ和TASKLET_SOFTIRQ,
以網路卡處理為例:
1 從網路卡硬體的緩衝區中把網路卡收到的網路資料包複製到系統記憶體中;
2 對這個資料包進行 TCP/IP 協議棧的處理;
3 透過 socket將資料包傳入使用者空間。
如果不分段,在資料傳入使用者空間之前,所有這些處理都會在中斷服務程式中完成,在這段時間內,CPU將不再響應網路卡發來的其他中斷,網路卡將因為自身快取的不足而丟失資料。
核心執行緒
ksoftirqd
每個CPU各有一個,軟中斷可以自我啟用,對於比較繁華的業務譬如網路卡資料包氾濫,可能會耗盡CPU;
執行期間產生的新的軟中斷,可以有兩種選擇:1 忽略,等到下一次時鐘中斷才執行;2 反覆檢查並執行,可能導致使用者態程式一直等待;
ksfotirqd試圖找到一個平衡點,若已經執行的軟中斷又被啟用,do_softirq()喚醒該核心執行緒並終止當前執行,允許使用者程式搶佔執行(核心執行緒優先順序較低);
kirqd
kirqd週期性呼叫do_irq_balance(),跟蹤最近時間間隔內每個CPU的中斷次數,若分佈不平衡則嘗試轉移IRQ;
可透過service irqbalance stop關閉;
巢狀執行
核心控制路徑可以任意巢狀,即中斷可以巢狀,前提是中斷處理程式不能阻塞, 即執行期間不可發生程式切換;。
核心控制路徑:中斷切換需要在核心態堆疊儲存程式計數器的當前值(eip和cs暫存器),其執行的程式碼不是一個程式(比程式切換輕量級);
CPU affinity
每個能發出中斷的外設都有一條IRQ輸出線,
I/O APIC包含中斷重定向表和可程式設計暫存器,透過修改中斷重定向表,可以把中斷資訊發生到特定CPU,即CPU affinity;
每個CPU都有一個本地的APIC,本地APIC都連線到一個外部的I/OAPIC,裝置的IRQ線連線到I/OAPIC。I/OAPIC接收到中斷訊號,根據一定的演算法,再將中斷分配給其中某個本地APIC。也可以透過配置指定某個中斷分配給某個CPU。
軟中斷負載均衡與RPS
對於多佇列網路卡,可直接對網路卡接收佇列設定CPU affinity,單佇列網路卡可透過軟體先模擬出多佇列,然後對每個佇列設定affinity,此即為RPS;
RPS 全稱是 Receive Packet Steering, 這是Google工程師 Tom Herbert (therbert@google.com )提交的核心補丁;
原理:
linux現在網路卡的驅動支援兩種模式,一種是NAPI,一種是非NAPI模式,這兩種模式的區別:
在NAPI中,中斷收到資料包後呼叫__napi_schedule排程軟中斷,然後軟中斷處理函式中會呼叫註冊的poll回掉函式中呼叫netif_receive_skb將資料包傳送到3層,沒有進行任何的軟中斷負載均衡。
在非NAPI中,中斷收到資料包後呼叫netif_rx,這個函式會將資料包儲存到input_pkt_queue,然後排程軟中斷,這裡為了相容 NAPI的驅動,他的poll方法預設是process_backlog,最終這個函式會從input_pkt_queue中取得資料包然後傳送到3層。
不管是NAPI還是非NAPI的話都無法做到軟中斷的負載均衡,因為軟中斷此時都是執行在在硬體中斷相應的cpu上。也就是說如果始終是cpu0相應網路卡的硬體中斷,那麼始終都是cpu0在處理軟中斷,而此時cpu1就被浪費了,因為無法並行的執行多個軟中斷。
google的這個patch的基本原理是這樣的,根據資料包的源地址,目的地址以及目的和源埠計算出一個hash值,然後根據這個hash值來選擇軟中斷執行的cpu,從上層來看,也就是說將每個連線和cpu繫結,並透過這個 hash值,來均衡軟中斷在多個cpu上。
實現方式
在netif_receive_skb()之後還有很多處理工作,也是在軟中斷上下文中,而且處理工作是和程式無關的。這樣就可以把後續的處理工作移到其它的CPU上執行,這也是網路協議棧的軟中斷的負載均衡的基本思想;
RPS的實現流程:將資料包加入其它CPU的接收佇列sd->input_pkt_queue,並啟用其它CPU的NAPI結構sd->backlog,則其它CPU將會在自己的軟中斷中執行process_backlog,process_backlog將會接收sd->input_pkt_queue佇列中的所有資料包,並呼叫__netif_receive_skb()執行後續工作。
http://blog.chinaunix.net/uid-233938-id-3362368.html
RPS也有兩種實現方式:
1 每佇列繫結到1個CPU
/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-4/rps_cpus 00000010
/sys/class/net/eth0/queues/rx-5/rps_cpus 00000020
/sys/class/net/eth0/queues/rx-6/rps_cpus 00000040
/sys/class/net/eth0/queues/rx-7/rps_cpus 00000080
2 每佇列繫結到多個或所有CPU
/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-4/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-5/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-6/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-7/rps_cpus 000000ff
RFS
http://blog.chinaunix.net/uid-233938-id-3362368.html
全稱是 Receive Flow Steering, 這也是Tom提交的核心補丁,它是用來配合RPS補丁使用的,是RPS補丁的擴充套件補丁,它把接收的資料包送達應用所在的CPU上,提高cache的命中率。
由於RPS只是單純的把同一流的資料包分發給同一個CPU核來處理了,但是有可能出現這樣的情況,即給該資料流分發的CPU核和執行處理該資料流的應用程式的CPU核不是同一個:資料包均衡到不同的cpu,這個時候如果應用程式所在的cpu和軟中斷處理的cpu不是同一個,此時對於cpu cache的影響會很大。那麼RFS補丁就是用來確保應用程式處理的cpu跟軟中斷處理的cpu是同一個,這樣就充分利用cpu的cache。
不僅由於cache快取的問題,還有一些其它的原因需要把特徵相同的資料包分配給同一個CPU處理,例如:
TCP的IP包的分段重組問題,一旦亂序就要重傳,這種情況下,一個linux主機如果只是作為一臺路由器的話,那麼進入系統的一個TCP包的不同分段如果被不同的cpu處理並向一個網路卡轉發了,那麼同步問題會很麻煩的,如果你不做同步處理,那麼很可能後面的段被一個cpu先發出去了,那麼在真正的接收方接收到亂序的包後就會請求重發,這是不希望的,因此還是一個cpu序列處理好。
現在再回過頭來看儲霸的帖子,感覺輕鬆不少;http://blog.yufeng.info/archives/2037
1 某個CPU的軟中斷偏高:mpstat;
2 調查是誰惹的禍:stap監控softirq.entry,workqueue.execute和irq_handler.entry,分別為軟中斷,工作佇列和irq中斷線;確定是網路卡引起的;
3 解決方案:1 換用多佇列網路卡 + SMP affinity;2 採用RPS軟體模擬多佇列;
其他連結
http://blog.itpub.net/15480802/viewspace-753982/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-1408527/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux LVS 負載均衡Linux負載
- 在Linux中,如何實現負載均衡?Linux負載
- 解密負載均衡技術和負載均衡演算法解密負載演算法
- Kubernetes 中的 gRPC 負載均衡RPC負載
- 【知識分享】四層負載均衡和七層負載均衡負載
- 代理和負載均衡概述負載
- 在Linux中,什麼是負載均衡?它是如何工作的?Linux負載
- 負載均衡和動態負載均衡分別是什麼?-VeCloud負載Cloud
- 做了反向代理和負載均衡的nginx配置檔案簡單示例(nginx.conf) HTTP負載均衡/TCP負載均衡負載NginxHTTPTCP
- gRPC負載均衡(自定義負載均衡策略)RPC負載
- gRPC負載均衡(客戶端負載均衡)RPC負載客戶端
- 負載均衡是什麼?怎麼理解負載均衡的部署方式和工作原理負載
- 在Linux中,nginx反向代理和負載均衡實現原理是什麼?LinuxNginx負載
- 負載均衡負載
- dubbo叢集和負載均衡負載
- gRPC的負載均衡RPC負載
- CDN和負載均衡的基本瞭解負載
- Linux環境下Nginx及負載均衡LinuxNginx負載
- nginx負載均衡Nginx負載
- LVS 負載均衡負載
- 【Nginx】負載均衡Nginx負載
- NGINX 負載均衡Nginx負載
- LoadBalancer負載均衡負載
- IP負載均衡負載
- WebSocket負載均衡Web負載
- 負載均衡---ribbon負載
- Kubernetes中負載均衡功能簡介負載
- 負載均衡的種類負載
- OceanBase 負載均衡的魅力負載
- 4.8 負載均衡的概念負載
- 負載均衡的那些事?負載
- 負載均衡技術(一)———負載均衡技術介紹負載
- 在Linux中,什麼是負載均衡,並且如何在Linux中實現它。Linux負載
- 負載均衡技術(二)———常用負載均衡服務介紹負載
- dubbo容錯機制和負載均衡負載
- 剖析HBase負載均衡和效能指標負載指標
- windows第七層負載均衡 基於IIS的ARR負載均衡詳解Windows負載
- 負載均衡補充負載
- 負載均衡4層負載