聶永的博客

          記錄工作/學習的點點滴滴。

          Fastsocket學習筆記之網卡設置篇

          前言

          前面編譯安裝好了包含有fastsocket的內核模塊,以及fastsocket的動態鏈接庫libfsocket.so,下面其實就可以設置網卡了。

          下面為一些名詞解釋,上下文中需要使用到:

          • Rx:接收隊列
          • Tx:發送隊列

          本文網卡設置筆記內容,大部分來自于fastsocket源碼相對路徑fastsocket/scripts/;老規矩,先翻譯。

          網卡設置篇翻譯原文

          介紹

          nic.sh腳本負責網卡配置以盡可能的最大化受益于fastsocket帶來的問題。給定一個網卡接口, 它調整接口的各種特性以及一些系統配置。

          相關配置

          中斷和CPU的親和性

          每個網卡硬件隊列及其關聯中斷綁定到不同的CPU核心。若硬件隊列數大于CPU核數,隊列需要配置成循環round-robin方式, Irqbalance服務需要被禁用以防其更改配置。

          中斷閥速率

          nic.sh腳本通過ethtool命令設置每秒中斷數上限,防止中斷風暴。兩個Rx中斷間隔設置成至少333us,約3000個中斷每秒。

          RPS

          為每個CPU核心與不同的網卡硬件隊列之間建立一一映射對應關系,這樣CPU核心就可以很均勻地處理網絡數據包。當網卡硬件隊列小于CPU內核數,nic.sh腳本利用RPS (Receive Packet Steering)軟件方式平衡進入流量負載,這樣CPU和硬件隊列不存在對應關系。RPS機制可以讓進入的數據包自由分發到任一CPU核上。

          網卡接收產生的中斷可以均衡分配到對應CPU上。

          XPS

          XPS (Transmit Packet Steering) 建立CPU內核和Tx發送隊列映射對應關系,掌控出站數據包。系統有N個CPU核心,腳本會設置XPS至少存在N個Tx隊列在網卡接口上,這樣就可以建立CPU內核和Tx隊列1對1的映射關系。

          網卡傳送數據產生的中斷一樣可以均很分配到CPU上,避免單個CPU核心過于繁忙。

          IPTABLES

          壓測時,防火墻iptables的規則會占用更多的CPU周期,有所降低網絡堆棧性能。因此nic.sh腳本若檢測到iptables后臺運行中會直接輸出報警信息,提示關閉之。

          nic.sh腳本腳本分析

          經過驗證好用的Intel和博通系列千兆和萬兆網卡列表:

          # igb
          "Intel Corporation 82576 Gigabit Network Connection (rev 01)"
          "Intel Corporation I350 Gigabit Network Connection (rev 01)"
          # ixgbe
          "Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Connection (rev 01)"
          "Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)"
          # tg3
          "Broadcom Corporation NetXtreme BCM5720 Gigabit Ethernet PCIe"
          "Broadcom Corporation NetXtreme BCM5761 Gigabit Ethernet PCIe (rev 10)"
          # bnx2
          "Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet (rev 12)"
          "Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)"
          

          若當前服務器沒有以上網卡,會警告一下,無礙。

          這里把一些常規性的CPU、網卡驅動、網絡隊列情況檢查單獨抽取出來,重溫好多已經遺忘的命令,有改變,這樣寫較簡單嘛,便于以后使用:

          • 直接查看CPU核數:grep -c processor /proc/cpuinfo
          • 查看網卡軟接收隊列數:ls /sys/class/net/eth0/queues | grep -c rx
          • 查看網卡軟發生隊列數:ls /sys/class/net/eth0/queues | grep -c tx
          • 查看當前網卡硬件隊列數:egrep -c eth0 /proc/interrupts
          • 查看網卡名稱和版本號:lspci | grep Ethernet | sed "s/Ethernet controller: //g"
          • 查看網卡驅動名稱:ethtool -i eth0 | grep driver

          腳本先是獲取CPU、網卡等信息,接著設置中斷單位秒內吞吐量: ethtool -C eth0 rx-usecs 333 > /dev/null 2>&1

          啟用XPS,充分借助網卡發送隊列,提升網卡發送吞吐量,是有條件限制的,發送隊列數要大于CPU核數:

          if [[ $TX_QUEUES -ge $CORES ]]; then
              for i in $(seq 0 $((CORES-1))); do
               cpuid_to_mask $((i%CORES)) | xargs -i echo {} > /sys/class/net/$IFACE/queues/tx-$i/xps_cpus
              done
              info_msg "    XPS enabled"
          fi
          

          接著判斷是否可以啟用PRS,省去手動設置的麻煩,但啟用RPS前提是CPU核數與網卡硬件隊列不相等:

          if [[ ! $HW_QUEUES == $CORES ]]; then
              for i in /sys/class/net/$IFACE/queues/rx-*; do
               printf "%x\n" $((2**CORES-1)) | xargs -i echo {} > $i/rps_cpus;
              done
              info_msg "    RPS enabled"
          else
              for i in /sys/class/net/$IFACE/queues/rx-*; do
               echo 0 > $i/rps_cpus;
              done
              info_msg "    RPS disabled"
          fi
          

          若沒有使用fastsocket,單純借助于RPS,會帶來處理中斷的CPU和處理當前數據包的CPU不是同一個,自然會造成CPU Cache Miss(CPU緩存丟失),造成少許的性能影響,為了避免這種情況,人們會依賴于RFS(Receive Flow Steering)。

          使用了fastsocket后,就不用這么麻煩了。

          irqbalance和fastsocket有沖突,會強制禁用:

          if ps aux | grep irqbalance | grep -v grep; then
              info_msg "Disable irqbalance..."
              # XXX Do we have a more moderate way to do this?
              killall irqbalance > /dev/null 2>&1
          fi
          

          腳本也包含了設置中斷和CPU的親和性:

          i=0
          intr_list $IFACE $DRIVER | while read irq; do
              cpuid_to_mask $((i%CORES)) | xargs -i echo {} > /proc/irq/$irq/smp_affinity
              i=$((i+1))
          done
          

          若iptables服務存在,會友善建議禁用會好一些,畢竟會帶來性能損耗。文件打開句柄不大于1024,腳本同樣會提醒,怎么設置文件打開句柄,可以參考以前博文。

          Linux系統網絡堆棧的常規擴展優化措施

          針對不使用fastsocket的服務器,當前比較流行的針對網卡的網絡堆棧性能擴展、優化措施,一般會使用到RSS、RPS、RFS、XFS等方式,以便充分利用CPU多核和硬件網卡等自身性能,達到并行/并發處理的目的。下面總結一個表格,可以湊合看一下。


          RSS
          (Receive Side Scaling)
          RPS
          (Receive Packet Steering)
          RFS
          (Receive Flow Steering)
          Accelerated RFS
          (Accelerated Receive Flow Steering)
          XPS
          (Transmit Packet Steering)
          解決問題 網卡和驅動支持 軟件方式實現RSS 數據包產生的中斷和應用處理在同一個CPU上 基于RFS硬件加速的負載平衡機制 智能選擇網卡多隊列的隊列快速發包
          內核支持 2.6.36開始引入,需要硬件支持 2.6.35 2.6.35 2.6.35 2.6.38
          建議 網卡隊列數和物理核數一直 至此多隊列的網卡若RSS已經配置了,則不需要RPS了 需要rps_sock_flow_entries和rps_flow_cnt屬性 需要網卡設備和驅動都支持加速。并且要求ntuple過濾已經通過ethtool啟用 單傳輸隊列的網卡無效,若隊列比CPU少,共享指定隊列的CPU最好是與處理傳輸硬中斷的CPU共享緩存的CPU
          fastsocket 網卡特性 改進版RPS,性能提升 源碼包含,文檔沒有涉及 文檔沒有涉及 要求發送隊列數要大于CPU核數
          傳送方向 網卡接收 內核接收 CPU接收處理 加速并接收 網卡發送數據

          更具體優化措施,可以參考文檔:Scaling in the Linux Networking Stack

          另,若網卡支持Flow Director Filters特性(這里有一個非常有趣的動畫介紹,Intel® Ethernet Flow Director,值得一看),那么可以結合Fastsocket一起加速。比如,在其所作Redis長連接測試中,啟用Flow-Director特性要比禁用可以帶來25%的性能提升。

          自然軟硬結合,可以做的更好一些嘛。

          延伸閱讀:多隊列網卡簡介

          小結

          以上記錄了學習fastsocket的網卡設置腳本方面筆記。

          不過呢,nic.sh腳本,值得收藏,無論使不使用fastsocket,對線上服務器網卡調優都是不錯選擇哦。

          posted on 2015-01-30 16:49 nieyong 閱讀(9896) 評論(1)  編輯  收藏 所屬分類: Socket

          評論

          # re: Fastsocket學習筆記之網卡設置篇 2015-01-30 22:27 京山游俠

          mark。  回復  更多評論   

          公告

          所有文章皆為原創,若轉載請標明出處,謝謝~

          新浪微博,歡迎關注:

          導航

          <2015年1月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          統計

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 新龙县| 玉溪市| 始兴县| 岢岚县| 上饶县| 清水河县| 祁门县| 呈贡县| 闸北区| 昆明市| 出国| 博爱县| 青神县| 湄潭县| 永寿县| 甘南县| 邵武市| 蚌埠市| 黎川县| 察雅县| 尼勒克县| 伊宁市| 嘉义县| 陇川县| 灵川县| 闽侯县| 卢龙县| 黔西县| 桃源县| 双辽市| 张北县| 永善县| 许昌市| 依安县| 奉节县| 巍山| 万年县| 都江堰市| 正蓝旗| 孝昌县| 宾阳县|