开发者
资源
文档评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

使用前配置

配置大页内存

  • 使用大页内存可减少页表与内存管理开销,提升应用程序性能。
  • 请用户根据服务端环境具体的大页配置调整参数,服务端环境关闭或重启后需要重新配置和挂载。
  • 若服务端为物理机,从步骤1开始执行;若服务端为虚拟机,可直接从步骤9开始执行。
  1. 查看物理机是否配置大页内存。

    cat /sys/devices/system/node/node*/meminfo | grep Huge

    回显类似如下:

    Node 0 AnonHugePages:         0 kB
    Node 0 ShmemHugePages:        0 kB
    Node 0 HugePages_Total:     0
    Node 0 HugePages_Free:      0
    Node 0 HugePages_Surp:      0
    Node 1 AnonHugePages:         0 kB
    Node 1 ShmemHugePages:        0 kB
    Node 1 HugePages_Total:     0
    Node 1 HugePages_Free:      0
    Node 1 HugePages_Surp:      0

    如果所有Node的HugePages_Total显示信息为0,说明此时系统没有配置内存大页。

    • 如果没有配置大页内存,则执行步骤2以及后续步骤。
    • 如果配置了大页内存,则从步骤8开始执行。
  2. 配置物理机内存大页。

    查看主机支持的大页类型:

    ls -la /sys/kernel/mm/hugepages/

    回显示例如下:

    total 0
    drwxr-xr-x. 2 root root 0 Sep 1 10:30 .
    drwxr-xr-x. 3 root root 0 Sep 1 10:30 ..
    -rw-r--r--. 1 root root 0 Sep 1 10:30 hugepages-1048576kB
    -rw-r--r--. 1 root root 0 Sep 1 10:30 hugepages-2048kB
  3. 更改Linux默认启动内核版本,修改GRUB设置。

    • 系统架构为aarch64场景时:

      vi /etc/grub2-efi.cfg
    • 系统架构为x86_64场景时:

      vi /etc/grub2.cfg
  4. 在Linux行输入以下配置。若无需永久默认配置可跳过此步骤,跳转至步骤8。 按“i”进入编辑模式,在文件的Linux行后输入以下内容。

    default_hugepagesz=1G hugepagesz=1G  hugepages=2 iommu.passthrough=1 pci=realloc

    按“Esc”键退出编辑模式,输入 :wq!,按“Enter”键保存并退出文件。

    • 此处设置默认大页内存的大小为1GB,数量为2。大页内存大小请根据步骤2中查询到的主机支持的大页类型更改。
    • iommu.passthrough=1 pci=realloc为虚拟化场景所需配置。
  5. 重启。

    reboot
  6. 重新进入系统后,确定内存大页配置情况。

    cat /proc/sys/vm/nr_hugepages # 回显显示数量为2
  7. 在Host侧查看各个NUMA节点上的大页分配情况。

    cat /sys/devices/system/node/node*/meminfo | grep Huge

  8. 执行命令,确认要用的网口。

    hinicadm工具直接查询:

    hinicadm3 info

    回显示例如下,获取到可用网口设备为“enp6s0”,BDF号为“0000:06:00.0”。

    Card num:1
    Device Information:
        Card        PCIe Function
    |----hinic0(CAL_2X100G)
            |--------0000:06:00.2(NIC:bifur)
            |--------0000:06:00.0(NIC:enp6s0)

    获取并确认要使用的网口后,执行以下命令获取网口IP地址以及MAC地址。

    ip a

    (可选)若网口不存在IP地址可手动配置:

    客户端服务器也需要保证网口存在IP地址,否则网络无法联通。

    ip addr add 192.168.*.*/24 dev enp6s0 # 用户根据实际情况替换IP地址、掩码以及网口设备

    需记下使用网口的IP、MAC地址,后续DPDK接管网口后该信息不可见。

  9. 配置NUMA大页内存。从此步骤开始,如果要在虚拟机中运行业务,那就在虚拟机中操作,如果是在物理机中运行业务,则在物理机操作。

    • 服务端为物理机场景:

      cat /sys/class/net/ens6f0/device/numa_node # 查看网卡所在NUMA

      此处以网卡名ens6f0为例,用户根据实际使用的网卡名填写。

      回显示例如下,此处说明所在NUMA为1。

      echo never > /sys/kernel/mm/transparent_hugepage/enabled # 关闭透明大页
      echo 2 > /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages # 为指定节点分配2个大小为1048576kB(1GB)的大页
      • 此处node1为上一步查询到的网卡所在NUMA节点,具体node编号根据查询到的网卡所在NUMA进行更改。
      • 分配的大页数量与单个大页大小根据实际情况替换。
    • 服务端为虚拟机场景:

      echo never > /sys/kernel/mm/transparent_hugepage/enabled # 关闭透明大页
      echo 2 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
    • 配置2个1GB类型内存大页,如果是512MB类型推荐配置4个。
    • 服务端关闭或重启需要重新执行此步骤。
    • 关闭透明大页会降低Redis的性能,但是性能更稳定,请用户根据实际需要决定透明大页设置。启用透明大页可参考:
    echo always > /sys/kernel/mm/transparent_hugepage/enabled
  10. 确认是否配置成功。

    dpdk-hugepages.py -s

    回显示例如下:

    Node Pages Size Total
    1    2     1Gb  2Gb

    说明在node1节点配置了2个1GB类型大页。

  11. 挂载大页。

    如果使用的为1GB类型大页,需要执行此步骤,如果是其他类型大页,无需挂载,请跳过本步骤。

    若为root用户: 直接将大页挂载至系统路径下。

    mkdir -p /dev/hugepages1G
    mount -t hugetlbfs -o pagesize=1G hugetlbfs /dev/hugepages1G   #将1GB类型大页挂载到/dev/hugepages1G目录下,如果业务环境关闭或重启需要重新执行

    若为非root用户: 用户名以KNET_USER为占位符进行示例,用户组名以KNET_USER_GROUP为占位符进行示例,运行时请将其替换为实际用户名和用户组名,如果创建普通用户时未指定属组,KNET_USER和KNET_USER_GROUP是同名的,将1GB类型大页挂载到“/home/KNET_USER/hugepages”目录下。

    为避免业务冲突,请用户执行此步骤将大页挂载到K-NET业务大页路径,否则会导致大页挂载到默认的大页路径/dev/hugepages。

    mkdir -p /home/KNET_USER/hugepages
    mount -t hugetlbfs -o pagesize=1G hugetlbfs /home/KNET_USER/hugepages   #将1G类型大页挂载到/home/KNET_USER/hugepages目录下,如果业务环境关闭或重启需要重新执行
    chown -R KNET_USER:KNET_USER_GROUP /home/KNET_USER/hugepages
  12. 查看大页挂载情况。

    mount | grep huge

    回显示例如下,表示成功使能1GB大页:

    cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
    hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)
    hugetlbfs on /home/KNET_USER/hugepages type hugetlbfs (rw,relatime,pagesize=1024M)

    这里需要注意是否存在其他1GB类型大页挂载路径,如果存在的话,可能会造成权限问题影响后续业务运行,需要执行以下命令取消挂载:

    umount /path     # /path为其他1GB类型大页挂载路径

