当前位置: 首页 > news >正文

第90讲:MySQL数据库主从复制集群原理概念以及搭建流程

文章目录

    • 1.MySQL主从复制集群的核心概念
      • 1.1.什么是主从复制集群
      • 1.2.主从复制集群中的专业术语
      • 1.3.主从复制集群工作原理
      • 1.4.主从复制中的小细节
      • 1.5.搭建主从复制集群的前提条件
      • 1.6.MySQL主从复制集群的架构信息
    • 2.搭建MySQL多实例环境
      • 2.1.在mysql-1中搭建身为主库的MySQL实例
      • 2.2.在mysql-2中搭建MySQL多实例
        • 2.2.1.安装数据库软件
        • 2.2.1.搭建第一个3306从库的MySQL实例
        • 2.2.2.搭建第二个3307从库的MySQL实例
      • 2.3.MySQL多个节点搭建完毕
    • 3.配置MySQL主从复制集群
      • 3.1.在主库开启Binlog二进制日志
      • 3.2.在主库上创建主从复制的用户
      • 3.3.将主库数据备份并在从库中进行还原
      • 3.4.配置从库连接主库的复制信息
      • 3.5.启动主从复制线程
    • 4.查看主从复制集群状态

1.MySQL主从复制集群的核心概念

1.1.什么是主从复制集群

主从复制是指将主数据库的 DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。

MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制。

MySQL 复制的优点主要包含以下三个方面:

  • 主库出现问题,可以快速切换到从库提供服务。
  • 实现读写分离,降低主库的访问压力。
  • 可以在从库中执行备份,以避免备份期间影响主库服务。

1.2.主从复制集群中的专业术语

在MySQL主从复制集群中,主要分为两大部分:文件、线程。

文件:

  • 主库
    • Binlog:二进制日志。
  • 从库
    • relay-log:中继日志,主库推送过来的Binlog日志都存放在中继日志中。
    • master.info:从库复制主库的信息文件,记录着主库的地址、用户、Binlog等信息。
    • relay-log.info:中继日志的信息文件,该文件记录了上次执行relay-log的位置等信息。

线程:

  • 主库
    • binlog_dump_thread:二进制日志投递线程,主要将二进制日志发送给从库的线程。
  • 从库
    • IO_Thread:从库的IO线程,用于请求和接收主库的Binlog二进制日志。
    • SQL_Thread:从库的SQL线程,用于将主库发来的二进制日志在数据库中进行数据复制。

1.3.主从复制集群工作原理

MySQL主从复制集群的工作原理主要围绕前面提到的文件和线程。

MySQL主从复制集群的原理:

1)首先从库执行change master to将连接主库的配置信息记录到master.info文件中,此时从库上会开启两个线程:I/O线程和SQL线程。

2)从库上的I/O线程会从master.info文件中读取主库的连接信息。

3)从库I/O线程获取到主库的信息后,会与主库进行身份认证,然后建立连接。

4)当从库I/O线程成功连接到主库后,主库会立即给从库分配一个binlog_dump_thread线程,用于推送Binlog日志到从库。

5)从库I/O线程会根据master.info中记录的Binlog信息(Binlog日志文件、标识位号)与主库的binlog_dump_thread线程请求最新的Binlog日志。

6)这时主库的binlog_dump_thread线程就会去查询是否产生了新的Binlog日志,如果产生了新的Binlog日志,会截取最新的Binlog日志然后推送给从库的I/O线程。

7)从库的I/O线程接收到主库推送的Binlog日志后,会现将其存放在内存的TCP/IP缓存中,然后告知主库的binlog_dump_thread线程,Binlog日志已收到。

8)此时从库的I/O线程会去更新master.info文件中的Binlog位置点信息,记录最新的Binlog标识号。

9)然后从库的I/O线程会将主库推送的Binlog日志写入到磁盘上的relay-log文件中。

10)最后由从库的SQL线程读取relay-log.ifno文件,获取relay-log最新的位置点,然后根据的位置点去relay-log中执行最新的Binlog日志,执行完成后会再次更新relay-log.info文件中记录的relay-log位置点。

