---
title: 环境配置
description: "> [!NOTE]说明"
url: https://www.hikunpeng.com/document/detail/zh/knet/feature/docs/zh/feature_guide/environment_configuration.md
sourcePath: /source/zh/knet/feature/docs/zh/feature_guide/environment_configuration.md
indexId: 8191cddb6a6f610d8f306f54d33f08ecec53afb83284830e55df508fc062916e74
---
# 环境配置

## 配置大页内存

> [!NOTE]说明
>
>- 使用大页内存可减少页表与内存管理开销，提升应用程序性能。
>- 请用户根据服务端环境具体的大页配置调整参数，服务端环境关闭或重启后需要重新配置和挂载。
>- 若服务端为物理机，从步骤1开始执行；若服务端为虚拟机，可直接从步骤9开始执行。

1. 查看物理机是否配置大页内存。

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

    回显类似如下：

    ```ColdFusion
    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. 配置物理机内存大页。

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

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

3. 更改Linux默认启动内核版本，修改GRUB设置。
    - 系统架构为aarch64场景时：

        ```bash
        vi /etc/grub2-efi.cfg
        ```

    - 系统架构为x86_64场景时：

        ```bash
        vi /etc/grub2.cfg
        ```

4. 在Linux行输入以下配置。
    按“i”进入编辑模式，在文件的Linux行后输入以下内容。

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

    

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

    > [!NOTE]说明
    >- 此处设置默认大页内存的大小为1GB，数量为2。
    >- iommu.passthrough=1 pci=realloc为虚拟化场景所需配置。

5. 重启。

    ```bash
    reboot
    ```

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

    ```bash
    cat /proc/sys/vm/nr_hugepages # 回显显示数量为2
    ```

7. 在Host侧查看各个NUMA节点上的大页分配情况。

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

    

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

    hinicadm工具直接查询：

    ```bash
    hinicadm3 info
    ```

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

    ```text
    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地址。
    
    ```bash
    ip a
    ```

    

    （可选）若网口不存在IP地址可手动配置：

    > [!NOTE]说明
    > 客户端服务器也需要保证网口存在IP地址，否则网络无法联通。

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

    > [!NOTE]说明
    >需记下使用网口的IP、MAC地址，后续DPDK接管网口后该信息不可见。

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

    - 服务端为物理机场景：

        ```bash
        cat /sys/class/net/ens6f0/device/numa_node # 查看网卡所在NUMA
        ```
        
        > [!NOTE]说明
        >此处以网卡名ens6f0为例，用户根据实际使用的网卡名填写。
        
        回显示例如下，此处说明所在NUMA为1。

        

        ```bash
        echo never > /sys/kernel/mm/transparent_hugepage/enabled # 关闭透明大页
        echo 2 > /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages # 为指定节点分配2个大小为1048576kB（1GB）的大页
        ```

        > [!NOTE]说明
        >
        >- 此处node1为上一步查询到的网卡所在NUMA节点，具体node编号根据查询到的网卡所在NUMA进行更改。
        >- 分配的大页数量与单个大页大小根据实际情况替换。

    - 服务端为虚拟机场景：

        ```bash
        echo never > /sys/kernel/mm/transparent_hugepage/enabled # 关闭透明大页
        echo 2 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
        ```

    > [!NOTE]说明
    >- 配置2个1GB类型内存大页，如果是512MB类型推荐配置4个。
    >- 服务端关闭或重启需要重新执行此步骤。
    >- 关闭透明大页会降低Redis的性能，但是性能更稳定，请用户根据实际需要决定透明大页设置。启用透明大页可参考：
    >
    > ```bash
    > echo always > /sys/kernel/mm/transparent_hugepage/enabled
    >    ```

10. 确认是否配置成功。

    ```bash
    dpdk-hugepages.py -s
    ```

    回显示例如下：

    ```text
    Node Pages Size Total
    1    2     1Gb  2Gb
    ```

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

11. 挂载大页。
    > [!NOTE]说明
    > 如果使用的为1GB类型大页，需要执行此步骤，如果是其他类型大页，无需挂载，请跳过本步骤。

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

    ```bash
    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”目录下。
    > [!NOTICE]须知
    >为避免业务冲突，请用户执行此步骤将大页挂载到K-NET业务大页路径，否则会导致大页挂载到默认的大页路径/dev/hugepages。

    ```bash
    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. 查看大页挂载情况。

    ```bash
    mount | grep huge
    ```

    回显示例如下，表示成功使能1GB大页：

    ```ColdFusion
    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)
    ```

    > [!NOTE]说明
    >这里需要注意是否存在其他1GB类型大页挂载路径，如果存在的话，可能会造成权限问题影响后续业务运行，需要执行以下命令取消挂载：
    >
    >```bash
    >umount /path     # /path为其他1GB类型大页挂载路径
    >```

