全部產品
Search
文件中心

Elastic Compute Service:使用NetACC加速TCP應用

更新時間:Oct 13, 2024

對於對網路通訊效能要求高、需要低延遲和高輸送量的TCP應用,如果需要使用eRDMA加速網路通訊,可以通過NetACC,無需修改應用代碼即可適配eRDMA。本文為您介紹NetACC及其使用方法。

重要

NetACC當前處於公測階段。

NetACC簡介

NetACC(Network Accelerator)是一個使用者態網路加速庫,利用eRDMA的低時延、高吞吐等優勢,通過相容socket介面,實現對現有TCP應用的加速。

適用情境

NetACC適用於網路開銷較大的情境:

  • 高PPS(Packets per Second)情境:尤其是大量收發小包的情境。使用NetACC可以降低CPU開銷,提升系統吞吐能力,例如在Redis處理請求的情境中。

  • 對網路時延敏感的情境:eRDMA的網路時延比TCP更低,可以提升網路響應速度。

  • 反覆建立短串連的情境:NetACC可以最佳化二次串連的速度,加快連線速度,提升系統效能。

安裝NetACC

  • 安裝方式

    • 通過eRDMA驅動安裝

      安裝eRDMA驅動時候,NetACC也會一併安裝。關於eRDMA驅動的安裝,請參見為已有執行個體配置eRDMA

    • 單獨安裝

      如果您需要使用特定版本的NetACC或者您需要臨時使用NetACC等,您可以在ECS執行個體上執行以下命令,單獨安裝NetACC:

      sudo curl -fsSL https://netacc-release.oss-cn-hangzhou.aliyuncs.com/release/netacc_download_install.sh | sudo sh
  • 設定檔

    安裝NetACC後預設設定檔是/etc/netacc.conf,您可以在設定檔中配置NetACC的使用參數,如線程數、日誌路徑等。設定檔樣本如下:

    /etc/netacc.conf檔案樣本

    [netacc]
    # 一個buffer的size,一般發送資料區塊較大時適當調大這個參數可以提高效能;調小可以節省記憶體。
    # int
    NACC_SOR_MSG_SIZE=16384
    
    # rdma首次註冊的mr大小,調小可以節省記憶體
    #   NACC_SOR_MSG_SIZE的2的N次冪倍,最小為1倍
    NACC_RDMA_MR_MIN_INC_SIZE=16384
    
    # rdma最大單次註冊的mr大小(1MB ~ 512MB),調小可以節省記憶體
    #   NACC_RDMA_MR_MIN_INC_SIZE的2的N次冪倍,最小為1倍,最大為512M
    NACC_RDMA_MR_MAX_INC_SIZE=8388608
    
    # 單個QP承載的連結數,適當調大可以最佳化效能;特殊情境只能調成1
    # int
    NACC_SOR_CONN_PER_QP=1
    
    # netacc的線程數,如果吞吐較大可以適當增加
    # int
    NACC_SOR_IO_THREADS=1
    
    # 空QP淘汰時間,單位ms,0代表立即淘汰,-1代表不會淘汰
    NACC_EMPTY_QP_EXPIRE_MS=60000
    
    # 允許存在的空QP總數
    NACC_EMPTY_QP_MAX_ALL=100
    
    # 每個目的地址允許存在的空QP總數
    NACC_EMPTY_QP_MAX_PER=10
    
    # connect使用rdma建連的機率,0 ~ 100
    NACC_CONNECT_RDMA_PERCENT=100
    
    # 是否預設開啟RDMA
    NACC_ENABLE_RDMA_DEFAULT=1
    
    # 記錄層級
    # 0: TRACE
    # 1: DEBUG
    # 2: INFO
    # 3: WARN
    # 4: ERROR
    # 5: FATAL
    NACC_LOG_LEVEL=3
    
    # 日誌路徑
    NACC_LOG_PATH="/tmp/netacc.log"
    
    # 下面是不常用或者不需要設定的參數
    
    # 線程親和性設定
    # string
    NACC_SOR_AFFINITY=""
    
    # 是否優先使用TCP建立連結
    # bool
    NACC_CONN_TCP_FIRST=0

使用NetACC

您可以通過netacc_run命令或者設定環境變數LD_PRELOAD的方式在應用中整合NetACC。

