STEP BY STEP带你使用Docker搭建MySql-MGR高可用集群

news2025/1/11 0:33:52

数据的重要性

数据已成为当今数字时代最重要的资产之一,对于企业的成功至关重要。它可以帮助企业了解客户、市场和自身运营,提高运营效率,做出明智决策,推动创新,并获得竞争优势。

数据的采集,存储,分析离不开企业的各种软件系统,这些数据最终都会存储在数据库中。确保数据安全,数据完整性,不丢失数据可以说是整个IT团队的责任,是保障系统正常运行和业务连续性的重要保证。

MySQL高可用方案

通常来讲,单台数据库服务器很容易就会发生单点故障,就很有可能造成业务数据的丢失,为了避免单点故障,生产环境的数据库都会采用高可用集群的方式进行部署。

MySQL有几中常见的高可用方案

  • MySQL复制(MySQL Replication)
  • MHA(Master High Availability)
  • MGR(MySQL Group Replication)

今天我们要讲的就是Mysql官方提供的MGR解决方案。更详细的内容,大家可以翻阅Mysql官方关于组复制的参考文档。

MGR简单说明
MySQL Group Replication是MySQL数据库的一种高可用性解决方案,它是基于组复制(Group Replication)技术实现的。它允许多个MySQL服务器之间形成一个同步复制组,实现数据的自动复制和故障转移,从而提高了系统的可用性和容错性。

通过Docker容器模拟搭建一个MGR集群

我们进入今天的主题,带大家一步一步通过Docker容器来快速搭建一个MGR的集群。不过要声明一点,我们这个MGR集群是在本地电脑上模拟出的三个节点,实际上还是属于单点,只是为了让大家熟悉了理解MGR集群创建的整个过程,生产环境请不要按这种方式操作。

容器环境的准备

如果我们的操作系统上还没有安装Docker运行时环境的,可以参考我写的另两篇文章

  • 【Ubuntu 22.04下Docker安装(最全指引)】
  • 【Mac OS下Docker的安装与配置】

准备工作

  • 创建容器网络
  • 创建工作目录

创建容器网络

#创建容器网络,并指定subnet
docker network create --subnet=172.20.0.0/16 mysql-mgr