这就是完整的主从复制工作原理。

image-20220705232103542

简单来说MySQL主从复制的原理就是,从库的I/O线程读取连接主库的配置信息,然后去连接主库开始主从同步,当I/O线程连接上主库后,主库会立即给I/O线程分配一个Dump线程,用于推送Binlog日志到从库,此时I/O线程会根据master.info文件中记录的Binlog信息,向主库的Dump线程请求最新的BInlog,Dump线程查询到有最新的Binlog产生,会将最新的Binlog截取,然后推送给从库的I/O线程,I/O线程收到Binlog日志后,将其存放在内存的TCP/IP缓存中,然后更新master.info文件中最新的Binlog信息,紧接着将Binlog日志写入到relay-log中,最后由从库的SQL线程从relay-log.info中读取relay-log的位置号,然后执行relay-log中最新的Binlog日志,执行完成后,再次更新relay-log.info中的relay-log位置号,以便于下次再relay-log中读取最新的Binlog日志。

relay-log日志会通过MySQL中的其他线程定期清理。

1.4.主从复制中的小细节

从上面说的主从复制原理来看,好像每次都是从库向主库去请求新数据,那么什么时候从库才应该向主库请求呢?请求的频率如何?

其实是这样的:当主库上产生了新的事务,更新到Binlog日之后,会给binlog_dump_thread线程发送一个“信号”,binlog_dump_thread线程会与从库的I/O线程一直建立连接,binlog_dump_thread线程就会通知从库的I/O线程有新数据产生了,这时从库的I/O线程就带着master.info中记录的最新Binlog标识位号,向binlog_dump_thread线程请求最新的Binlog,然后完成数据同步。

MySQL主从复制第一次复制时,是按照上面说到的10步完成的,第二次复制时,只需要等待主库的binlog_dump_thread线程向从库的I/O线程发送信号,然后I/O线程去请求最新的Binlog,最后由SQL线程复制数据即可。

1.5.搭建主从复制集群的前提条件

搭建MySQL主从复制集群的前提条件如下:

  • 首先需要准备多个MySQL实例,最少两个MySQL实例,能够实现一主一从的架构,可以在多个服务器中分布部署独立的MySQL节点,也可以在一台服务器中部署多个MySQL实例。
  • 每个MySQL实例都需要由单独的sever_id。
  • 身为主库角色的MySQL实例需要开启二进制日志,从库在特定场景下需要开启。
  • 主库需要授权一个专门的用户作为主从复制的用户。
  • 如果主库是一个运行很多年的数据库,突然要升级为主从复制集群,最好先将主库的数据同步一份到从库中。
  • 开启专用的复制线程。

1.6.MySQL主从复制集群的架构信息

本次主从复制的架构是一主两从的结构。

IP主机名端口角色server_id
192.168.20.11mysql-13306主库1
192.168.20.12mysql-23306从库2
192.168.20.12mysql-23307从库3

2.搭建MySQL多实例环境

再搭建MySQL主从复制集群之前,首先搭建出多个MySQL实例,由于服务器有限,因此通过两台机器模拟出一主两从的环境。

主从复制集群中有一个节点开启了gtid,所有的节点都需要开启gtid,否则主从将不能同步。

2.1.在mysql-1中搭建身为主库的MySQL实例

mysql-1服务器中的3306端口的MySQL实例再前面已经搭建完成了,就是我们一直在使用的数据库实例,里面有数据,更加方便演示主从集群,下面只是提供一下搭建过程的步骤。

注意每个MySQL节点的server_id都要设置成不同的,如果你的一主两从都是单独在不同服务器中部署的,那么直接参考本小结的数据库实例安装即可,不用再看多实例的步骤了。