netacc_run命令

netacc_run是一個工具,用於啟動應用程式時載入NetACC庫,通過在應用程式命令之前增加netacc_run,使用者可以比較方便地啟動應用程式並應用NetACC加速。

netacc_run提供了很多配置選項,比如IO線程數(-t)、QP複用數(-p)等,這些參數可以協助最佳化NetACC的效能。通過netacc_run命令設定的參數會覆蓋設定檔中的參數。

netacc_run命令參數說明

netacc_run -h
Usage: netacc_run [ OPTIONS ] COMMAND

Run COMMAND using NetACC for TCP sockets

OPTIONS:
   -f <path>   set config file, default /etc/netacc.conf
   -p <num>    set max connections per QP, default 1
   -t <num>    set netacc io threads, default 4
   -s <num>    set netacc message size, default 16384
   -F <num>    fast connect mode, default 0
   -d          enable debug mode
   -T          use TCP first in connect
   -P <num>    polling cq time ms
   -A <str>    affinity CPU list, 0 | 1-3 | 1,3,4
   -i <num>    set cq comp_vector, default 0
   -h          display this message
   -v          display version info
  • 使用樣本:

    以本文中Redis應用為例,在Redis命令之前增加netacc_run即可實現應用NetACC。

    • 啟動Redis服務

      netacc_run redis-server
    • 啟動Redis基準測試

      netacc_run redis-benchmark

設定LD_PRELOAD環境變數

LD_PRELOAD是一個環境變數,用於指定在程式啟動時積極式載入的共用庫。如果您需要在指令碼中自動化NetACC的載入,您可以通過LD_PRELOAD指定NetACC加速庫。

  1. 執行以下命令,查看NetACC動態庫的位置:

    ldconfig -p | grep netacc

    返回資訊如下所示:

    image

  2. 執行以下命令,設定LD_PRELOAD環境變數來指定預先載入庫:

    LD_PRELOAD=/lib64/libnetacc-preload.so your_application

    此處your_application是您想要加速的應用程式。

    使用樣本:以本文中Redis應用常用命令為例:

    • 啟動Redis服務

      LD_PRELOAD=/lib64/libnetacc-preload.so redis-server
    • 啟動Redis基準測試

      LD_PRELOAD=/lib64/libnetacc-preload.so redis-benchmark

    在指令碼中設定LD_PRELOAD環境變數

    如果您經常需要使用NetACC加速某個應用程式,或者您希望通過指令碼統一管理多個應用程式在啟動時候利用NetACC進行網路加速,您可以在指令碼中設定LD_PRELOAD環境變數。例如,您可以建立一個名為run_with_netacc的指令碼:

    #!/bin/bash
    LD_PRELOAD=/lib64/libnetacc-preload.so $@

    然後,您可以通過執行以下命令,運行應用程式:

    ./run_with_netacc.sh your_application

    使用樣本:以本文中Redis應用常用命令為例:

    • 啟動Redis服務

      ./run_with_netacc.sh redis-server
    • 啟動Redis基準測試

      ./run_with_netacc.sh redis-benchmark

NetACC監控

netacc_ss是NetACC中內建的監控工具,您可以執行netacc_ss命令監控使用了NetACC加速的TCP應用進程收發資料的狀態。在Server端和Client端均可以執行該命令進行監測。netacc_ss命令詳細說明如下:

netacc_ss命令說明

netacc_ss -h
Usage:
 netacc_ss: [-p] <pid> [options]...
 Show monitoring information of specified netacc process

Options:
 -c   clear unused sock file
 -h   display this help
 -s   display specified monitoring metric[s]. [all|cfg|cnt|mem|qp|sock]
      all: all monitoring information
      cfg: configuration information
      cnt: counter information[default]
      mem: memory information
      qp : queue pair information
      sock: socket information
 -v   display netacc version

Examples:
 netacc_ss -p 12345 -s mem,cnt

執行如下命令,查看使用了NetACC加速的TCP應用進程收發資料的狀態

netacc_ss -s all -p <進程ID>
說明

您可以通過執行ps -ef | grep <進程名稱>命令查詢進程ID。

Redis應用中使用NetACC