#检查容器网络
vian@txzq1899-ubuntu:~$ docker network inspect mysql-mgr 
[
    {
        "Name": "mysql-mgr",
        "Id": "6d33e30330ed998c7ceb26971455479d5642d04e015bcfbab720733f9655bd80",
        "Created": "2024-05-07T17:38:32.975808257+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.20.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        }
]

创建工作目录
工作目录主要是用于存放脚本,初始配置文件,容器数据卷,用户名&密码文件

vian@txzq1899-ubuntu:~/ws/mysql$ ll
总计 24
drwxrwxr-x  6 vian vian 4096  58 01:34 ./
drwxrwxr-x 10 vian vian 4096  58 09:40 ../
drwxrwxr-x  5 vian vian 4096  58 01:42 conf/
drwxrwxr-x  5  999 vian 4096  58 01:27 data/
drwxrwxr-x  2 vian vian 4096  58 01:45 script/
drwxrwxr-x  2 vian vian 4096  58 09:50 secrets/

vian@txzq1899-ubuntu:~/ws/mysql/secrets$ ll
总计 16
drwxrwxr-x 2 vian vian 4096  58 09:50 ./
drwxrwxr-x 6 vian vian 4096  58 01:34 ../
-rw-rw-r-- 1 vian vian   11  57 10:38 mysql-root
-rw-rw-r-- 1 vian vian   11  57 10:38 repl-user


脚本源码
本文中所有的操作步骤我都已经进行了脚本化,大家可以上我的github repo上自行下载相关的脚本。

地址如下:MySQL Containerize

https://github.com/TXZQ1899/containerize.git

STEP1、初始化Mysql实例

  • 创建三个MySQL容器
  • 映射数据卷
  • 分配IP地址

以下是脚本源码

  • 容器IP与准备工作中的子网是对应上的。
  • 映射了数据卷
    • 数据库文件
    • 密码文件

我们看到,第一次创建和启动容器是没有使用自定义的my.cnf配置文件的,采用默认方式启动3个MySQL容器节点。

#!/bin/bash

# MySQL的docker容器名
container_names=("mysql-1" "mysql-2" "mysql-3")

# MySQL宿主机端口
host_ports=(3306 3307 3308)
host_ports_x=(13306 13307 13308)
container_ips=("172.20.0.11" "172.20.0.12" "172.20.0.13")

# 批量创建MySQL容器
for i in ${!container_names[@]}
do
    docker run --name ${container_names[$i]} \
    --net mysql-mgr --ip ${container_ips[$i]} \
    -d -p ${host_ports[$i]}:3306 -p ${host_ports_x[$i]}:33061 \
    -v ~/ws/mysql/data/${container_names[$i]}:/var/lib/mysql \
    -v ~/ws/mysql/secrets:/run/secrets \
    -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root \
    mysql:latest
    
    echo "Mysql container : ${container_names[$i]} has been created!"
done

echo "Step 1: MySQL Cluster Initialization Completed!"

STEP2、创建MGR配置文件

这里只是准备三个节点的配置文件,用于第四步中更新配置文件。同样也是使用脚本来批量创建。

vian@txzq1899-ubuntu:~/ws/mysql/conf$ tree
.
├── mysql-1
│   └── my.cnf
├── mysql-2
│   └── my.cnf
└── mysql-3
    └── my.cnf

3 directories, 3 files

请注意源码中,这个组名是一个UUID,大家自行生成即可。

group_replication_group_name="bc946766-0c46-11ef-a8e2-0242ac110002" 

脚本源码如下:

#!/bin/bash

# mysql安装路径
mysql_base_path=~/ws/mysql/conf/

rm -rf ~/ws/mysql/conf/*

# 节点数量和起始IP地址
node_count=3
base_ip="172.20.0.11"

# 将起始IP地址分割成数组
IFS='.' read -ra ADDR <<< "$base_ip"

# 计算最后一个IP片段的起始数字
last_octet=${ADDR[3]}

# 创建配置文件
for ((i=1; i<=node_count; i++))
do
    # 计算每个节点的IP地址
    ip="172.20.0.$((last_octet + i - 1))"
    
    # MySQL配置路径
    conf_path=${mysql_base_path}/mysql-${i}

    # 创建目录
    mkdir -p ${conf_path}

    # 将节点配置写入对应的my.cnf文件
    cat > ${conf_path}/my.cnf <<EOF
[mysqld]
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

server_id=${i}
gtid_mode=ON
enforce_gtid_consistency=ON

plugin_load_add='group_replication.so'

group_replication_group_name="bc946766-0c46-11ef-a8e2-0242ac110002" 
group_replication_start_on_boot=off
group_replication_local_address= "${ip}:33061"
group_replication_group_seeds= "172.20.0.$((last_octet)):33061,172.20.0.$((last_octet + 1)):33061,172.20.0.$((last_octet + 2)):33061"
group_replication_bootstrap_group=off
EOF


done
tree ~/ws/mysql/conf 
echo "MGR配置文件创建完毕!"

STEP3、安装Group Replication插件

这一步是要在三个MySQL实例上安装group replication插件,需要在每一个MySQL实例的命令行执行安装指令。

mysql > install PLUGIN group_replication SONAME 'group_replication.so';

因为我们的MySQL实例部署在docker 容器中,所以需要通过docker exec 这个命令在容器内执行相应的SQL语句。

#mysql-1 是容器名称
#mysql,是容器中的mysql客户端, 
#-u,-p mysql用户名,密码
#-e "sql command;",要执行的SQL
docker exec -it mysql-1 \
mysql -uroot -phelloworld -e "sql command;"

第三步的脚本源码如下:

#!/bin/bash

# 用户信息设置
CONTAINER_NAMES=("mysql-1" "mysql-2" "mysql-3")

# 从环境变量读取root密码
MYSQL_ROOT_PASSWORD=$(<~/ws/mysql/secrets/mysql-root)

# 在每个MySQL实例上执行创建用户和设置权限的步骤
for CONTAINER in "${CONTAINER_NAMES[@]}"
do
    docker exec -it $CONTAINER mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "
    install PLUGIN group_replication SONAME 'group_replication.so';
    "
done

echo "Done"

STEP4、更新MySQL配置文件

这一步比较简单,就是需要将第二步创建的配置文件,复制到容器中mysql配置文件存储的地方。

主要通过docker cp命令实现

docker cp /path/to/file/filename container_name:/path/in/container

批量更新脚本源码如下 :

#!/bin/bash

# MySQL的docker容器名
container_names=("mysql-1" "mysql-2" "mysql-3")


# 批量更新MGR配置文件
for i in ${!container_names[@]}
do
    docker cp ~/ws/mysql/conf/${container_names[$i]}/my.cnf ${container_names[$i]}:/etc/mysql/conf.d 
done

echo "Configuration update complete!"

STEP5、重启MySQL实例

更新完配置文件后需要批量重启MySQL实例,这个也比较简单,通过docker restart container_name来实现
脚本源码如下:

#!/bin/bash

# MySQL的docker容器名
container_names=("mysql-1" "mysql-2" "mysql-3")

# 批量重启MySQL容器
for i in ${!container_names[@]}
do
    docker restart ${container_names[$i]} 
done

echo "Container restart is complete!"

STEP6、创建Replication用户

这一步需要创建用于Replication的用户,授权等操作。和第三步类似,也是通过docker exec在容器内执行相应SQL语句。

具体的SQL语句参考官方文档:

  • 【User Credentials For Distributed Recovery】

脚本源码如下 :

#!/bin/bash

# 用户信息设置
USER='rpl_user'
PASSWORD=$(<~/ws/mysql/secrets/repl-user)
CONTAINER_NAMES=("mysql-1" "mysql-2" "mysql-3")

# 从环境变量读取root密码
MYSQL_ROOT_PASSWORD=$(<~/ws/mysql/secrets/mysql-root)

# 在每个MySQL实例上执行创建用户和设置权限的步骤
for CONTAINER in "${CONTAINER_NAMES[@]}"
do
    docker exec -it $CONTAINER mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "
    SET SQL_LOG_BIN=0;

    CREATE USER IF NOT EXISTS '$USER'@'%' IDENTIFIED BY '$PASSWORD';
    GRANT REPLICATION SLAVE, CONNECTION_ADMIN, BACKUP_ADMIN ON *.* TO '$USER'@'%';
    GRANT GROUP_REPLICATION_STREAM ON *.* TO '$USER'@'%';
    FLUSH PRIVILEGES;

    SET SQL_LOG_BIN=1;
        
    CHANGE REPLICATION SOURCE TO SOURCE_USER='$USER',
        SOURCE_PASSWORD='$PASSWORD' FOR CHANNEL 'group_replication_recovery';
    "
done

echo "Done"

STEP7、设置和开启组复制

这一步就是设置和开启组复制功能,也是需要在数据库中执行相应的SQL指令。

开启组复制的SQL指令参考官方文档:

  • 【Bootstrapping the Group】

MySQL官方称之为引导,指引中有明确讲到:引导应该只由单个服务器完成,即启动群组的服务器,并且只能执行一次。

The process of starting a group for the first time is called bootstrapping. You use the group_replication_bootstrap_group system variable to bootstrap a group. The bootstrap should only be done by a single server, the one that starts the group and only once.

所以最终的脚本如下:

#!/bin/bash

# 用户信息
USER='rpl_user'
PASSWORD=$(<~/ws/mysql/secrets/repl-user)
MYSQL_ROOT_PASSWORD=$(<~/ws/mysql/secrets/mysql-root)

container_names=("mysql-1" "mysql-2" "mysql-3") # 所有容器的名称

for CONTAINER in "${container_names[@]}"
do
  if [ "$CONTAINER" == "mysql-1" ]; then
    # 如果是master容器,执行bootstrapping命令
    echo "Initializing the master ($CONTAINER)..."
    docker exec -it $CONTAINER mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "
      SET GLOBAL group_replication_bootstrap_group=ON;
      START GROUP_REPLICATION USER='$USER', PASSWORD='$PASSWORD';
      SET GLOBAL group_replication_bootstrap_group=OFF;
    "
  else
    # 如果是其它容器,则加入已有集群
    echo "Adding the slave ($CONTAINER) to the group..."
    docker exec -it $CONTAINER mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "
      START GROUP_REPLICATION USER='$USER', PASSWORD='$PASSWORD';
    "
  fi
done

echo "Group replication started for all nodes."

STEP8、检查MGR集群状态

这一步就是检查一下MGR集群的状态,也是通过执行MySQL指令的形式

脚本源码如下:

#!/bin/bash
MYSQL_ROOT_PASSWORD=$(<~/ws/mysql/secrets/mysql-root)
docker exec -it mysql-1 mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "
      SELECT * FROM performance_schema.replication_group_members;
    "

MySQL-MGR-Cluster搭建完成

大家可以在主库上进行一些数据库操作,看看从库是否能实现数据同步。
也可以通过docker stop关闭mysql-1节点(Master),看看MGR机制是否能完成主从的切换。

vian@txzq1899-ubuntu:~/ws/mysql/script$ docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED        STATUS        PORTS                                                                                                 NAMES
84531a0b4f0d   mysql:latest   "docker-entrypoint.s…"   12 hours ago   Up 12 hours   33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp, 0.0.0.0:13308->33061/tcp, :::13308->33061/tcp   mysql-3
f91d0848fac2   mysql:latest   "docker-entrypoint.s…"   12 hours ago   Up 12 hours   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp, 0.0.0.0:13307->33061/tcp, :::13307->33061/tcp   mysql-2
e7f3589bdeac   mysql:latest   "docker-entrypoint.s…"   12 hours ago   Up 12 hours   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp, 0.0.0.0:13306->33061/tcp, :::13306->33061/tcp   mysql-1
vian@txzq1899-ubuntu:~/ws/mysql/script$ 

vian@txzq1899-ubuntu:~/ws/mysql/script$ ./8.check-mgr-cluster-member-status.sh 
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 122dd904-0c97-11ef-a155-0242ac14000b | e7f3589bdeac |        3306 | ONLINE       | PRIMARY     | 8.4.0          | XCom                       |
| group_replication_applier | 125ddf4e-0c97-11ef-a1fb-0242ac14000c | f91d0848fac2 |        3306 | ONLINE       | SECONDARY   | 8.4.0          | XCom                       |
| group_replication_applier | 12a8bbac-0c97-11ef-a14f-0242ac14000d | 84531a0b4f0d |        3306 | ONLINE       | SECONDARY   | 8.4.0          | XCom                       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+

#所有的脚本如下,只需要按次序依次执行即可。
vian@txzq1899-ubuntu:~/ws/mysql/script$ ll
总计 56
drwxrwxr-x 2 vian vian 4096  58 01:45 ./
drwxrwxr-x 6 vian vian 4096  58 01:34 ../
-rwxr-xr-x 1 vian vian  766  58 01:26 1.init-cluster.sh*
-rwxr-xr-x 1 vian vian 1210  58 01:45 2.init-conf.sh*
-rwxrwxr-x 1 vian vian  450  57 22:52 3.install-gr-plugin.sh*
-rwxr-xr-x 1 vian vian  300  58 01:11 4.update-mgr-conf.sh*
-rwxr-xr-x 1 vian vian  260  58 01:13 5.restart-cluster.sh*
-rwxrwxr-x 1 vian vian  861  57 22:52 6.create-repl-user.sh*
-rwxr-xr-x 1 vian vian  989  58 00:58 7.setup-group-replication.sh*
-rwxr-xr-x 1 vian vian  207  58 01:41 8.check-mgr-cluster-member-status.sh*
-rwxr-xr-x 1 vian vian  118  57 17:25 cleanup.sh*
-rwxr-xr-x 1 vian vian   88  57 17:07 remove-cluster.sh*
-rwxr-xr-x 1 vian vian  228  58 01:37 start-cluster.sh*
-rwxr-xr-x 1 vian vian  228  58 01:38 stop-cluster.sh*

留一个思考题,MGR只是保证了MySQL集群的高可用,MGR能自动进行主从的切换,但我们的应用是感知不到这个动作的发生的。一般来讲应用通过域名连接到这个MySQL-MGR-集群,域名又是指向的哪里?如何保证应用能准确的连接到新的主库上呢?

关注我的公众号

欢迎大家关注、点赞、转发,一起交流软件开发、架构设计、云原生技术。
TXZQ聊IT技术与架构

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解析源代码安全的防泄密解决途径

随着各行各业业务数据信息化发展&#xff0c;各类产品研发及设计等行业&#xff0c;都有关乎自身发展的核心数据&#xff0c;包括业务数据、代码数据、机密文档、用户数据等敏感信息&#xff0c;这些信息数据有以下共性&#xff1a; 属于核心机密资料&#xff0c;万一泄密会对…

TCP四次挥手中为什么 TIME_WAIT 等待的时间是 2MSL?

TCP 连接断开 1、TCP 四次挥手过程是怎样的&#xff1f;如下图 2、为什么 TIME_WAIT 等待的时间是 2MSL&#xff1f; MSL 是 Maximum Segment Lifetime&#xff0c;报文最大生存时间&#xff0c;它是任何报文在网络上存在的最长时间&#xff0c;超过这个时间报文将被丢弃。因…

JavaEE技术之MySql高级-ShardingSphere5(SpringBoot版本:3.0.5)

文章目录 1 ShardingSphere-JDBC读写分离1.1 创建SpringBoot程序1.1.1、创建项目1.1.2、添加依赖1.1.3、创建实体类1.1.4、创建Mapper1.1.5、配置 Spring Boot1.1.6、配置shardingsphere 1.2 测试1.2.1 读写分离测试1.2.2 负载均衡测试1.2.3 事务测试常见错误 2 ShardingSphere…

电子商务对应的职业有哪些?10年互联网人透底行业秘密!

电子商务对应的职业有哪些&#xff1f;10年互联网人透底行业秘密&#xff01; 事实说话&#xff0c;实事求是&#xff0c;不要再把美颜滤镜下的市场&#xff0c;传给新人小伙伴了&#xff01; 大家好&#xff0c;我是微三云胡佳东&#xff0c;一家软件公司负责人&#xff01; …

20240508在RK3588的Buildroot系统下播放MP4视频

20240508在RK3588的Buildroot系统下播放MP4视频 2024/5/8 18:09 开发板&#xff1a;飞凌的OK3588-C SDK&#xff1a;Linux/Buildroot R4版本 4.4.2.5 播放 H264 格式视频 [rootok3588:/]# gst-launch-1.0 filesrc location13850_h264.mp4 ! qtdemux ! queue ! h264parse ! mpp…

3D模型素材有哪些常见的用途?

3D模型素材已经成为了设计、游戏开发、电影制作和建筑等领域的重要工具。它们以其独特的形式和丰富的细节&#xff0c;为这些领域的专业人士提供了无尽的创作可能性。 1.建筑和室内设计&#xff1a;在建筑设计中&#xff0c;3D模型可以帮助建筑师更直观地展示设计方案&#xff…

WiFi原理

一、引言 简介&#xff1a;WiFi&#xff0c;全称Wireless Fidelity&#xff0c;是一种允许电子设备连接到一个无线局域网&#xff08;WLAN&#xff09;的技术&#xff0c;通常使用2.4GHz或5GHz UHF&#xff08;特高频&#xff09;和SHF&#xff08;超高频&#xff09;ISM&…

游戏辅助 -- 三种分析角色坐标方法(CE、xdbg、龙龙遍历工具)

所用工具下载地址&#xff1a; https://pan.quark.cn/s/d54e7cdc55e6 在上次课程中&#xff0c;我们成功获取了人物对象的基址&#xff1a;[[[0xd75db8]1C]28]&#xff0c;而人物血量的地址则是基址再加上偏移量278。 接下来&#xff0c;我们需要执行以下步骤来进一步操作&a…

SpringCloud 集成consul,消费者报I/O error on GET request for...

创建消费者微服务&#xff0c;去调用生产者微服务的请求过程中&#xff0c;出现以下错误&#xff1a; 报错原因 因为在使用SpringCloudAlibaba中的Nacos框架时&#xff0c;自动整合了SpringCloud中的Ribbon框架中的负载均衡&#xff0c;因为微服务提供者有两个&#xff0c;在消…

taos数据库服务器安装

涛思数据库服务器安装分为两种情况 一。新服务器直接安装&#xff08;非常好&#xff09; 二。旧服务器删除后删除干净再安装&#xff08;麻烦得很&#xff09; 先来讲解一下情况一&#xff1a; 找需要的taos安装版本链接&#xff1a;https://docs.taosdata.com/releases/tde…

STM32、GD32驱动PCA9685控制舵机源码分享

一、PCA9685介绍 PCA9685是一种16通道PWM&#xff08;脉宽调制&#xff09;控制器芯片&#xff0c;由NXP Semiconductors公司生产。它具有高速I2C总线接口&#xff0c;可以通过I2C总线与微控制器或其他设备进行通信。PCA9685广泛应用于各种需要精确控制多路PWM信号的应用&…

【启明智显技术分享】基于ESP32-S3方案的彩屏固件烧录指南

前言&#xff1a; 【启明智显】专注于HMI&#xff08;人机交互&#xff09;及AIoT&#xff08;人工智能物联网&#xff09;产品和解决方案的提供商&#xff0c;我们深知彩屏显示方案在现代物联网应用中的重要性。为此&#xff0c;我们一直致力于为客户提供彩屏显示方案相关的技…

ThreeJS:补间动画与Tween.JS

补间动画 补间动画指的是做FLASH动画时&#xff0c;在两个关键帧中间需要做“补间动画”&#xff0c;才能实现图画的运动&#xff1b;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。 ——摘自《百度百科&#xff1a;补间动画_百度百科》 Tween.js Tween.js…

JRT失控处理打印和演示

基于JRT完备的脚本化和打印基础&#xff0c;基于JRT的业务可以轻松的实现想要的打效果&#xff0c;这次以质控图的失控处理打印和月报打印来分享基于JRT的打印业务实现。 演示视频链接 失控报告打印 失控处理打印的虚拟M import JRT.Core.DataGrid.GridDto; import JRT.Co…

数据结构(十二)----查找

目录 一.查找的概念 二.查找算法 1.顺序查找 顺序查找的查找效率&#xff1a; 顺序查找的优化&#xff1a; •有序表的优化&#xff08;缩短查找失败的平均查找长度&#xff09; •被查概率不相等的表的优化&#xff08;缩短查找成功的平均查找长度&#xff09; 2.折半…

[Redis] 使用布隆过滤器和分布式锁实现用户注册

布隆过滤器&#xff08;Bloom Filter&#xff09;是一种数据结构&#xff0c;用于快速判断一个元素是否可能存在于一个集合中。它通过使用多个哈希函数和一个位数组来表示一个集合&#xff0c;当一个元素被加入到集合时&#xff0c;通过哈希函数计算出多个哈希值&#xff0c;并…

「网络流 24 题」最小路径覆盖 【最小路径覆盖】

「网络流 24 题」最小路径覆盖 思路 具体可以看 这篇博客 对于有向无环图&#xff0c;我们只需要将假装将点裂成左点和右点&#xff08;实际没有裂开&#xff09;&#xff0c;然后连边&#xff1b; 在上面跑二分图最大匹配后&#xff0c;剩下没有匹配的左点就是终点&#xff…

【linuxC语言】获取进程信息

文章目录 前言一、getrusage函数二、示例代码总结 前言 在Linux环境下&#xff0c;了解和获取进程的信息对于系统监控、性能优化以及调试等任务至关重要。C语言作为Linux系统编程的主要语言之一&#xff0c;提供了丰富的系统调用和库函数&#xff0c;可以帮助我们轻松地获取进…

嵌入式学习69-C++(Opencv)

知识零碎&#xff1a; QT的两种编译模式 1.debug 调试模式 …

javaWeb入门(自用)

1. vue学习 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"https://unpkg.com/vue2"></script> </head> <body><div id"…