2.4高性能网络设计专栏-基于dpdk的用户态协议栈的实现

a. dpdk的环境搭建

1. 配置多队列网卡

使用cat /proc/interrupts | grep ens160可查看网卡ens160情况, 如果显式的行数只有1需要修改配置,编辑Vmware虚拟机的配置文件,以.vmx为后缀,添加这两行:
image
image

小问题

配置网卡的这时候我遇到了个小问题,最后解决了,总结一下路程:
我想给我的ubuntu虚拟机新添一个网卡ens33,然后ens33专门负责跟主机ssh连接,然后ens160专门处理多队列网卡。于是我在虚拟机设置里专门为其分配了一块ens33网卡。
image

但是重启后,发现主机无法ping通,然后折腾了半天。
输入ifconfig & ip a发现我的两块网卡的状态是'down':
image
上网搜索后发现可以使用下面的命令临时解决:

sudo ip link set ens33 up
sudo dhclient ens33
sudo systemctl restart NetworkManager

此时就主机就可以正常连接和ping通这台虚拟机了,但是这种方法治标不治本,下次重启虚拟机网卡还是不工作。
我们需要借助下面的方法来解决问题。
方法就是停止并禁用桌面版的 NetworkManager, 改用服务器级网络服务 networkd 来管理。

# 停止并禁用 NetworkManager
sudo systemctl stop NetworkManager
sudo systemctl disable NetworkManager
# 启用服务器级网络服务
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd
# Netplan 配置, 建议在root用户下进行
sudo vim /etc/netplan/01-server-config.yaml

仿照下面的内容修改

network:
  version: 2
  renderer: networkd   # 核心修改:切换到底层服务,不再依赖图形界面
  ethernets:
    # 管理网卡 (ens33)
    # 对应 VMX 中的 ethernet0 (Slot 33)
    ens33:
      dhcp4: true
      dhcp4-overrides:
        route-metric: 100
    ens160:
      dhcp4: true
      dhcp4-overrides:
        use-routes: false  # 关键:不抢网关,保证 SSH 稳定
        route-metric: 200
# 修正权限
sudo chmod 600 /etc/netplan/01-server-config.yaml
sudo netplan apply
sudo reboot

另一个解决方法

sudo vim /etc/network/interfaces

按照下面的配置,也就是ens33(桥接模式作为ssh连接的机器,负责联通主机),ens160作为DPDK网卡配置

image

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
# NAT
auto ens33
iface ens33 inet dhcp
# DODK
auto ens160
iface ens160 inet manual
    up ip link set ens160 up
    down ip link set ens160 down

image
然后reboot重启也可以解决

2. hugepage, 大页/巨页

页(page)是虚拟内存中固定大小的块。操作系统将进程的虚拟地址空间划分为多个页,每个页的大小通常是 4 KB

DPDK需要使用到大页内存,在高并发海量大数据包的场景下,常规的4KB内存页面无法有效承载的,所有我们需要配置大页为2M或者1G,大大降低同等内存条件下的页表项,进而减少页表查询和缺页中断。

sudo vim /etc/default/grub

GRUB_CMDLINE_LINUX追加这三个配置, "default_hugepagesz=1G hugepagesz=1G hugepages=1024"
image

# 更新
sudo update-grub
# 重启虚拟机

下载并且配置DPDK编译环境

ubuntu22.04安装dpdk22.07

参考安装地址
下载网站:https://core.dpdk.org/download/ ,由于我的ubuntu是22.04版本,这里选择dpdk 22.07版本。
(我也尝试使用dpdk-19.08.02版本了,但编译时,内核GCC版本不适配,所以选择dpdk 22.07, 可以看下文有ubuntu16.04安装dpdk19.08)

wget https://fast.dpdk.org/rel/dpdk-22.07.tar.xz
# 解压到虚拟机的`/dpdk-22.07`目录下。
tar xf dpdk-22.07.tar.xz

# 配置DPDK编译环境
# 安装编译所需要的环境库
sudo apt-get update
sudo apt-get install gcc
sudo apt-get install build-essential
sudo apt-get install libnuma-dev
sudo apt-get install pkg-config
sudo apt-get install meson
sudo apt install python3-pyelftools

# 编译dpdk
cd dpdk-22.07
# meson build这一步需要很长时间,可以修改一下配置文件,裁剪编译更快
meson  build
cd build
ninja
ninja install

执行完之后所有的库都安装在 /usr/local/lib/x86_64-linux-gnu/ 目录。

可执行程序和脚本都安装在 /usr/local/bin/ 目录。

要卸载只需执行 ninja uninstall 即可。

裁剪编译
默认编译时,会默认编译不需要的驱动,导致编译很慢。在虚拟机中,很多驱动都可以不需要,因此可以做裁剪。

具体在执行 meson build 之前,

修改 drivers/meson.build 文件,subdirs 里只保留 ‘bus’,‘mempool’,‘net’ 即可。

修改 drivers/bus/meson.build 文件,drivers 里只保留 ‘pci’,‘vdev’ 即可。

修改 drivers/mempool/meson.build 文件,drivers 里只保留 ‘ring’,‘stack’ 即可。

修改 drivers/net/meson.build 文件,drivers 里只保留 ‘e1000’ 即可【因为虚拟机网卡使用的是 e1000 驱动】。

接着执行 meson build。
编译 igb uio 驱动

git clone http://dpdk.org/git/dpdk-kmods
cd dpdk-kmods/linux/igb_uio
make
# 编译出来 igb_uio.ko

