linux內核軟中斷引起大量丟包

最近用linux做nat多出口時,遇到的幾個問題,經過一個星期的資料查找跟具體實踐終於給解決了,由於的問題複雜性,加之個人水平十分有限,解決的過程十分的痛苦,爲了使更多的人,不痛苦或者少痛苦一點,介紹一下問題解決的過程。
先說說環境
1.硬件:DELL R410
2.網卡:板載1000M BCM5709
2.OS: RHEL 5.5 x86_64
3.KERNEL: 2.6.18-194.el5
所出現的問題
1.網卡毫無徵兆的down掉,而且沒有任何log信息
2.當流量增大時,不到理論上限的1/3時機器出現網絡延遲嚴重,伴隨大量的丟包
3.機器的cpu軟中斷不均衡,只有1個cpu處理軟中斷,並且該cpu的軟中斷週期性的達到100%
4.內外網網卡做nat丟包數據量不一致,差別很大,不在同一個數量級
想必第一個問題,大部分使用bcm網卡,rhel 5.3以後得機器都會遇到這種情況,網上的資料比較的多,我也不多囉嗦了,直接升級網卡驅動就可以解決了。第二,三,四其實是同一個問題都是由於網卡中斷過多,cpu處理不過來(準確的說,cpu分配不均衡,導致只有一個cpu處理,處理不過來),引起丟包,那麼爲什麼兩個網卡丟包的數量級不一樣呢,下面從原理上進行解釋,既然是做nat多出口,那麼就有大量的路由信息,是一個網絡應用,當一個數據包請求nat時,數據包先被網卡驅動的數據接收,網卡收到數據時,觸發中斷。在中斷執行例程中,把skb掛入輸入隊列,並觸發軟中斷。稍後的某個時刻,當軟中斷執行時,再從該隊列中把skb取下來,投遞給上層協議。
如果在這個過程當中cpu沒有及時處理完這個隊列導致網卡的buffer滿了,網卡將直接丟棄該數據包。這裏牽涉到2個隊列,一個是tx,一個是rx,它的隊列的大小默認都是255,可以通過ethtool -g eth0(你指定的網卡),爲了防止丟包,當時我通過ethtool -G eth0 rx xxx 把它調大了,但是調大以後,還是杯水車薪啊,通過ethtool -S eth0 |grep rx_fw_discards,發現數值還是不停的在增長,也就是說還在不停的丟包,cpu處理不過來,這時候找到網上有人在利用lvs時也遇到這個問題,cpu軟中斷分配不均衡,只有一個cpu處理軟中斷的問題,網上的資料五花八門,有建議使用修改設備中斷方式。即通過修改設置中斷/proc/irq/${網卡中斷號}/smp_affinit這時候,我也修改過,沒有什麼實質的效果,
從官方的bug報告,https://bugzilla.redhat.com/show_bug.cgi?id=520888,其中提到rhel5.6已經修復了這個bug,這其中也提到目前我們的版本可以升級內核到kernel-2.6.18-194.3.1.el5可以解決這個問題。
紅帽子官方修復報告中的說明如下:http://rhn.redhat.com/errata/RHSA-2010-0398.html,我們升級了這個內核算是解決單核處理軟中斷的問題,升級後各個cpu已經能夠平均的分配這個軟中斷,也不丟包了,那麼爲什麼cpu處理不過來這個軟中斷呢,數據量並不是特別的大啊,上層應用接到這個數據包後,通過路由協議,找到某個出口給nat出去,找nat出口是需要查找路由表,查詢路由表是一件很耗時的工作,而每一個不同源地址,不同目的地址的數據包都得重新查找一次路由表,導致cpu處理不過來,爲了提高路由查詢的效率。Linux內核引用了路由緩存,用於減少對路由表的查詢。Linux的路由緩存是被設計來與協議無關的獨立子系統,查看路由緩存可以通過命令route -Cn,由於路由緩存當中是採用hash算法進行才找,它的查找速度非常之快,既然是cache就有超時這一概念。系統默認爲10分鐘,可以通過這個文件進行查看和修改/proc/sys/net/ipv4/route/secret_interval。而當路由緩存當中未找到或者已經超時的路由信息纔開始查找路由表,查詢到的結果保存在路由緩存中。如果路由表越大,那麼查詢的時間就越長,一個新的連接進來後或者是老連接cache超時後,佔用大量的cpu查詢時間,導致cpu週期性的軟中斷出現100%,而兩個網卡丟包的情況來看不均衡也是因爲用戶的數據包是經過其中一個網卡進來後查詢路由表耗時過長,cpu處理不過來,導致那塊網卡的隊列滿了,丟包嚴重。當然在路由表變動不大的情況下可以加大cache的時間,修改上述內容後,從我監測的情況來看,扛流量能力得到了大大的提升。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章