在存儲系統中為了提高後端裝置的吞吐量,往往需要采用多網卡綁定技術。例如,後端存儲最大能夠提供300MB/s的吞吐量,是以需要采用3塊1Gps的網卡并發傳輸才可以達到峰值性能。那麼,從研發的角度來看如何實作多網卡綁定呢?這裡對提高吞吐量用途的多網卡綁定技術進行深入分析。
多網卡綁定一方面能夠提高網絡吞吐量,另一方面也可以增強網絡高可用。這裡對高可用應用的多網卡綁定技術不做讨論。從軟體的角度來看,多網卡綁定實際上隻需要提供一個額外的bond驅動程式即可,通過該虛拟網卡驅動程式可以将實際多塊網卡屏蔽,對TCP/IP協定層而言隻存在一個Bond網卡。在Bond驅動程式中實作網絡流量的負載平衡(load balance),将一個網絡請求重定位到不同的網卡(NIC)上,以此來提高總體網絡的性能。多網卡綁定的軟體層次架構如下圖所示:
考慮一下,為了綁定多塊網卡,其技術難點在于什麼地方?網絡交換機是通過實體位址進行端口路由的,對于不支援IEEE802.3ab協定的普通交換機而言,其隻能連接配接不同實體位址的網卡,否則交換機将會無法正常工作。每個網絡擴充卡具備一個IP位址,而每個IP位址又通過ARP協定和一個MAC位址綁定在一起。由此分析,在沒有交換機的配合下,我們很難實作想象中完美的多網卡綁定通信模型:
如果ARP協定能夠支援将一個IP位址映射到多個MAC位址,那麼在Bond驅動層我們完全可以實作上圖所示的多網卡綁定通信模型。在實際IP網絡中,為了達到上述綁定效果,需要交換機的802.3ab協定支援,通過交換機實作round robin方式的網卡綁定,純軟體方法無法做到。基于802.3ab協定的多網卡綁定如下圖所示:
在802.3ab的支援下,Server端所有網卡的MAC位址全部配置成一個,例如MAC-A,然後在交換機端将這些端口聚合起來。交換機在接收到資料封包之後會輪詢這些端口将資料封包發送給Bond驅動,Bond驅動想發送資料的時候同樣通過輪詢方法将資料封包交給不同網卡進行傳輸。這種方法可以對Client端進行透明,從整體架構上來說比較簡單,唯一缺點是需要交換機的支援。個人認為對于存儲系統而言,這種方案是目前網卡綁定的最佳方式。
除了交換機支援的解決方案之外,當然我們也可以采用純軟體的方法,隻不過這種綁定在有些應用中有所局限。一種比較簡單的綁定思想是隻對Transmit進行綁定(Linux Bond5 Mode)。該綁定模型如下圖所示:
在這種模型中,Client向Server發送ARP請求,Server将Bond擴充卡的MAC位址告訴給Client。Bond擴充卡驅動程式會選擇一個Slave-NIC的MAC位址作為自己的MAC位址。例如,Client-B向Server發送ARP請求,Server會将MAC-C位址告訴給Client-B。是以,Client端發送的資料封包會全部被MAC-C位址所在的NIC接收。換句話說,所有Client了解到Server的MAC位址都是MAC-C,Client看不到Server端其他NIC的MAC位址。在Server端發送資料封包的時候,Server端封裝的Source-Address都是Bond擴充卡配置的MAC位址,目的位址是Client NIC所在的MAC位址。在資料發送的時候,Bond驅動程式會根據一定算法将發送封包均勻配置設定到所有NIC上,由于NIC驅動不會更改以太網封包中的内容,通過這種方式,Bond驅動可以充分利用所有網卡的實體帶寬。這種方法實作簡單,Bond驅動程式不需要截獲傳輸封包的任何資料,隻需要選擇網卡進行資料傳輸即可。由于Client隻知道一個網卡的實體位址,是以無法實作多網卡的并發資料接收,隻能實作并發資料發送。對于隻關注資料發送吞吐量的應用,這種解決方案還是非常有效的。
在存儲應用中,需要考慮雙向資料傳輸的吞吐量,上述解決方案存在資料接收瓶頸。那麼如何才能使得Server進行高效的雙向資料傳輸呢?其關鍵問題在于需要讓Client知道不同網卡的MAC位址,上述解決方案中,所有的Client隻知道一個MAC位址。為了達到雙向傳輸的效果,Bond驅動程式需要截取ARP封包和資料封包,并且修改MAC位址。這種網卡綁定的資料傳輸模型(Linux Bond6 Mode)如下圖所示:
在Client向Server發送ARP請求的時候,Bond驅動程式會截取傳回給Client的ARP應答封包,并且選取一個Slave-NIC的MAC位址,用這個MAC位址修改ARP應答封包。通過這種方式,Server将一塊網卡配置設定給一個Client,每個Client配置設定得到不同NIC的MAC位址,進而Client可以通過不同的網卡實作資料傳輸。在多Client的情況下,實作Server端并發資料接收。在Server端資料發送的時候,Bond驅動程式需要截取發送資料封包,并且修改以太網封包中的源MAC位址(bond_alb_xmit函數實作了Bond的資料發送功能),然後通過算法選擇一塊NIC發送資料,實作并發資料傳輸(資料封包發送并不固定在一塊網卡上,上圖的示範模型隻是一個特例)。這種方案和上述方案最大的不同是Bond驅動程式需要截獲ARP和正常的資料封包,并進行處理。從Client而言,每個Client的資料發送可以綁定到一個單獨的NIC卡上。
這裡對多網卡的綁定技術進行了一些總結,這些技術還是值得慢慢品味的。