NetACC在Redis應用中的作用

  • 提升系統吞吐能力

    NetACC適用於處理每秒需要處理大量資料包的情境,在Redis處理大量請求時,可以降低CPU開銷並提升系統輸送量。

  • 提升網路響應速度

    對於需要快速網路響應的Redis應用,NetACC利用eRDMA提供的低時延特性,可以顯著提升網路響應速度。

Redis效能基準測試中使用NetACC

redis-benchmark是Redis內建的一個效能測試工具,它可以類比多個用戶端同時對Redis發送請求,以此來評估Redis伺服器在不同負載下的效能表現。

測試情境

redis-benchmark中使用NetACC,類比100個clients,4個threads,迴圈5000000次set操作。

redis-server常用命令參數說明

redis-server是啟動Redis伺服器的命令。您可以在執行個體上執行redis-server -h查看具體參數說明,本文中用到的參數說明如下:

redis-server --port 6379 --protected-mode no
  • --port 6379:指定Redis服務的啟動連接埠,預設不指定,為6379。

  • --protected-mode no:這個參數用來設定Redis伺服器是否運行在保護模式下。保護模式是一種安全特性,當啟用時,Redis只允許在本地主機(127.0.0.1 或 localhost)上進行串連,從而防止遠端連線。使用no作為參數值表示禁用保護模式,允許Redis接受來自任何 IP 位址的串連。

    重要

    關閉Redis服務的保護模式,這在生產環境中可能帶來安全風險,因此在開放的網路環境中使用時需要謹慎。

redis-benchmark常用命令參數說明

redis-benchmark是Redis內建的壓力測試工具,用於類比多個用戶端向Redis發送大量請求,以測試Redis的效能。您可以在執行個體上執行redis-benchmark --help查看具體參數說明,本文中用到的參數說明如下:

redis-benchmark -h 172.17.0.90 -p 6379 -c 100 -n 5000000 -r 10000 --threads 4 -d 512 -t set
  • -h 172.17.0.90:指定Redis服務所在伺服器的主機名稱或 IP 位址,這裡是172.17.0.90

  • -p 6379:指定Redis服務的啟動連接埠,如果使用了預設連接埠6379,則可以省略此配置,如果您的Redis服務啟動時候指定了其他連接埠,需要指定。

    說明

    您可以在Redis服務端通過sudo grep "^port" /<redis.conf檔案路徑>/redis.conf命令查詢,Redis預設設定檔路徑為/etc/redis.conf

  • -c 100:指定並發串連數,這裡是100個並發串連。

  • -n 5000000:指定請求總數,這裡是5000000個請求。

  • -r 10000:使用隨機鍵的範圍,這裡指定了10000個不同的鍵的範圍。這意味著測試中的SET命令將使用從0到9999的隨機整數作為鍵的一部分。

  • --threads 4:指定線程數,這裡是4個線程。redis-benchmark預設是單線程的,但某些系統可能允許使用多線程來類比並發。

  • -d 512:指定SET命令值的資料大小,這裡是512位元組。

  • -t set:指定只運行set測試。-t參數後面跟的是測試命令的名稱,這裡只測試set命令的效能。

這個命令的意思是,使用4個線程,每個線程100個並發串連,總共發送5000000個set請求到IP地址為172.17.0.90的Redis伺服器,每個請求的值是一個512位元組的隨機資料,並且使用的鍵是0到9999之間的隨機整數。

redis-benchmark常用測試結果指標說明

  • 輸送量(Throughput Summary):

    每秒請求數rps(requests per second):表示在測試期間伺服器每秒能夠處理的請求數量。例如332933.81 requests per second表示伺服器每秒可以處理約332934個請求。

  • 延遲(Latency Summary),單位為毫秒:

    • avg:平均延遲,即所有請求的平均回應時間。

    • min:最小延遲,即所有請求中的最小回應時間。

    • p50(50th percentile,中位元):一半的請求回應時間低於這個值。

    • p95(95th percentile):95%的請求回應時間低於這個值。

    • p99(99th percentile):99%的請求回應時間低於這個值。

    • max:最大延遲,即所有請求中的最大回應時間。

準備工作

購買兩台支援eRDMA的執行個體,勾選自動安裝eRDMA驅動,並且在主網卡開啟eRDMA網路介面。兩台ECS執行個體分別作為Redis的服務端和用戶端。