## 相关业务配置

### 通用业务配置

> [!NOTE]说明
> K-NET支持两种工作模式，根据业务需求选择：
> 
> - **标准模式**：DPDK完全接管网卡。适用于大多数场景。
> - **流量分叉模式**：无需DPDK接管网卡，K-NET与内核态协议栈同时工作。适用于需要同时使用K-NET加速和内核态网络的场景。
> 
> 若使用**流量分叉模式**，请跳过本章节的步骤2（DPDK接管网卡），完成本章其他配置后，参考[流量分叉功能](https://www.hikunpeng.com/document/detail/zh/knet/feature/docs/zh/feature_guide/traffic_bifurcation.md)文档进行后续使用。

1. 修改配置文件。

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

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

        1. 打开文件。

            ```bash
            vi /etc/knet/knet_comm.conf
            ```

        2. 按“i”进入编辑模式，修改配置项，示例如下：

            ```json
            #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号核。
            - "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"即可。

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

2. **标准模式**：DPDK接管网卡。（流量分叉模式请跳过此步骤）

    > [!NOTE]说明
    >服务端环境关闭或重启后需要重新执行当前步骤。

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

        ```bash
        ip link set dev enp6s0 down
        ```

    2. 加载VFIO驱动。

        ```bash
        modprobe vfio enable_unsafe_noiommu_mode=1
        modprobe vfio-pci
        ```

    3. DPDK接管网卡。

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

        回显如下，表示成功接管网卡：

        

        > [!NOTE]说明
        >如果想要取消DPDK接管网卡，执行：
        >
        >```bash
        >dpdk-devbind.py -b "hisdk3" 0000:06:00.0  # "hisdk3"为SP670网卡使用的驱动
        >```

3. 配置K-NET动态库、knet_mp_daemon、knet_comm.conf以及业务软件相关权限。

    > [!NOTE]说明
    >
    >- 用户名以KNET_USER为占位符进行示例，用户组名以KNET_USER_GROUP为占位符进行示例，运行时请将其替换为实际用户名和用户组名。如果创建普通用户时未指定属组，KNET_USER和KNET_USER_GROUP是同名的，KNET_USER需具有命令执行权限。
    >- 此处以Redis作为示例。
    >- 若为root用户可跳过此步骤。

    ```bash
    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
    ```

    > [!NOTE]说明
    >- “/path/redis-6.0.20/src/”为redis-server的路径，请根据实际安装Redis的路径填写。
    >- 若使用其他业务软件，将此处Redis的安装路径修改为对应业务软件的路径。

4. 设置“XDG_RUNTIME_DIR”启动环境变量，普通用户未设置该变量会产生错误，root用户请跳过此步骤。

     > [!NOTE]说明
     > 用户名使用KNET_USER作为通配符进行示例，运行时请将其替换为实际用户名。环境变量路径涉及的权限及安全需要用户保证。

     用户可以根据需要选择永久或者临时配置环境变量。如果用户选择临时配置环境变量，需要在每个终端页面执行相关命令。
     - 永久配置环境变量。
         > [!NOTE]说明
         > 配置完成之后重新切换到该用户时无需重新配置环境变量。
        1. 创建环境变量路径。

            ```bash
            cd /home/KNET_USER/
            mkdir knet
            ```

        2. 编辑环境变量相关文件。

            ```bash
            vi ~/.bashrc
            ```

        3. 按“i”进入编辑模式，在末尾加上：

            ```bash
            export XDG_RUNTIME_DIR=/home/KNET_USER/knet
            ```

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

            ```bash
            source ~/.bashrc
            echo $XDG_RUNTIME_DIR #确认是否配置环境变量，如果已配置会显示配置的路径
            ```

     - 临时配置环境变量。
         > [!NOTE]说明
         >- 服务端环境关闭或重启后，或者退出普通用户再重新切换到该用户，均需要重新执行步骤。
         >- 通过设置环境变量指定运行时目录，路径依据不同用户名会有差异。

        1. 创建环境变量路径。

            ```bash
            cd /home/KNET_USER/
            mkdir knet
            ```

        2. 配置环境变量。

            ```bash
            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行代码注释或者删除，具体代码如下：

```c
#ifndef __windows__
flags = MSG_NOSIGNAL;
#endif
```

再进行编译，编译后K-NET可以劫持双端进行网络加速。