验证环境

cd examples/l2fwd
make

image
加载 igb uio 驱动

cd dpdk-kmods/linux/igb_uio
modprobe uio
insmod igb_uio.ko intr_mode=legacy

分配巨页

sudo vim /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
# 在文件里把默认的0修改为512,退出保存

绑定网卡

ifconfig ens160 down
dpdk-devbind.py -b igb_uio ens160

验证

cd /dpdk-22.07/examples/l2fwd/build/
./l2fwd -l 0-1 -- -p 0x1 -T 1

image

解绑网卡
如果之后想把刚刚绑定的网卡解绑,需要通过下面的方法:

# 获取网卡设备号
lspci | grep Eth

image
我的ens160应该是最后一个 03:00.0

dpdk-devbind.py -u 03:00.0
dpdk-devbind.py -b e1000 03:00.0
ifconfig ens160 up

ubuntu16.04安装dpdk19.08

参考网站
下载源码

wget https://fast.dpdk.org/rel/dpdk-19.08.2.tar.xz
tar xf dpdk-19.08.2.tar.xz

设置dpdk环境变量

image

export RTE_SDK=/home/chan/dpdk-stable-19.08.2 # 指向DPDK的源代码目录

export RTE_TARGET=x86_64-native-linux-gcc # 指向DPDK的编译输出目录

配置dpdk编译环境

安装必要包

sudo apt-get update
sudo apt-get install gcc
sudo apt-get install build-essential
sudo apt-get install libnuma-dev
sudo apt-get install pkg-config

运行dpdk-setup

#切换到root用户
su
cd /home/chan/dpdk-stable-19.08.2
./usertools/dpdk-setup.sh 
  • 选择39进行编译 (这一步时间比较长 20分钟+)
    image
    编译完会多一个文件夹
    image

  • 选择 43 插入 IGB_UIO 模块, 选择网卡为 vmxnet3 会加载此模块。
    image

  • 选择 44 插入 VFIO 模块,安全硬件虚拟化,确保设备只能访问限定内存区域避免程序错误导致系统崩溃。
    image

  • 选择 45 绑定 KNI 模块内核协议栈桥接,做到DPDK仅从硬件收发数据,将数据交由内核无需重构整个网络栈。
    image

  • 选择 46 ,47配置大页,针对两种不同系统(非NUMA/NUMA),配置巨页页数,将指定大小的巨页都分为512页。
    image
    image

  • 选择 49 绑定 IGB UIO模块(在这里需要将ens160网卡down掉)。

ifconfig ens160 down

然后在setup中 输入49,物理设备号输入 ens160的设备号
image
image

选择 60 退出

DPDK编译环境就已经完成~

测试dpdk环境

cd /home/chan/dpdk-stable-19.08.2/examples/helloworld
make
./build/helloworld

image

网卡的作用

b. 使用dpdk收数据

image

  • 网卡:核心作用是让计算机能够接入网络,实现数据的发送与接收,是计算机与网络之间的桥梁。
    负责AD转换 [接收数据:电信号(高低电平)\(\rightarrow\)数字信号]、DA转换 [发送数据:数字信号\(\rightarrow\)电信号]。
  • 网卡驱动:使得网卡正常工作,Linux内核官方维护,了解即可。主要提供了两层:1)NIC负责把原始数据放至相应位置(sk_buff),提供给网络层的TCP/IP协议栈。
  • TCP/IP:

网卡的作用:网络通信中,大量的sk_buff选择什么数据结构保存?

UIO: 截获PCI的地址
PCI

1.dpdk能不能提升Redis qps?
不能,dpdk不一定能提升
2.dpdk能不能减少Nginx延迟?
不明显
3.dpdk能不能提升吞吐量?
可以, 主要是来提升吞吐量的

dpdk的主要作用是把网卡数据截获,能够抓取到原始数据,做自己的协议栈、posixapi、应用,以提升性能, 特别适合高性能网络开发

dpdk的应用场景:

  • 数据备份(适用于传输大文件,底层用DPDK,应用层用RDMA)
  • 网关防火墙
    dpdk用户协议栈:
  • a。ntytcp
  • b. 4.4BSD (腾讯的f-stack协议栈用的BSD,自己写的Posix api,使其适配dpdk)
  • c. mtcp
  • d.lwip
  • e.vapp

开发 -> 编译 -> 运行
编译的时候我们需要借助Makefile文件(可以复制/dpdk-22.07/examples/helloworld/Makefile)

mkdir /dpdk-22.07/dpdk
cp /dpdk-22.07/examples/helloworld/Makefile /dpdk-22.07/dpdk

然后编写一份代码ustack.c

#include <stdio.h>
#include <rte_eal.h>
int main(int argc, char *argv[]){
    if(rte_eal_init(argc, argv) < 0) {
        rte_exit(EXIT_FAILURE, "Error with init\n");
    }
    printf("Hello World!\n");
    return 0;
}

修改Makefile
image

cd /dpdk-22.07/dpdk
make
./build/ustack

image

至此,我们已经完成了dpdk收到数据的前提条件:dpdk绑定网卡

image

dpdk mbuf 与 kernel sk_buff 它们的作用是一样的

参考:
https://bbs.csdn.net/topics/620040250
https://blog.csdn.net/qq_57951250/article/details/155463935?spm=1001.2014.3001.5502

posted @ 2026-03-05 16:35  Xiaomostream  阅读(56)  评论(0)    收藏  举报