本樣本參數如下所示:

  • 鏡像:均為Alibaba Cloud Linux 3

  • 執行個體規格:均為ecs.g8ae.4xlarge

  • 執行個體主網卡的私網IP地址:Server端(172.17.0.90)、Client端(172.17.0.91)。在以下測試中,您需要根據實際情況替換IP地址。

    說明
    • 本文以在執行個體的主網卡上開啟eRDMA網路介面為例進行測試,那麼這裡的172.17.0.90即Redis服務端所在ECS執行個體的主網卡的私網IP地址。

    • 如果您是通過輔助彈性網卡上開啟eRDMA網路介面進行測試,那麼這裡的IP地址,需要改為您實際的輔助彈性網卡的私網IP地址。更多資訊,請參見建立新執行個體時配置eRDMA

建立過程重要參數樣本

建立過程中需注意以下配置項(其他參數,請參見自訂購買執行個體):

  • 執行個體規格和鏡像:請參見使用限制鏡像需要選中安裝eRDMA驅動。執行個體啟動過程中會自動安裝eRDMA驅動,無需您再手動安裝。

    image

  • 彈性網卡:在主網卡右側選中彈性RDMA介面

    重要

    建立執行個體時,僅支援為主網卡啟用彈性RDMA介面,且單台ECS執行個體最多隻能綁定一個啟用彈性RDMA介面的網卡。如果您需要使用輔助網卡配置eRDMA,只能在建立執行個體後,單獨建立輔助彈性網卡並為其啟用彈性RDMA介面,然後綁定至ECS執行個體上使用。具體操作,請參見建立輔助彈性網卡綁定輔助彈性網卡

    image