相关业务配置

通用业务配置

K-NET支持两种工作模式,根据业务需求选择:

  • 标准模式:DPDK完全接管网卡。适用于大多数场景。
  • 流量分叉模式:无需DPDK接管网卡,K-NET与内核态协议栈同时工作。适用于需要同时使用K-NET加速和内核态网络的场景。

若使用流量分叉模式,请跳过本章节的步骤2(DPDK接管网卡),完成本章其他配置后,参考流量分叉功能文档进行后续使用。

  1. 修改配置文件。

    1. 参考配置大页内存的步骤8确认要用的网口。

    2. 修改/etc/knet/knet_comm.conf文件。

      1. 打开文件。

        vi /etc/knet/knet_comm.conf
      2. 按“i”进入编辑模式,修改配置项,示例如下:

        #interface配置项
            "interface": {
                ...
                "bdf_nums": [
                   "0000:06:00.0"
                ], # 1. 填写获取的BDF号
                "mac": "52:54:00:2e:1b:a0", # 2. 填写绑定网卡的MAC地址 
                "ip": "192.168.1.6",        # 3. 填写绑定网卡的IP地址
                ...
            },
        #dpdk配置项
            "dpdk": {
                "core_list_global": "1",  # 4. 数据面绑核,表示使用1号核。需要确保与ctrl_vcpu_ids绑定的核不同。
                ...
                "socket_mem": "--socket-mem=0,1024", # 5.网卡所在NUMA node1,在0号socket上预分配0MB大页内存,在1号socket上分配1024MB大页内存。
                ...
                "huge_dir": "--huge-dir=/home/KNET_USER/hugepages" # 6. 大页挂载文件夹路径
            }
        • "bdf_nums":填写获取的BDF号,此处以0000:06:00.0为例。
        • "mac":填写绑定网卡的MAC地址,此处以52:54:00:2e:1b:a0为例。
        • "ip":填写绑定网卡的IP地址,此处以192.168.1.6为例。
        • "core_list_global":数据面绑核。需要为网卡所在CPU的中间值,NUMA node0所用CPU为0-23,此处可以填写1,表示使用1号核。需要确保与ctrl_vcpu_ids绑定的核不同,ctrl_vcpu_ids为控制面绑核,在配置文件的common配置项下。
        • "socket_mem":给网卡所在numa_node分配的大页内存,用户需根据实际情况更改。
          • 服务端为物理机时:
            • 如果网卡所在NUMA node0,在0号socket上分配1024MB大页内存,可使用"--socket-mem=1024"。
            • 如果网卡所在NUMA node1,在0号socket上预分配0MB大页内存,在1号socket上分配1024MB大页内存,请填写为“--socket-mem=0,1024”。
          • 服务端为虚拟机时:使用默认配置"--socket-mem=1024"即可。
        • "huge_dir":大页挂载文件夹路径。
      3. 按“Esc”键退出编辑模式,输入 :wq!,按“Enter”键保存并退出文件。

  2. 标准模式:DPDK接管网卡。(流量分叉模式请跳过此步骤)

    服务端环境关闭或重启后需要重新执行当前步骤。

    1. 关闭网口enp6s0(该网口后续会使用DPDK接管)。

      ip link set dev enp6s0 down
    2. 加载VFIO驱动。

      modprobe vfio enable_unsafe_noiommu_mode=1
      modprobe vfio-pci
    3. DPDK接管网卡。

      dpdk-devbind.py -b vfio-pci 0000:06:00.0
      dpdk-devbind.py -s                 #确认是否接管

      接管网卡后,内核网络协议栈将无法直接使用该网卡进行通信,必须启动K-NET进程,待K-NET初始化完成后才能开展K-NET加速业务通信。对于需要同时使用K-NET和内核协议栈的场景。可参考网卡流量分叉功能或内核流量转储功能进行部署。

      回显如下,表示成功接管网卡:

      如果想要取消DPDK接管网卡,执行:

      dpdk-devbind.py -b "hisdk3" 0000:06:00.0  # "hisdk3"为SP670网卡使用的驱动
  3. 配置K-NET动态库、knet_mp_daemon、knet_comm.conf以及业务软件相关权限。

    • 用户名以KNET_USER为占位符进行示例,用户组名以KNET_USER_GROUP为占位符进行示例,运行时请将其替换为实际用户名和用户组名。如果创建普通用户时未指定属组,KNET_USER和KNET_USER_GROUP是同名的,KNET_USER需具有命令执行权限。
    • 此处以Redis作为示例。
    • 若为root用户可跳过此步骤。
    • 以下setcap命令对普通用户进行提权操作,可能会有安全问题。对于提权可能的风险,建议用户通过其他手段防护,如权限最小化,只能被指定的运行用户使用。
    chmod 550 /usr/lib64/libknet_frame.so
    chmod 550 /usr/lib64/libknet_core.so
    chmod 550 /usr/lib64/libdpstack.so
    chmod 550 /usr/bin/knet_mp_daemon
    chown root:KNET_USER_GROUP /usr/lib64/libknet_frame.so
    chown root:KNET_USER_GROUP /usr/lib64/libknet_core.so
    chown root:KNET_USER_GROUP /usr/lib64/libdpstack.so
    chown root:KNET_USER_GROUP /usr/bin/knet_mp_daemon
    chmod a+s /usr/lib64/libknet_frame.so
    chown KNET_USER:KNET_USER_GROUP /etc/knet/knet_comm.conf
    chown -R KNET_USER:KNET_USER_GROUP /etc/knet/run
    setcap 'cap_sys_rawio+p cap_net_admin+p cap_dac_read_search+p cap_ipc_lock+p  cap_sys_admin+p cap_net_raw+p cap_dac_override+p' /usr/bin/knet_mp_daemon 
    setcap 'cap_sys_rawio+p cap_net_admin+p cap_dac_read_search+p cap_ipc_lock+p  cap_sys_admin+p cap_net_raw+p cap_dac_override+p' /path/redis-6.0.20/src/redis-server
    • “/path/redis-6.0.20/src/”为redis-server的路径,请根据实际安装Redis的路径填写。
    • 若使用其他业务软件,将此处Redis的安装路径修改为对应业务软件的路径。
  4. 设置“XDG_RUNTIME_DIR”启动环境变量,普通用户未设置该变量会产生错误,root用户请跳过此步骤。

    用户名使用KNET_USER作为占位符进行示例,运行时请将其替换为实际用户名。环境变量路径涉及的权限及安全需要用户保证。

    用户可以根据需要选择永久或者临时配置环境变量。如果用户选择临时配置环境变量,需要在每个终端页面执行相关命令。

    • 永久配置环境变量。

      配置完成之后重新切换到该用户时无需重新配置环境变量。

      1. 创建环境变量路径。

        cd /home/KNET_USER/
        mkdir knet
      2. 编辑环境变量相关文件。

        vi ~/.bashrc
      3. 按“i”进入编辑模式,在末尾加上:

        export XDG_RUNTIME_DIR=/home/KNET_USER/knet
      4. 按“Esc”键退出编辑模式,输入 :wq!,按“Enter”键保存并退出文件。

        source ~/.bashrc
        echo $XDG_RUNTIME_DIR #确认是否配置环境变量,如果已配置会显示配置的路径
    • 临时配置环境变量。

      • 服务端环境关闭或重启后,或者退出普通用户再重新切换到该用户,均需要重新执行步骤。
      • 通过设置环境变量指定运行时目录,路径依据不同用户名会有差异。
      1. 创建环境变量路径。

        cd /home/KNET_USER/
        mkdir knet
      2. 配置环境变量。

        export XDG_RUNTIME_DIR=/home/KNET_USER/knet
        echo $XDG_RUNTIME_DIR #确认是否配置环境变量,如果已配置会显示配置的路径

(可选)SockPerf业务配置

若用户需使用K-NET加速SockPerf,由于用户态协议栈recvfrom()暂不支持MSG_NOSIGNAL flag,需将SockPerf源码路径下src/input_handlers.h第66-68行代码注释或者删除,具体代码如下:

#ifndef __windows__
flags = MSG_NOSIGNAL;
#endif

再进行编译,编译后K-NET可以接管双端进行网络加速。