1.解压MySQL
[root@mysql-1 ~]# tar xf mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
[root@mysql-1 ~]# mv /usr/local/mysql-5.7.36-linux-glibc2.12-x86_64 /usr/local/mysql2.设置MySQL的环境变量
[root@mysql-1 ~]# vim /etc/profile
export MYSQL_HOME=/usr/local/mysql
export PATH=$MYSQL_HOME/bin:$PATH
export LD_LIBRARY_PATH=:/usr/local/mysql/lib3.创建mysql用户
[root@mysql-1 ~]# groupadd -r mysql
[root@mysql-1 ~]# useradd -M -r -s /sbin/nologin -g mysql mysql4.准备数据目录
[root@mysql-1 ~]# mkdir /data/mysql
[root@mysql-1 ~]# chown -R mysql. /data/mysql5.初始化数据库
[root@mysql-1 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql6.准备mysql配置文件
[root@mysql-1 ~]# vim /etc/my.cnf
[mysqld]	
user=mysql								
port=3306							    
server_id=1							#每个MySQL数据库的server_id都设置成不同的
basedir=/usr/local/mysql				
datadir=/data/mysql	
log_bin=mysql-bin
gtid-mode=on
enforce-gtid-consistency=true
socket=/tmp/mysql.sock
log_error=/data/mysql/mysql_err.log
character-set-server=utf8[mysql]
socket=/tmp/mysql.sock7.准备服务管理脚本
[root@mysql-1 ~]# vim /etc/systemd/system/mysqld.service 
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 50008.启动数据库
[root@mysql-1 ~]# systemctl daemon-reload 
[root@mysql-1 ~]# systemctl start mysqld9.设置root密码
[root@mysql-1 ~]# mysqladmin -u root -P 3306  password '123456'10.登陆数据库
[root@mysql-1 ~]# mysql -uroot -p123456
mysql>

2.2.在mysql-2中搭建MySQL多实例

由于服务器数量有限,在mysql-2这台服务器中分别搭建两个从库。

2.2.1.安装数据库软件
1.解压MySQL
[root@mysql-2 ~]# tar xf mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
[root@mysql-2 ~]# mv /usr/local/mysql-5.7.36-linux-glibc2.12-x86_64 /usr/local/mysql2.设置MySQL的环境变量
[root@mysql-2 ~]# vim /etc/profile
export MYSQL_HOME=/usr/local/mysql
export PATH=$MYSQL_HOME/bin:$PATH
export LD_LIBRARY_PATH=:/usr/local/mysql/lib3.创建mysql用户
[root@mysql-2 ~]# groupadd -r mysql
[root@mysql-2 ~]# useradd -M -r -s /sbin/nologin -g mysql mysql
2.2.1.搭建第一个3306从库的MySQL实例

搭建第一个从库实例,端口号为3306,server_id为2,数据路径为/data/mysql3306。

1.创建3306从库的数据目录
[root@mysql-2 ~]# mkdir /data/mysql3306
[root@mysql-2 ~]# chown -R mysql.mysql /data/mysql3306/2.准备3306从库的配置文件
[root@mysql-1 ~]# vim /etc/my3306.cnf
[mysqld]	
user=mysql								
port=3306							    
server_id=2							#每个MySQL数据库的server_id都设置成不同的
basedir=/usr/local/mysql				
datadir=/data/mysql3306	
log_bin=/data/mysql3306/mysql-bin
gtid-mode=on
enforce-gtid-consistency=true
socket=/data/mysql3306/mysql.sock
log_error=/data/mysql3306/mysql_err.log
character-set-server=utf8[mysql]
socket=/data/mysql3306/mysql.sock3.初始化3306从库
[root@mysql-2 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql33064.准备服务管理脚本
[root@mysql-1 ~]# vim /etc/systemd/system/mysqld3306.service 
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my3306.cnf
LimitNOFILE = 50005.启动数据库
[root@mysql-1 ~]# systemctl daemon-reload 
[root@mysql-1 ~]# systemctl start mysqld33066.设置root密码
[root@mysql-2 ~]# mysqladmin -u root -P 3306 -S /data/mysql3306/mysql.sock password '123456'7.登陆数据库
[root@mysql-2 ~]# mysql -uroot -p123456 -P3306 -S /data/mysql3306/mysql.sock
mysql>
2.2.2.搭建第二个3307从库的MySQL实例

搭建第一个从库实例,端口号为3306,server_id为2,数据路径为/data/mysql3306。

1.创建3307从库的数据目录
[root@mysql-2 ~]# mkdir /data/mysql3307
[root@mysql-2 ~]# chown -R mysql.mysql /data/mysql3307/2.准备3307从库的配置文件
[root@mysql-1 ~]# vim /etc/my3307.cnf
[mysqld]	
user=mysql								
port=3307							    
server_id=3							#每个MySQL数据库的server_id都设置成不同的
basedir=/usr/local/mysql				
datadir=/data/mysql3307	
log_bin=/data/mysql3307/mysql-bin
gtid-mode=on
enforce-gtid-consistency=true
socket=/data/mysql3307/mysql.sock
log_error=/data/mysql3307/mysql_err.log
character-set-server=utf8[mysql]
socket=/data/mysql3307/mysql.sock3.初始化3307从库
[root@mysql-2 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql33074.准备服务管理脚本
[root@mysql-1 ~]# vim /etc/systemd/system/mysqld3307.service 
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my3307.cnf
LimitNOFILE = 50005.启动数据库
[root@mysql-1 ~]# systemctl daemon-reload 
[root@mysql-1 ~]# systemctl start mysqld33076.设置root密码
[root@mysql-2 ~]# mysqladmin -u root -P 3307 -S /data/mysql3307/mysql.sock password '123456'7.登陆数据库
[root@mysql-2 ~]# mysql -uroot -p123456 -P3307 -S /data/mysql3307/mysql.sock
mysql>

2.3.MySQL多个节点搭建完毕

MySQL多个节点已经搭建完毕了,下面来查询每个实例的server_id。

image-20220705001555462

3.配置MySQL主从复制集群

MySQL数据库的多个实例节点已经搭建完成了,下面将这些搭建的数据库实例配置成主从复制集群(一主两从)。

IP主机名端口角色
192.168.20.11mysql-13306主库
192.168.20.12mysql-23306从库
192.168.20.12mysql-23307从库

配置MySQL主从复制集群的大致步骤:

  • 主库开启Binlog日志,从库复制主库数据要通过Binlog进行复制。
  • 主库创建专门用作主从复制的用户。
  • 将主库数据进行备份,再从库中恢复。
  • 配置从库连接主库的复制信息。
  • 启动主从复制集群。

3.1.在主库开启Binlog二进制日志

主库已经开启了Binlog二进制日志,我们来查一下。

mysql> show variables like '%log_bin%';
+---------------------------------+-----------------------------+
| Variable_name                   | Value                       |
+---------------------------------+-----------------------------+
| log_bin                         | ON                          |
| log_bin_basename                | /data/mysql/mysql-bin       |
| log_bin_index                   | /data/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                         |
| log_bin_use_v1_row_events       | OFF                         |
| sql_log_bin                     | ON                          |
+---------------------------------+-----------------------------+
6 rows in set (0.01 sec)

从库复制主库数据,都是通过Binlog进行传输和恢复的。

3.2.在主库上创建主从复制的用户

mysql> grant replication slave on *.* to replicas@'192.168.20.%' identified by '123456';

3.3.将主库数据备份并在从库中进行还原

如果是运行很久的主库,要升级为主从复制集群,那么建议将主库上的数据备份还原到从库上,避免从库一次性同步很多数据,浪费性能。

[root@mysql-1 ~]# mysqldump -uroot -p123456 -A --master-data=2 -R -E --triggers --single-transaction > all_db.sql

在192.168.20.12的两个从库中还原主库的备份数据。

1.将备份上传到从库的服务器上
[root@mysql-1 ~]# scp -rp all_db.sql root@192.168.20.12:/root2.3306从库还原主库备份数据
[root@mysql-2 ~]# mysql -uroot -p123456 -P3306 -S /data/mysql3306/mysql.sock 
mysql> set sql_log_bin=0;
mysql> source /root/all_db.sql;3.3307从库还原主库备份数据
[root@mysql-2 ~]# mysql -uroot -p123456 -P3307 -S /data/mysql3307/mysql.sock 
mysql> set sql_log_bin=0;
mysql> source /root/all_db.sql;

3.4.配置从库连接主库的复制信息

接下来我们需要配置从库连接主库的信息,包括让从库知道主库的IP、端口号、复制的用户密码、Binlog相关的信息。

1)获取主库Binlog的信息

从库是通过Binlog复制主库数据的,首先要获取主库Binlog日志的一些信息,包括主库的Binlog日志使用的是哪个、要从Binlog日志中的哪一个事件标识号处开始复制数据。

从Binlog的哪一个事件标识号处开始复制数据,尤为关键,因为主库可能运行的时间长了,也有很多的数据,一定要从合适的位置处开始复制数据,要不然也会产生很大的资源浪费。

我们是用主库头一天的全库备份,然后还原到从库上的,在主库的备份文件中就记录了从库应该从哪一个Binlog事件标识位处开始复制数据。

vim all_db.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=452;

从备份文件中得知,我们应该让从库从主库Binlog事件标识位号452处,开始复制数据。

如果主库不是运行很久的,不需要备份数据还原到从库,而是直接搭建的主从复制集群,那么直接可以从主库状态信息那里,获取Binlog的标识位号,在配置主从时,一定要指对Binlog标识位号,否则主从将会失败。

mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000001 |      452 |              |                  | 4f87bad8-fc67-11ec-be7b-005056b791aa:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

2)配置从库连接主库进行复制的参数信息

配置从库连接主库进行复制的参数有很多,不过只需要记住这一条命令:help change master to即可,在MySQL交互式下执行此命令可以打印出从库连接主库的所有配置参数。

1.3306从库配置
[root@mysql-2 ~]# mysql -uroot -p123456 -P3306 -S /data/mysql3306/mysql.sock 
mysql> CHANGE MASTER TOMASTER_HOST='192.168.20.11',MASTER_USER='replicas',MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=452,MASTER_CONNECT_RETRY=10;1.3307从库配置
[root@mysql-2 ~]# mysql -uroot -p123456 -P3307 -S /data/mysql3307/mysql.sock 
mysql> CHANGE MASTER TOMASTER_HOST='192.168.20.11',MASTER_USER='replicas',MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=452,MASTER_CONNECT_RETRY=10;  

参数解释:

参数含义
MASTER_HOST主库的地址
MASTER_USER主从复制的专用用户
MASTER_PASSWORD主从复制用户的密码
MASTER_PORT主库的端口号
MASTER_LOG_FILE主库的Binlog日志名
MASTER_LOG_POS从主库BInlog日志的哪一个标识位处开始复制
MASTER_CONNECT_RETRY主从连接失败的重试时间间隔

3.5.启动主从复制线程

1.3306从库配置
[root@mysql-2 ~]# mysql -uroot -p123456 -P3306 -S /data/mysql3306/mysql.sock 
mysql> start slave;1.3307从库配置
[root@mysql-2 ~]# mysql -uroot -p123456 -P3307 -S /data/mysql3307/mysql.sock 
mysql> start slave;

4.查看主从复制集群状态

1.3306从库配置
[root@mysql-2 ~]# mysql -uroot -p123456 -P3306 -S /data/mysql3306/mysql.sock 
mysql> show slave status\G;1.3307从库配置
[root@mysql-2 ~]# mysql -uroot -p123456 -P3307 -S /data/mysql3307/mysql.sock 
mysql> show slave status\G;

当每个从库的IO线程和SQL线程的状态都是Yes,就表示主从复制集群搭建完毕了。

image-20220706000742368

MySQL主从配置过程中从库连接主库的配置写错了应该如何解决?

只要不执行start slave,再执行一次change master to会覆盖上一次配置。

1.停止主从复制
mysql>stop slave;2.清空从库连接主库的信息
mysql> reset slave all;3.重新设置
mysql> CHANGE MASTER TOMASTER_HOST='192.168.20.11',MASTER_USER='replicas',MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=452,MASTER_CONNECT_RETRY=10;

相关文章:

第90讲:MySQL数据库主从复制集群原理概念以及搭建流程

文章目录 1.MySQL主从复制集群的核心概念1.1.什么是主从复制集群1.2.主从复制集群中的专业术语1.3.主从复制集群工作原理1.4.主从复制中的小细节1.5.搭建主从复制集群的前提条件1.6.MySQL主从复制集群的架构信息 2.搭建MySQL多实例环境2.1.在mysql-1中搭建身为主库的MySQL实例2…...

PHP反序列化漏洞-魔术方法绕过

一、__wakeup()魔法函数绕过: 在PHP中,__wakeup()是一个魔术方法,用于在反序列化对象时自动调用。当反序列化字符串中的对象属性个数大于实际属性个数时,可以利用这个漏洞进行绕过。 触发条件: PHP版本为5.6.25或早期版本,或者PHP7版本小于7.0.10。反序列化字符串中的对…...

抖店和商品橱窗的区别?这两个千万别再搞混了!

我是电商珠珠 很多人都会将抖店和商品橱窗搞混,想开抖店的人开了商品橱窗,想开橱窗的人开通了抖店。 我做抖店三年了,这种情况屡见不鲜。 那么抖店和商品橱窗究竟有什么区别呢? 1、属性不同 商品橱窗是抖音所展现商品的一个功…...

个人总结钉钉7.5新品发布会

钉钉发布了 7.5 版本,最主要推出了围绕AI能力的各项升级,通过AI“超级助理”提升组织内部的沟通协作效率、管理决策智能化程度,以及相关的音视频、在线文档、Teambition功能的升级,以满足不同企业的多元化需求。截至发布会&#x…...

连接超时的问题

连接超时的问题 通用第三方工具连接超时 connect timeout 方案一: /etc/ssh/sshd_config node1上操作,图是错的 方案二: windows上Hosts文件域名解析有问题 比如: 192.168.xx.100 node1 192.168.xx.161 node1 两个都解析成node…...

python贪吃蛇游戏

为了实现这个游戏,需要用到Python的pygame模块,它是一个专门用于开发游戏的模块,提供了很多方便的功能,比如窗口、图形、音效、事件处理等。 用pygame来创建一个窗口,设置游戏的背景色,画出蛇和食物&#…...

【Spring】Spring AOP

文章目录 前言1. 什么是 AOP2. 什么是 Spring AOP3. Spring AOP 的使用引入 AOP 依赖编写 AOP 程序 4. Spring AOP 详解4.1 Spring AOP 的概念4.1.1 切点4.1.2 连接点4.1.3 通知4.1.4 切面 4.2 通知类型4.3 切点4.4 切面优先级 Order注解4.5 切点表达式4.5.1 execution 切点表达…...

软件开发架构

【 一 】软件开发架构图 【 1】ATM和选课系统 三层的开发架构 前段展示台 后端逻辑层 数据处理层 【二】软件开发架构的步骤流程 需求分析:在软件开发架构设计之前,需要对应用系统进行需求分析,明确用户需求、功能模块、业务流程等内容。…...

计图大模型推理库部署指南,CPU跑大模型,具有高性能、配置要求低、中文支持好、可移植等特点

Excerpt 计图大模型推理库,具有高性能、配置要求低、中文支持好、可移植等特点 计图大模型推理库,具有高性能、配置要求低、中文支持好、可移植等特点 计图大模型推理库 - 笔记本没有显卡也能跑大模型 本大模型推理库JittorLLMs有以下几个特点: 成本低:相比同类框架,本库…...

CSS||Emmet语法

1、简介 ​ Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法。 ​ 快速生成HTML结构语法 ​ 快速生成CSS样式语法 2、快速生成HTML结构语法 生成标签 直接输入标签名 按tab键即可 比如 div 然后tab 键&#xff0c; 就可以生成 <…...

Android中的anr定位指导与建议

1.背景 8月份安卓出现了一次直播间卡死(ANR)问题&#xff0c;且由于排查难度较大&#xff0c;持续了较长时间。本文针对如何快速定位安卓端出现ANR问题进行总结和探讨. 这里大致补充一下当时的情况,当时看到情景的是从某一个特定的场景下进入直播间后整个直播间界面立刻就卡住…...

YOLOV7剪枝流程

YOLOV7剪枝流程 1、训练 1&#xff09;划分数据集进行训练前的准备&#xff0c;按正常的划分流程即可 2&#xff09;修改train.py文件 第一次处在参数列表里添加剪枝的参数&#xff0c;正常训练时设置为False&#xff0c;剪枝后微调时设置为True parser.add_argument(--pr…...

【React】组件性能优化、高阶组件

文章目录 React性能优化SCUReact更新机制keys的优化render函数被调用shouldComponentUpdatePureComponentshallowEqual方法高阶组件memo 获取DOM方式refs如何使用refref的类型 受控和非受控组件认识受控组件非受控组件 React的高阶组件认识高阶函数高阶组件的定义应用一 – pro…...

前端开发中基于Web Speech API(speechSynthesis接口)实现文字转语音功能

文章目录 一、Web Speech 的概念及用法二、Web Speech 的 API 接口1、SpeechSynthesis属性方法 2、SpeechSynthesisUtterance属性方法 三、Web Speech 的 用法用法演示一用法演示二htmljs 四、扩展 一、Web Speech 的概念及用法 在开发业务系统时&#xff0c;有时候可能需要使…...

C++核心编程之通过类和对象的思想对文件进行操作

目录 ​​​​​​​一、文件操作 1. 文件类型分类&#xff1a; 2. 操作文件的三大类 二、文本文件 1.写文件 2.读文件 三、二进制文件 1.写二进制文件 2.读二进制文件 一、文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放 通过文件可以将…...

Verilog语法——4.Verilog工程模板、相应规范再强调

参考资料 【明德扬_verilog零基础入门语法HDL仿真快速掌握-手把手教你写FPGA/ASIC代码设计流程中的应用】 4. Verilog工程模板、相应规范 4.1 Verilog工程模板 4.1.1 设计模块模板 module module_name(clk,rst_n,//其他信号&#xff0c;举例doutdout };//参数定义parameter …...

CNN:Convolutional Neural Network(下)

目录 1 CNN 学到的是什么 1.1 Convolution 中的参数 1.2 FFN 中的参数 1.3 Output 2 Deep Dream 3 Deep Style 4 More Application 4.1 AlphaGo 4.2 Speech 4.3 Text 原视频&#xff1a;李宏毅 2020&#xff1a;Convolutional Neural Network 本博客属于学…...

FPGA时序分析与时序约束(四)——时序例外约束

目录 一、时序例外约束 1.1 为什么需要时序例外约束 1.2 时序例外约束分类 二、多周期约束 2.1 多周期约束语法 2.2 同频同相时钟的多周期约束 2.3 同频异相时钟的多周期约束 2.4 慢时钟域到快时钟域的多周期约束 2.5 快时钟域到慢时钟域的多周期约束 三、虚假路径约…...

无需任何三方库,在 Next.js 项目在线预览 PDF 文件

前言&#xff1a; 之前在使用Vue和其它框架的时候&#xff0c;预览 PDF 都是使用的 PDFObject 这个库&#xff0c;步骤是&#xff1a;下载依赖&#xff0c;然后手动封装一个 PDF 预览组件&#xff0c;这个组件接收本地或在线的pdf地址&#xff0c;然后在页面中使用组件的车时候…...

排序问题——晴问题库

排序问题——晴问题库 排序问题是线性数据的常考问题&#xff0c;在解晴问题库时总结归纳以下关于排序的解题方法和思路。 感谢晴神 排序问题是数据结构中十分重点的一部分。 可以分为五个大部分&#xff1a; 插入排序选择排序交换排序基数归并 再具体往下分&#xff1a; 插…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...