vDPA测试环境搭建

要求:

  • 运行 Linux 发行版的计算机。本指南使用 CentOS 9-stream,但对于其他 Linux 发行版,特别是对于 Red Hat Enterprise Linux 7,命令不应有重大变化。

  • 具有 sudo 权限的用户

  • ~ 主目录中有 25 GB 的可用空间

  • 至少 8GB 内存

首先,我们安装我们需要的软件包:

sudo yum install qemu-kvm libvirt-daemon-qemu libvirt-daemon-kvm libvirt virt-install libguestfs-tools-c kernel-tools dpdk dpdk-tools

创建 VM

首先,从以下网站下载最新的 CentOS-Cloud-Base 映像:

user@host $ sudo wget -O /var/lib/libvirt/images/CentOS-Stream-GenericCloud-9-20240212.0.x86_64.qcow2 https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240212.0.x86_64.qcow2

(请注意,上面的 URL 可能会更改,请将其更新为 https://cloud.centos.org/centos/9-stream/x86_64/images中的最新 qcow2 映像。

制作image的副本,以便将来可以重用它(用这种方法,我们可以启动很多个虚拟机,但镜像只占用很小的磁盘空间):

user@host $ sudo qemu-img create -f qcow2 -b  /var/lib/libvirt/images/CentOS-Stream-GenericCloud-9-20240212.0.x86_64.qcow2 -F qcow2  /var/lib/libvirt/images//vhuser-test1.qcow2

如果我们导出以下变量,则可以使用非特权用户(推荐)执行此操作的 libvirt 命令:

user@host $ export LIBVIRT_DEFAULT_URI="qemu:///system"

现在,清理命令(将密码更改为您自己的密码,卸载和安装一些工具):

user@host $ sudo virt-sysprep --root-password password:changeme --uninstall cloud-init --selinux-relabel -a /var/lib/libvirt/images/vhuser-test1.qcow2 --network --install "dpdk,dpdk-tools,pciutils"

如果出现报错:

Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

创建shell脚本

$ cat scripts 
#!/bin/bash
cd /etc/yum.repos.d/
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

,并使用如下命令:

user@host $ sudo virt-sysprep --root-password password:changeme --run ./scripts --uninstall cloud-init --selinux-relabel -a /var/lib/libvirt/images/vhuser-test1.qcow2 --network --install "dpdk,dpdk-tools,pciutils"

此命令挂载文件系统并自动应用一些基本配置,以便映像可以重新引导。

配置VM网络

我们还需要一个网络来连接我们的 VM。Libvirt 处理网络的方式与管理虚拟机的方式类似,您可以使用 XML 文件定义网络,然后通过命令行启动或停止它。

在这个例子中,我们将使用一个名为default的网络,为了方便起见,它的定义包含在 libvirt 中。以下命令定义default网络,启动它并检查它是否正在运行。

user@host $ virsh net-define /usr/share/libvirt/networks/default.xml
Network default defined from /usr/share/libvirt/networks/default.xml
user@host $ virsh net-start default
Network default started
user@host $virsh net-list
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   no          yes

/usr/share/libvirt/networks/default.xml内容如下:

$ cat /usr/share/libvirt/networks/default.xml
  1 <network>
  2   <name>default</name>
  3   <bridge name="virbr0"/>
  4   <forward/>
  5   <ip address="192.168.122.1" netmask="255.255.255.0">
  6     <dhcp>
  7       <range start="192.168.122.2" end="192.168.122.254"/>
  8     </dhcp>
  9   </ip>
 10 </network>

该文件定义了一个内核网桥virbr0,网桥的ip、掩码和作为dhcp server时分配的ip范围。我们也可以自定义其他的网络。

最后,我们可以使用 virt-install 来创建 VM。此命令行实用程序为一组已知操作系统创建所需的定义。这将为我们提供基本定义,然后我们可以自定义这些定义:

user@host $ virt-install --import --name vdpa-test1 --ram=5120 --vcpus=3 \
--nographics --accelerate --machine q35 \
       --network network:default,model=virtio --mac 02:ca:fe:fa:ce:aa \
      --debug --wait 0 --console pty \
      --disk /var/lib/libvirt/images/vdpa-test1.qcow2,bus=virtio --os-variant centos-stream9

此命令的选项用于指定 vCPU 的数量、VM 的 RAM 量以及我们希望 VM 连接到的磁盘路径和网络。
osinfo-query os | grep centos 可以查询os版本。

您可能已经注意到,与 Vhost 用户动手操作相比,有一个区别,因为我们将机器类型指定为“q35”而不是默认的“pc”类型。这是启用对虚拟 IOMMU 的支持的要求。

除了根据我们指定的选项定义虚拟机外,virt-install 命令还应该为我们启动虚拟机,因此我们应该能够列出它:

user@host $ virsh list
 Id   Name       State
------------------------------
 1 vdpa-test1   running

瞧!我们的 VM 正在运行。我们需要尽快对其定义进行一些更改。所以我们现在将关闭它:

user@host $ virsh shutdown vdpa-test1

Host环境准备

DPDK 有助于以最佳方式分配和管理内存缓冲区。在 Linux 上,这需要使用 hugepage 支持,该支持必须在正在运行的内核中启用。使用大于通常 4K 大小的页面可以减少页面总数,从而减少 TLB(Translation Lookaside Buffers)查找,从而提高性能。需要这些查找才能将虚拟地址转换为物理地址。为了在引导过程中分配 hugepages,我们在引导加载程序配置中的内核参数中添加了以下内容。

user@host $ sudo grubby --args="default_hugepagesz=1G hugepagesz=1G hugepages=6" --update-kernel /boot/<your kernel image file>

这有什么作用?

default_hugepagesz=1G: make all created hugepages by default 1G big

hugepagesz=1G: for the hugepages created during startup set the size to 1G as well

hugepages=6: create 6 hugepages (of size 1G) from the start. These should be seen      after booting in /proc/meminfo

现在可以重新引导主机。在它出现后,我们可以通过运行以下命令来检查我们对内核参数的更改是否有效:

user@host $ cat /proc/cmdline

Guest环境准备

virt-install 命令使用 libvirt 创建并启动了 VM。要将基于 DPDK 的 vswitch testpmd 连接到 QEMU,我们需要添加 vhost-user 接口的定义(由 UNIX 套接字支持),并将虚拟 IOMMU 设置到 XML 的 device 部分:

user@host $ virsh edit vdpa-test1

让我们从添加所有必要的设备开始,以使 Virtio-net 设备与 IOMMU 支持一起工作。

首先,我们需要创建一个专用于 Virtio-net 设备的 pcie-root-port,我们将用作 vDPA 设备,以便它有自己的 IOMMU group。否则,它将与同一总线上的其他设备共享,从而阻止它在用户空间中使用:

<controller type='pci' index='8' model='pcie-root-port'>
   <model name='pcie-root-port'/>
   <target chassis='8' port='0xe'/>
   <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</controller>

解惑IOMMU

然后,我们可以使用 vhost-user 后端添加 Virtio-net 设备,并将其插入我们刚刚创建的 pcie-root-port(总线 8)。我们还需要启用 IOMMU 和 ATS(地址转换服务)支持:

最后,我们添加 IOMMU 设备,启用中断重新映射和 IOTLB 支持:
<iommu model='intel'>
   <driver intremap='on' iotlb='on'/>
</iommu>

要使启用了 IOMMU 的 vhost-user 正常工作,还需要进行一些其他 XML 调整。

首先,就像在 vhost-user 动手操作 中一样,我们需要让 guest 使用huge pages,这是通过在 guest 定义中添加以下内容来完成的:

  <memoryBacking>
    <hugepages>
      <page size='1048576' unit='KiB' nodeset='0'/>
    </hugepages>
    <locked/>
  </memoryBacking>
   <numatune>
    <memory mode='strict' nodeset='0'/>
  </numatune>

字段含义参考libvirt xml memoryBacking。

为了让 vhost-user 后端能够访问内存,我们需要在 guest 配置中添加一个额外的设置。这是一个重要的设置,如果没有它,我们将看不到任何正在传输的数据包:

<cpu mode='host-passthrough' check='none'>
     <topology sockets='1' cores='3' threads='1'/>
     <numa>
     <cell id='0' cpus='0-2' memory=’5242880’ unit='KiB' memAccess='shared'/>
     </numa>
</cpu>

字段含义参考libvirt xml host-passthrough

最后,我们需要让 Qemu 管理 I/O APIC,以便中断重新映射工作:

<features>
      <acpi/>
      <apic/>
      <ioapic driver='qemu'/>
</features>

字段含义参考libvirt xml ioapic driver=‘qemu’
现在我们需要启动我们的guest。由于我们将其配置为连接到 vhost-user UNIX 套接字,因此我们需要确保它们在guest启动时可用。这是通过启动 testpmd 来实现的,它将为我们打开套接字:

user@host $ sudo testpmd -l 0,2 --socket-mem=1024 -n 4 \
    --vdev 'net_vhost0,iface=/tmp/vhost-user1,iommu-support=1'  -- \
    --portmask=1 -i --rxq=1 --txq=1 \
    --nb-cores=1 --forward-mode=io

最后一件事,因为我们连接到 vhost-user unix 套接字,我们需要让 QEMU 以 root 身份运行这个实验。为此,请在 /etc/libvirt/qemu.conf 中设置 “user = root”。这是我们的特殊用例所必需的,但一般不建议这样做。事实上,读者应该在阅读这篇动手文章后,通过注释掉“user = root”设置来恢复设置。

现在,我们可以使用以下命令启动 VM:virsh start

user@host $ virsh start vdpa-test1

以 root 身份登录。我们在 guest 中做的第一件事是向内核命令行添加一些参数,以在启动时保留一些巨大的页面,并在直通模式下启用对 IOMMU 的内核支持:

root@guest $ sudo grubby --args="default_hugepagesz=1G hugepagesz=1G hugepages=2 intel_iommu=on iommu=pt" --update-kernel /boot/<your kernel image file>

为了应用新的内核参数,让我们重新启动客户机。
以上也可以通过host实现:

sudo virt-sysprep -v --run-command 'grubby --args="default_hugepagesz=1G hugepagesz=1G hugepages=6" --update-kernel=ALL' -a  /var/lib/libvirt/images/vhuser-test1.qcow2

在启动时,我们现在可以将 virtio 设备绑定到 vfio-pci 驱动程序。为了能够做到这一点,我们需要首先加载所需的内核模块。

root@guest $ modprobe vfio-pci

让我们先找出 virtio-net 设备的 PCI 地址。

root@guest $ dpdk-devbind --status net
…
Network devices using kernel driver
===================================
0000:01:00.0 'Virtio network device 1041' if=eth0 drv=virtio-pci unused=virtio_pci,vfio-pci *Active*
0000:08:00.0 'Virtio network device 1041' if=eth1 drv=virtio-pci unused=virtio_pci,vfio-pci

在输出中,在未标记为active的部分中查找 virtio-device。我们可以用dpdk-devbind来做这个实验:

root@guests $ dpdk-devbind.py -b vfio-pci 0000:08:00.0

现在,客户机已准备好运行我们基于 DPDK 的 vDPA 应用程序。但在试验 vDPA 之前,我们首先要确保在启用 IOMMU 时,我们可以将 Virtio 设备与其 Virtio PMD 驱动程序结合使用 testpmd:

root@guests $ testpmd -l 0,1 --socket-mem 1024 -n 4 -- --portmask=1 -i --auto-start

然后,我们可以在主机 testpmd 实例中启动数据包转发,并在 IO 转发循环中注入突发数据包:

HOST testpmd> start tx_first 512

为了检查一切是否正常工作,我们可以通过重复调用 show port stats all 命令来检查任一 testpmd 实例中的端口统计信息:

HOST testpmd> show port stats all
  ######################## NIC statistics for port 0  ########################
  RX-packets: 60808544   RX-missed: 0          RX-bytes:  3891746816
  RX-errors: 0
  RX-nombuf:  0         
  TX-packets: 60824928   TX-errors: 0          TX-bytes:  3892795392
  Throughput (since last show)
  Rx-pps:     12027830
  Tx-pps:     12027830
  ############################################################################

搭建环境图

创建加速数据路径

构建 vDPA 应用程序

在确保Host和Guest都正确配置后,让乐趣开始吧!

正如在上一篇文章中提到的,Virtio-vDPA DPDK 驱动程序,它支持使用半虚拟化的 Virtio-net 设备或完整的 Virtio 卸载硬件 NIC,正在上游 DPDK 邮件列表中进行审查,因此在官方上游版本中尚不可用(计划在 v19.11 版本中提供)。
这意味着我们必须应用引入此驱动程序的系列并构建 DPDK,而不是使用 DPKD 下游包。

首先,让我们安装所有依赖项来构建 DPDK:

root@guests $ yum install git gcc numactl-devel kernel-devel

然后我们构建 DPDK 库:

root@guests $ git clone https://gitlab.com/mcoquelin/dpdk-next-virtio.git dpdk
root@guests $ cd dpdk
root@guests $ export RTE_SDK=`pwd`
root@guests $ export RTE_TARGET=x86_64-native-linuxapp-gcc
root@guests $ make -j2 install T=$RTE_TARGET DESTDIR=install

最后,我们构建了 DPDK 树中提供的 vDPA 示例应用程序。此应用程序将探测 vDPA 驱动程序,并使用 vDPA 框架将 vDPA 设备绑定到 vhost-user 套接字:

root@guests $ cd examples/vdpa
root@guests $ make

启动 vDPA 应用程序

如果还没有完成,我们需要将 Virtio-net 设备绑定到 vfio-pci 驱动程序:

root@guests $ dpdk-devbind.py -b vfio-pci 0000:08:00.0

然后,我们可以启动 vdpa 应用程序,请求它将可用的 vDPA 设备绑定到以 . /tmp/vdpa为前缀的 Vhost 用户套接字

为了使用 Virtio-vDPA 驱动程序而不是 Virtio PMD 探测 Virtio-net 设备,我们必须在 EAL 命令行中将“vdpa=1”设备参数传递给列入白名单的设备。

由于在此示例中只有一个 vDPA 设备,因此应用程序将在以下位置创建单个 vhost-user 套接字/tmp/vdpa0

root@guests $ ./build/examples/dpdk-vdpa -l 0,2 --socket-mem 1024 -w 0000:08:00.0,vdpa=1 -- --iface /tmp/vdpa
EAL: Detected 3 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device 0000:08:00.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 1af4:1041 net_virtio
EAL: PCI device 0000:08:00.0 on NUMA socket 0
EAL:   probe driver: 1af4:1041 net_virtio_vdpa
EAL:   using IOMMU type 1 (Type 1)
iface /tmp/vdpa
VHOST_CONFIG: vhost-user server: socket created, fd: 27
VHOST_CONFIG: bind to /tmp/vdpa0
enter 'q' to quit

Note:因为qemu开启了iommu,所以IOVA mode自动选择了"VA"。

启动用户应用程序

现在,绑定到 vDPA 设备的 vhost-user 套接字已准备好使用,我们可以启动将使用accelerated Virtio datapath的应用程序。

在现实生活中,它可以传递给虚拟机,以便其 Virtio 数据路径绕过主机,但我们已经在客户机中运行,因此这意味着设置嵌套虚拟化。

其他可能的情况是将 vhost-user 套接字传递给容器,以便它可以从高速接口中受益,但我们稍后将在以后的文章中介绍这一点。

为了简单起见,我们将只启动一个 testpmd 应用程序,它将使用 Virtio-user PMD 连接到 vhost-user 套接字。Virtio-user PMD 重用了 Virtio PMD 中的数据路径,但它不是通过 PCI 管理控制路径,而是实现了 vhost-user 协议的主端。

由于我们已经运行了一个 DPDK 应用程序,因此我们必须注意为它将分配的 hugepages 的文件名添加前缀。这要归功于以下命令:

root@guests $ ./install/bin/testpmd -l 0,2 --socket-mem 1024 --file-prefix=virtio-user --no-pci --vdev=net_virtio_user0,path=/tmp/vdpa0

就是这样,我们的加速数据路径已经设置好了!为了确认一切正常,让我们再次尝试注入一些数据包,看看它是否工作正常:

HOST testpmd> start tx_first 512

HOST testpmd> show port stats all
  ######################## NIC statistics for port 0  ########################
  RX-packets: 3565442688 RX-missed: 0          RX-bytes:  228188332032
  RX-errors: 0
  RX-nombuf:  0         
  TX-packets: 3565459040 TX-errors: 0          TX-bytes:  228189378560
  Throughput (since last show)
  Rx-pps:     11997065
  Tx-pps:     11997065
  ############################################################################

在这里插入图片描述
上面描述的是在虚拟环境里,启动了dpdk-vdpa[vhost-user server]和testpmd[vhost-user client]实现通信。使用virtio-user PMD driver,而不需要使用qemu作为[vhost-user client]进行测试。以上测试都不包含热迁移内容。

结论

在这篇文章中,我们使用 DPDK 的 vDPA 框架创建了一个标准的加速数据路径。在直接使用 Virtio PMD 运行初始 testpmd 和设置 vDPA 后运行之间,我们引入了 vDPA 层,以在不影响性能的情况下提供额外的灵活性。

此框架的价值在于,您现在可以试验 vDPA 控制平面,而无需供应商 NIC 支持业界目前正在开发的 vDPA 数据平面(硬件中的环布局支持)。

现在,我们将从 VM 领域转移到容器领域。接下来的实践文章将基于此框架进行构建,以在本地和混合云部署中试验 vDPA 加速容器。

附录

[Centos 8 qcow2镜像下载网址] https://cloud.centos.org/centos/8/x86_64/images/
[Centos 9 stream qcow2镜像下载网址] https://cloud.centos.org/centos/9-stream/x86_64/images/
[virt-sysprep用法]虚拟化技术之kvm镜像模板制作工具virt-sysprep.
vdpa动手博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/411681.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯-扫雷

代码解答及思路: #include <iostream> using namespace std; int main() { int n,m; int a[100][100] {0},b[100][100];//记住要开数组确数 &#xff0c;这样外围就会有边 &#xff0c;不能直接设置值&#xff0c;要记住&#xff01;&#xff01;&#xff01;&#…

FairyGUI × Cocos Creator 3.x 场景切换

前言 前文提要&#xff1a; FariyGUI Cocos Creator 入门 FairyGUI Cocos Creator 3.x 使用方式 个人demo&#xff1a;https://gitcode.net/qq_36286039/fgui_cocos_demo_dust 个人demo可能会更新其他代码&#xff0c;还请读者阅读本文内容&#xff0c;自行理解并实现。 官…

模版(初级)

一.泛型编程 当我们要写一个交换函数时&#xff0c;面对不同的类型&#xff0c;我们可能就需要向如下这么写&#xff1a; void Swap(int& left, int& right) {int temp left;left right;right temp; }void Swap(double& left, double& right) {double tem…

【linux】常见指令 -通配符,数据管道,重定向,压缩打包...

目录 前言 基本指令 ls命令 常见选项 ​编辑 pwd命令 cd 指令 常见选项 touch指令 mkdir指令 常见选项 rm 指令 常见选项 man指令 cp指令 常用选项&#xff1a; mv指令 常用选项 nano指令 如何写入且执行文件&#xff1f; cat指令 常用选项 more指令…

RPA超级自动化、AIGC大模型、低代码、流程挖掘四大热门峰会火热报名中!

由企智未来科技&#xff08;RPA中国、LowCode低码时代、AIGC开放社区&#xff09;主办的第四届「ISIG中国产业智能大会」将于2024年3月16日在上海召开&#xff0c;本届主题为“与科技共赢&#xff0c;与产业共进”。在此次大会中&#xff0c;我们将设立RPA超自动化、低代码/零代…

【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示

学习《OpenCV应用开发&#xff1a;入门、进阶与工程化实践》一书 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; OpenCV开发痛点 传统图像算法开发最好的开源解决方案是OpenCV视觉库&#xff0c;但是OpenCV中收录了2000的传统算法&#xf…

鸿蒙 渲染控制

前提&#xff1a;基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。&#xff08;或有偏颇&#xff0c;自行斟酌&#xff09; 1.概念 ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了…

Linux笔记--硬链接与软链接

一、硬链接 1.inode和block 文件包含两部分数据&#xff1a;文件属性和实际内容&#xff0c;属性放在inode中&#xff0c;实际内容放在data block中。还有个超级区块&#xff08;superblock&#xff09;记录整个文件系统的整体信息&#xff0c;包括inode和block的总量&#x…

基于huggingface加载openai/clip-vit-large-patch14-336视觉模型demo

文章目录 引言一、模型加载二、huggingface梯度更新使用三、图像处理四、模型推理五、整体代码总结 引言 本文介绍如何使用huggingface加载视觉模型openai/clip-vit-large-patch14-336&#xff0c;我之所以记录此方法源于现有大模型基本采用huggingface库来加载视觉模型和大语…

【办公类-22-10】周计划系列(5-2)“周计划-02源文件docx读取5天“ (2024年调整版本)

背景需求 承接上文&#xff0c;继续制作周计划 【办公类-22-09】周计划系列&#xff08;5-1&#xff09;“周计划-01源文件统一名称“ &#xff08;2024年调整版本&#xff09;-CSDN博客文章浏览阅读76次。【办公类-22-09】周计划系列&#xff08;5-1&#xff09;“周计划-01…

LabVIEW燃料电池船舶电力推进监控系统

LabVIEW燃料电池船舶电力推进监控系统 随着全球经济一体化的推进&#xff0c;航运业的发展显得尤为重要&#xff0c;大约80%的世界贸易依靠海上运输实现。传统的船舶推进系统主要依赖于柴油机&#xff0c;这不仅耗能高&#xff0c;而且排放严重&#xff0c;对资源和环境的影响…

2.25 day5 QT

闹钟 .h代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJ…

【Linux操作系统】死锁 | 预防、避免死锁

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;Linux系列专栏&#xff1a;Linux基础 &#x1f525; 给大家…

Codeforces Round 881 (Div. 3) F2. Omsk Metro (hard version)(倍增+最大子段和)

原题链接&#xff1a;F2. Omsk Metro (hard version) 题目大意&#xff1a; 最初开始时&#xff0c;你有一个根节点 1 1 1 且权值为 1 1 1 。 接下来会有 n n n 个操作&#xff0c;每次操作按照如下格式给出&#xff1a; 设操作开始前节点总数为 c n t cnt cnt&#xff1…

小型内衣裤洗衣机哪个牌子好?四大顶尖内衣洗衣机测评分享

要知道&#xff0c;内衣裤可能会残留我们身体分泌的尿液&#xff0c;或者是没有擦干净的便便&#xff0c;以及其他的一些分泌物&#xff0c;据科学家研究发现&#xff0c;内衣裤是含有很多细菌和病毒的地方&#xff0c;如果将内衣裤和衣服放在一起洗&#xff0c;导致这些细菌附…

golang学习1,dea的golang-1.22.0

参考&#xff1a;使用IDEA配置GO的开发环境备忘录-CSDN博客 1.下载All releases - The Go Programming Language (google.cn) 2.直接next 3.window环境变量配置 4.idea的go插件安装 5.新建go项目找不到jdk解决 https://blog.csdn.net/ouyang111222/article/details/1361657…

MySQL数据库集群技术主从复制 一主一从详细讲解

集群技术 集群概述 MySQL复制技术 集群目的 负载均衡 解决高并发 高可用HA 服务可用性 远程灾备 数据有效性 类型 一主一从 一主双从 双主双从 原理 概念 在主库上把数据更改&#xff08;DDL DML DCL&#xff09;记录到二进制日志&#xff08;Binary Log&#xff09;中…

AngularJS安装版本问题

一、安装 Angular CLI 脚手架安装命令&#xff1a; npm install -g angular/cli 在安装前请确保自己安装NodeJS环境版本为V18及以上&#xff0c;否则会因node版本问题导致项目无法正常运行。 脚手架安装后&#xff0c;已提示了当前node版本必须为18.13.0或大于20.9.0版本&…

Linux网卡安装好后自启动

Linux系统配置网卡Wifi博客 https://developer.aliyun.com/article/704878 1、插入网卡iwconfig&#xff0c;查看id是wlxec607385c827 2、创建一个脚本文件 创建一个脚本文件&#xff0c;比如 /usr/local/bin/start_wifi.sh&#xff0c;并添加以下内容&#xff0c;id请根据自…

多维时序 | Matlab实现GRU-MATT门控循环单元融合多头注意力多变量时间序列预测模型

多维时序 | Matlab实现GRU-MATT门控循环单元融合多头注意力多变量时间序列预测模型 目录 多维时序 | Matlab实现GRU-MATT门控循环单元融合多头注意力多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.多维时序 | Matlab实现GRU-MATT门控循环单元融…