具體操作

  1. 分別遠端連線Server端和Client端的ECS執行個體。

    具體操作,請參見通過密碼或密鑰認證登入Linux執行個體

  2. 確認兩台ECS執行個體的eRDMA驅動安裝完成。

    在執行個體啟動後,您可以通過ibv_devinfo命令確認已安裝完畢:

    • 如果正確安裝完成後,命令返回如下所示:

      image

    • 如果尚未完成安裝,命令返回如下所示(eRDMA相關驅動程式的安裝可能需要幾分鐘,您可以稍後再嘗試):

      image

  3. 在兩台ECS執行個體上分別執行以下命令安裝Redis。

    sudo yum install -y redis

    安裝完成後,返回資訊如下所示:

    image

  4. 通過redis-benchmark進行Redis效能的基準測試。

    使用NetACC加速測試
    1. 在Server端的ECS執行個體上,執行以下命令,以NetACC加速的方式啟動Redis服務:

      netacc_run redis-server --port 6379 --protected-mode no
      說明

      正確啟動後,返回如下所示:

      image

    2. 在Client端的ECS執行個體上,執行以下命令,開啟Redis基準測試:

       netacc_run redis-benchmark -h 172.17.0.90 -p 6379 -c 100 -n 5000000 -r 10000 --threads 4 -d 512 -t set
      說明
      • 您需要替換對應的172.17.0.906379為您實際啟動Redis服務的伺服器的IP地址和連接埠號碼,詳見redis-benchmark常用命令參數說明

      • 不同的網路環境下測試結果不同,本文測試資料僅供參考,具體執行結果以您的實際環境為準。

      測試結束後,返回樣本內容如下

      ====== SET ======                                                      
        5000000 requests completed in 6.52 seconds
        100 parallel clients
        512 bytes payload
        keep alive: 1
        host configuration "save": 3600 1 300 100 60 10000
        host configuration "appendonly": no
        multi-thread: yes
        threads: 4
      
      Latency by percentile distribution:
      0.000% <= 0.039 milliseconds (cumulative count 3)
      50.000% <= 0.127 milliseconds (cumulative count 2677326)
      75.000% <= 0.143 milliseconds (cumulative count 3873096)
      87.500% <= 0.151 milliseconds (cumulative count 4437348)
      93.750% <= 0.159 milliseconds (cumulative count 4715347)
      96.875% <= 0.175 milliseconds (cumulative count 4890339)
      98.438% <= 0.183 milliseconds (cumulative count 4967042)
      99.609% <= 0.191 milliseconds (cumulative count 4991789)
      99.902% <= 0.207 milliseconds (cumulative count 4995847)
      99.951% <= 0.263 milliseconds (cumulative count 4997733)
      99.976% <= 0.303 milliseconds (cumulative count 4998853)
      99.988% <= 0.343 milliseconds (cumulative count 4999403)
      99.994% <= 0.367 milliseconds (cumulative count 4999704)
      99.997% <= 0.391 milliseconds (cumulative count 4999849)
      99.998% <= 2.407 milliseconds (cumulative count 4999924)
      99.999% <= 5.407 milliseconds (cumulative count 4999962)
      100.000% <= 6.847 milliseconds (cumulative count 4999981)
      100.000% <= 8.423 milliseconds (cumulative count 4999991)
      100.000% <= 8.919 milliseconds (cumulative count 4999996)
      100.000% <= 9.271 milliseconds (cumulative count 4999998)
      100.000% <= 9.471 milliseconds (cumulative count 4999999)
      100.000% <= 9.583 milliseconds (cumulative count 5000000)
      100.000% <= 9.583 milliseconds (cumulative count 5000000)
      
      Cumulative distribution of latencies:
      18.820% <= 0.103 milliseconds (cumulative count 941003)
      99.917% <= 0.207 milliseconds (cumulative count 4995847)
      99.977% <= 0.303 milliseconds (cumulative count 4998853)
      99.998% <= 0.407 milliseconds (cumulative count 4999879)
      99.998% <= 0.503 milliseconds (cumulative count 4999903)
      99.998% <= 0.703 milliseconds (cumulative count 4999904)
      99.998% <= 0.807 milliseconds (cumulative count 4999905)
      99.998% <= 0.903 milliseconds (cumulative count 4999906)
      99.998% <= 1.007 milliseconds (cumulative count 4999908)
      99.998% <= 1.103 milliseconds (cumulative count 4999909)
      99.998% <= 1.207 milliseconds (cumulative count 4999912)
      99.998% <= 1.407 milliseconds (cumulative count 4999913)
      99.998% <= 1.503 milliseconds (cumulative count 4999915)
      99.998% <= 1.607 milliseconds (cumulative count 4999916)
      99.998% <= 1.703 milliseconds (cumulative count 4999917)
      99.998% <= 1.807 milliseconds (cumulative count 4999918)
      99.998% <= 1.903 milliseconds (cumulative count 4999919)
      99.998% <= 2.103 milliseconds (cumulative count 4999920)
      99.999% <= 3.103 milliseconds (cumulative count 4999931)
      99.999% <= 4.103 milliseconds (cumulative count 4999944)
      99.999% <= 5.103 milliseconds (cumulative count 4999958)
      99.999% <= 6.103 milliseconds (cumulative count 4999971)
      100.000% <= 7.103 milliseconds (cumulative count 4999984)
      100.000% <= 8.103 milliseconds (cumulative count 4999989)
      100.000% <= 9.103 milliseconds (cumulative count 4999996)
      100.000% <= 10.103 milliseconds (cumulative count 5000000)
      
      Summary:
        throughput summary: 767341.94 requests per second
        latency summary (msec):
                avg       min       p50       p95       p99       max
              0.126     0.032     0.127     0.167     0.183     9.583

      可以看到最下面的Summary資訊,最後列印的是77萬左右的rps。關於指標詳細說明,詳見redis-benchmark常用測試結果指標說明

    測試過程中通過netacc_ss查看服務端監控

    在測試過程中,您可以在Server端的ECS執行個體上通過netacc_ss查看目前服務端監控資訊:

    • 執行以下命令,查看目前Redis服務的進程ID:

      ps -ef | grep redis-server

      返回資訊如下,可以看到redis-server的進程ID為114379:

      image

    • 執行以下命令,查看Redis服務目前的串連資訊及收發資料的狀態:

      netacc_ss -p 114379 -s all
      說明

      您需要將命令中的114379替換為您實際環境中Redis服務的進程的PID。詳見netacc_ss命令說明

      命令返回資訊如下,可以看到目前建立的socket串連都是RDMA串連。最右側4列是收發的資料量:

      image

    未使用NetACC加速測試
    1. 在Server端的ECS執行個體上,執行以下命令,啟動Redis服務:

      redis-server --port 6379 --protected-mode no --save
      說明

      您需要替換對應的6379為您實際啟動Redis服務的連接埠號碼,詳見redis-server常用命令參數說明

      正確啟動後,返回如下所示:

      image

    2. 在Client端的ECS執行個體上,執行以下命令,開啟Redis基準測試:

       redis-benchmark -h 172.17.0.90 -c 100 -n 5000000 -r 10000 --threads 4 -d 512 -t set
      說明
      • 您需要替換對應的172.17.0.906379為您實際啟動Redis服務的伺服器的IP地址和連接埠號碼, 詳見redis-benchmark常用命令參數說明

      • 不同的網路環境下測試結果不同,本文測試資料僅供參考,具體執行結果以您的實際環境為準。

      測試結束後,返回樣本內容如下

      ====== SET ======                                                         
        5000000 requests completed in 15.02 seconds
        100 parallel clients
        512 bytes payload
        keep alive: 1
        host configuration "save": 
        host configuration "appendonly": no
        multi-thread: yes
        threads: 4
      
      Latency by percentile distribution:
      0.000% <= 0.055 milliseconds (cumulative count 27)
      50.000% <= 0.287 milliseconds (cumulative count 2635010)
      75.000% <= 0.335 milliseconds (cumulative count 3782931)
      87.500% <= 0.367 milliseconds (cumulative count 4459136)
      93.750% <= 0.391 milliseconds (cumulative count 4720397)
      96.875% <= 0.415 milliseconds (cumulative count 4855130)
      98.438% <= 0.439 milliseconds (cumulative count 4936478)
      99.219% <= 0.455 milliseconds (cumulative count 4965765)
      99.609% <= 0.471 milliseconds (cumulative count 4984031)
      99.805% <= 0.487 milliseconds (cumulative count 4993326)
      99.902% <= 0.495 milliseconds (cumulative count 4995579)
      99.951% <= 0.511 milliseconds (cumulative count 4997659)
      99.976% <= 0.551 milliseconds (cumulative count 4998848)
      99.988% <= 0.599 milliseconds (cumulative count 4999468)
      99.994% <= 0.631 milliseconds (cumulative count 4999722)
      99.997% <= 0.663 milliseconds (cumulative count 4999862)
      99.998% <= 0.695 milliseconds (cumulative count 4999924)
      99.999% <= 0.759 milliseconds (cumulative count 4999964)
      100.000% <= 0.807 milliseconds (cumulative count 4999982)
      100.000% <= 1.935 milliseconds (cumulative count 4999993)
      100.000% <= 2.071 milliseconds (cumulative count 4999996)
      100.000% <= 2.111 milliseconds (cumulative count 4999998)
      100.000% <= 2.119 milliseconds (cumulative count 4999999)
      100.000% <= 2.143 milliseconds (cumulative count 5000000)
      100.000% <= 2.143 milliseconds (cumulative count 5000000)
      
      Cumulative distribution of latencies:
      0.028% <= 0.103 milliseconds (cumulative count 1377)
      0.985% <= 0.207 milliseconds (cumulative count 49228)
      60.094% <= 0.303 milliseconds (cumulative count 3004705)
      96.325% <= 0.407 milliseconds (cumulative count 4816230)
      99.938% <= 0.503 milliseconds (cumulative count 4996887)
      99.991% <= 0.607 milliseconds (cumulative count 4999546)
      99.999% <= 0.703 milliseconds (cumulative count 4999927)
      100.000% <= 0.807 milliseconds (cumulative count 4999982)
      100.000% <= 0.903 milliseconds (cumulative count 4999987)
      100.000% <= 1.903 milliseconds (cumulative count 4999990)
      100.000% <= 2.007 milliseconds (cumulative count 4999995)
      100.000% <= 2.103 milliseconds (cumulative count 4999997)
      100.000% <= 3.103 milliseconds (cumulative count 5000000)
      
      Summary:
        throughput summary: 332955.97 requests per second
        latency summary (msec):
                avg       min       p50       p95       p99       max
              0.292     0.048     0.287     0.399     0.447     2.143

      可以看到最下面的Summary資訊,最後列印的是33萬左右的rps。關於指標詳細說明,詳見redis-benchmark常用測試結果指標說明