MySQL数据库主从复制+mycat读写分离+MHA实操

news2025/1/14 2:37:35

目录

一、主从复制

1.1 主从复制简介

1.2 MySQL支持的复制类型

1.3 主从复制的工作过程

1.4 主从复制的同步模式

1.4.1 异步复制(Asynchronous replication)

1.4.2 全同步复制(Fully synchronous replication)

1.4.3 半同步复制(Semisynchronous replication)

范例1:新建主从复制

主节点操作:

从节点:

范例2:级联 主从复制

主节点:

2级节点:

从节点:

范例3:半同步复制

主节点:

从节点:

二、读写分离

2.1mycat实现读写分离

2.1.1 mycat安装目录结构说明

2.1.2 Mycat的常用配置文件

2.1.3 Mycat日志

2.2 mycat 实现读写分离实际操作

1.环境准备

2.初始化环境

3.部署主从复制

4.安装mycat(192.168.10.30)

5.修改 mycat 配置文件 /apps/mycat/conf/server.xml

6.修改 mycat 配置文件/apps/mycat/conf/schema.xml

详细解读:

7. 主服务器上授权

8.重启mycat服务,客户机连接mycat

9.客户端测试读写分离

三、 MHA实操

1关闭防火墙selinux

2.主节点(7-4)安装 管理和客户端工具

3.其余所有节点(7-1,7-2,7-3)安装客户端

4. 所有节点 基于key验证

5 主节点(7-4)建立mha文件夹和配置文件

6 准备切换脚本

7实现主从复制

7.1主服务器操作(7-1)

7.2从服务器设置(7-2,7-3)

7.2.1 服务器7-2配置

7.2.2服务器7-3配置

8.设置虚拟地址

9在运行前需要先检测环境是否符合

9.1 检测 ssh 免密登录是否成功

9.2 检测主从复制 是否可以

9.3 查看状态未开启

10 开启mha

11测试

11.1 mha 如何发现主节点宕机

11.2 查看 mha 服务的日志

11.3 模拟 mysql 主节点故障


一、主从复制

1.1 主从复制简介

MySQL主从复制是一种数据库复制技术,用于将一个MySQL数据库服务器的更改同步到其他MySQL数据库服务器。

在主从复制中,有一个主数据库(Master)和一个或多个从数据库(Slave)。

主数据库负责接收和处理所有的写操作,而从数据库则通过复制主数据库的日志文件,将这些写操作在自身的数据库中重演,从而实现数据的同步。

1.2 MySQL支持的复制类型

1)STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高;

2)ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍;

3)MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

1.3 主从复制的工作过程

主从复制原理:
1主节点负责用户的写操作,用户发起写操作后,会修改数据库
2.数据库修改后,会更新主节点上的二进制日志
3.主服务器会产生一个  dump线程, 一边读取二进制日志一边将二进制日志通过 网络传给从服务器
4.从服务器会开启io线程,接收主服务器的二进制日志
5 会写入中继日志,这时只是生成了一个文件,并没有同步
6.从服务器再开启  sql线程将 中继日志中  操作写入数据库完成更新

1.4 主从复制的同步模式

1.4.1 异步复制(Asynchronous replication)

一个主库,一个或多个从库,数据异步同步到从库。

MySQL默认的复制即是异步的
主库在执行完客户端提交的事务后会立即将结果返给客户端,并不关心从库是否已经接收并处理。

这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

1.4.2 全同步复制(Fully synchronous replication)

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。
因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

1.4.3 半同步复制(Semisynchronous replication)

在异步复制的基础上,确保任何一个主库上的事务在提交之前至少有一个从库已经收到该事务并记录。

介于异步复制和全同步复制之间。

主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端(只能保证主库的 Binlog 至少传输到了一个从节点上),否则需要等待直到超时时间然后切换成异步模式再提交。

相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。
所以,半同步复制最好在低延时的网络中使用。

范例1:新建主从复制

主节点:192.168.10.40

从节点:192.168.10.20

主节点操作:

[root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=100
log-bin=/data/mysql-bin

[root@localhost ~]#mkdir /data/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld

select @@server_id;
#可以查看serverid  默认都是1
show master status;
#查看二进制日志位置


grant replication slave on *.* to test@'192.168.91.%' identified by 'Admin@123';
#建立复制用户

show processlist;
#查看线程

从节点:

[root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=102
log-bin=/data/mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
#read-only  #只读可加


[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld


CHANGE MASTER TO
  MASTER_HOST='192.168.10.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=437;

show slave status\G;
#查看设置的状态
Seconds_Behind_Master: NULL    #目前数据差

start slave;
#开启线程,开启主从复制



create database cxk;
#在主节点上建立数据测试

TIP:主从复制前的操作可以使用完全备份导入从节点中使主从一致

范例2:级联 主从复制

主节点:

root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=100
log-bin=/data/mysql/mysql-bin

[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld


select @@server_id;
#可以查看serverid  默认都是1
show master status;
#查看二进制日志位置


grant replication slave on *.* to test@'192.168.10.%' identified by 'Admin@123';
#建立复制用户

show processlist;
#查看线程

2级节点:

root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=101
log-bin=/data/mysql/mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
log_slave_updates
#read-only  #只读可加


[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld



下面修改配置 命令较长可以使用帮助
help change master to


CHANGE MASTER TO
  MASTER_HOST='192.168.10.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=604;
  注意最后分号




show slave status\G;
#查看设置的状态
Seconds_Behind_Master: NULL    #目前数据差

start slave;
#开启线程,开启主从复制

show master logs;
#查看  从节点的复制位置

从节点:

root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=102
log-bin=/data/mysql/mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
#read-only  #只读可加


[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld



下面修改配置 命令较长可以使用帮助
help change master to


CHANGE MASTER TO
  MASTER_HOST='192.168.10.20',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=448;
  注意最后分号




show slave status\G;
#查看设置的状态
Seconds_Behind_Master: NULL    #目前数据差

start slave;
#开启线程,开启主从复制

范例3:半同步复制

实现:

rpm -ql mysql-community-server |grep semisync
#需要安装插件

主节点:

[root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=100
log-bin=/data/mysql/mysql-bin
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_master_timeout=3000
#修改此行,需要先安装semisync_master.so插件后,再重启,否则无法启动 开启半同步
#设置3s内无法同步,也将返回成功信息给客户端

[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld
[root@localhost ~]#mysql -uroot -pAdmin@123

mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; #永久安装插件
mysql>UNINSTALL PLUGIN rpl_semi_sync_master ;
mysql>rpm -ql mysql-community-server |grep semisync #查看插件
mysql>SET GLOBAL rpl_semi_sync_master_enabled=1; #临时修改变量
mysql>SET GLOBAL rpl_semi_sync_master_timeout = 3000;  #超时长1s,默认值为10s

mysql>SHOW GLOBAL VARIABLES LIKE '%semi%';
#查看半同步状态

show global status like '%semi%';
#查看半同步客户端

show  master  status;

grant replication slave on *.* to test@'192.168.10.%' identified by 'Admin@123';
#建立复制用户

从节点:

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
#安装插件

[root@slave1 ~]#vim /etc/my.cnf
[mysqld]
server-id=101
rpl_semi_sync_slave_enabled=ON #修改此行,需要先安装semisync_slave.so插件后,再重启,否则无法启动


CHANGE MASTER TO
  MASTER_HOST='192.168.10.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=154;
  注意最后分号
  
  
  
show global status like '%semi%';
#查看状态  主从状态


mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql>SET GLOBAL rpl_semi_sync_slave_enabled=1; #临时修改变量
mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';

二、读写分离

2.1mycat实现读写分离

2.1.1 mycat安装目录结构说明

  • bin :mycat命令,启动、重启、停止等运行目录

  • catlet: catlet为Mycat的一个扩展功能

  • conf  :mycat 配置信息,重点关注

  • lib:mycat引用的jar包,Mycat是java开发的

  • logs日志文件,包括Mycat启动的日志和运行的日志

  • version.txt :mycat版本说明

2.1.2 Mycat的常用配置文件

Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:

  • server.xml :Mycat软件本身相关的配置文件,设置账号、参数等

  • schema.xml:Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制

  • rule.xml:Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等

2.1.3 Mycat日志

Mycat的日志文件都在logs目录里面

  • wrapper.log :mycat启动日志

  • mycat.log :mycat详细工作日志

2.2 mycat 实现读写分离实际操作

1.环境准备

mycat服务器上不能装mysql

master服务器192.168.10.40
slave1服务器192.168.10.20
mycat服务器192.168.10.30
客户机192.168.10.10

2.初始化环境

#每台服务器上都初始化,关闭防火墙
systemctl stop --now firewalld
systemctl disable firewalld
setenforce 0

3.部署主从复制

###################### 主mysql服务器配置(192.168.10.40)########################
[root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=100
log-bin=/data/mysql/mysql-bin

[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld

select @@server_id;
#可以查看serverid  默认都是1
show master status;
#查看二进制日志位置


grant replication slave on *.* to test@'192.168.10.%' identified by 'Admin@123';
#建立复制用户

show processlist;
#查看线程


############################# 从mysql服务器配置(192.168.10.20)################
[root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=101
log-bin=/data/mysql/mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
#read only  #只读可加


[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld



下面修改配置 命令较长可以使用帮助
help change master to


CHANGE MASTER TO
  MASTER_HOST='192.168.10.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=448;
  注意最后分号



show slave status\G;
#查看设置的状态
Seconds_Behind_Master: NULL    #目前数据差

start slave;
#开启线程,开启主从复制



create database cxk;
#在主节点上建立数据测试


####################### 在master服务器上上传库文件,并在从服务器上验证主从同步 ############

#在主服务器上下载hellodb库文件,source后加绝对路径
[root@localhost ~]#mysql -uroot -pAdmin@123
#下载hellodb库文件
source /bak/hellodb.sql
show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

#在从库中查看库文件hellodb是否已经同步
show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

4.安装mycat(192.168.10.30)

(1)主机上安装java(mycat基于java)
#yum安装java
[root@localhost ~]#yum install java -y
#确认安装成功
[root@localhost ~]#java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)

(2)切换至opt目录,下载mycat安装包
[root@localhost ~]#cd /opt
[root@localhost ~]#wget http://dl.mycat.org.cn/1.6.7.6/20210303094759/Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz

(3)创建/apps文件夹,并解压mycat包至/apps下
[root@localhost ~]#mkdir /apps
[root@localhost ~]#tar zxvf Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz -C /apps/

(4)设置变量环境
[root@localhost ~]#echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh
[root@localhost ~]#source /etc/profile.d/mycat.sh

(5)启动mycat,查看日志文件,最后可以看到启动成功
[root@localhost ~]#mycat start
#注意内存小于2G 起不来
Starting Mycat-server...

[root@localhost ~]#tail -f /apps/mycat/logs/wrapper.log
#启动成功日志末尾会出现successfully
STATUS | wrapper  | 2021/12/09 21:04:10 | --> Wrapper Started as Daemon
STATUS | wrapper  | 2021/12/09 21:04:10 | Launching a JVM...
INFO   | jvm 1    | 2021/12/09 21:04:11 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO   | jvm 1    | 2021/12/09 21:04:11 |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
INFO   | jvm 1    | 2021/12/09 21:04:11 | 
INFO   | jvm 1    | 2021/12/09 21:04:12 | MyCAT Server startup successfully. see logs in logs/mycat.log


(6)客户端连接数据库
#这里密码初始为123456   需要加端口
[root@localhost bin]#mysql -uroot -p123456 -h 192.168.10.30 -P8066

5.修改 mycat 配置文件 /apps/mycat/conf/server.xml

[root@localhost ~]#vim /apps/mycat/conf/server.xml

#去掉44行行注释,对应的在51行行末注释,删除50行行末注释,5 * 60 * 1000L; //连接空>    闲检查

#修改45行端口号为3306
45 <property name="serverPort">3306</property>

#配置Mycat的连接信息(账号密码),在110 和111行, 可以修改,这边不修改了
####参数解释说明####
110         <user name="root" defaultAccount="true">
111                 <property name="password">123456</property>
112                 <property name="schemas">TESTDB</property>
113                 <property name="defaultSchema">TESTDB</property>

116                 <!-- 表级 DML 权限设置 -->
117                 <!-- 
118                 <privileges check="false">
119                         <schema name="TESTDB" dml="0110" >
120                                 <table name="tb01" dml="0000"></table>
121                                 <table name="tb02" dml="1111"></table>
122                         </schema>
123                 </privileges>   
124                  -->

127         <user name="user">
128                 <property name="password">user</property>
129                 <property name="schemas">TESTDB</property>
130                 <property name="readOnly">true</property>
131                 <property name="defaultSchema">TESTDB</property>

user    用户配置节点
name    逻辑用户名,客户端登录MyCAT的用户名,也就是客户端用来连接Mycat的用户名。
password     客户端登录MyCAT的密码
schemas      数据库名,这里会和schema.xml中的配置关联,可配置多个,多个用逗号分开,例如:db1,db2
privileges   配置用户针对表的增删改查的权限
readOnly mycat   逻辑库所具有的权限。true为只读,false为读写都有,默认为false

##注意
1.#server.xml文件里登录mycat的用户名和密码可以任意定义,这个账号和密码是为客户机登录mycat时使用的账号信息
2.#逻辑库名(如上面的TESTDB,也就是登录mycat后显示的库名,切换这个库之后,显示的就是代理的真实mysql数据库的表)要在schema.xml里面也定义,否则会导致mycat服务启动失败!这里只定义了一个标签,所以把多余的都注释了。如果定义多个标签,即设置多个连接mycat的用户名和密码,那么就需要在schema.xml文件中定义多个对应的库!

6.修改 mycat 配置文件/apps/mycat/conf/schema.xml

schema.xml是最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的.MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
        <dataNode name="dn1" dataHost="localhost1" database="hellodb" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="host1" url="192.168.10.40:3306" user="root" password="Admin@123">
                 <readHost host="host2" url="192.168.10.20:3306" user="root" password="Admin@123"/>
                </writeHost>
        </dataHost>
</mycat:schema>
详细解读:
[root@localhost ~]#vim  /apps/mycat/conf/schema.xml
#删除所有内容,重新写入以下
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        #schema标签:数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应。
        #name:逻辑数据库名,与server.xml中的schema对应;
        #checkSQLschema: 数据库前缀相关设置,这里为false;
        #sqlMaxLimit:  select时默认的limit,避免查询全表,否则可能会遇到查询量特别大的情况造成卡 死;
        #dataNode:表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name
</schema>
        <dataNode name="dn1" dataHost="localhost1" database="hellodb" />
        #dataNode标签: 定义mycat中的数据节点,也是通常说的数据分片,也就是分库相关配置
        #name: 定义数据节点的名字,与table中dataNode对应
        #datahost: 物理数据库名,与datahost中name对应,该属性用于定义该分片属于哪个数据库实例
        #database: 物理数据库中数据库名,该属性用于定义该分片属性哪个具体数据库实例上的具体库
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
        #dataHost标签: 物理数据库,真正存储数据的数据库
        #name: 物理数据库名,与dataNode中dataHost对应
        #maxCon属性指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost标  签都会使用这个属性的值来实例化出连接池的最大连接数
        #minCon属性指定每个读写实例连接池的最小连接,初始化连接池的大小
        #balance: 均衡负载的方式
       
                  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                  #writeType: 写入方式
                  #dbType: 数据库类型
                  #dbDriver指定连接后端数据库使用的 Driver,目前可选的值有 native 和 JDBC。用 native 的话,因为这个值执行的是二进制的 mysql 协议,所以可以使用 mysql 和maridb。其他类型的数据库则需要使用 JDBC 驱动来支持。
                  #switchType:  “-1” 表示不自动切换; “1” 默认值,自动切换; “2” 基于 MySQL主从同步的状态决定是否切换心跳语句为 show slave status; “3” 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)心跳语句为 show status like ‘wsrep%’.
                <heartbeat>select user()</heartbeat>
                #heartbeat: 心跳检测语句,注意语句结尾的分号要加
                <writeHost host="host1" url="192.168.10.40:3306" user="root" password="Admin@123">
                #host:用于标识不同实例,一般 writeHost 我们使用*M1,readHost 我们用*S1。
                #url:后端实例连接地址。Native:地址:端口 JDBC:jdbc的url
                #user:后端存储实例需要的用户名字
                #password:后端存储实例需要的密码
                 <readHost host="host2" url="192.168.10.20:3306" user="root" password="Admin@123"/>

                </writeHost>
        </dataHost>
</mycat:schema>


#schema.xml文件中有三点需要注意:balance="1",writeType="0" ,switchType="1" 
#schema.xml中的balance的取值决定了负载均衡对非事务内的读操作的处理。balance 属性负载均衡类型,目前的取值有 4 种:
##balance="0":不开启读写分离机制,所有读操作都发送到当前可用的writeHost上,即读请求仅            发送到writeHost上
##balance="1":一般用此模式,读请求随机分发到当前writeHost对应的readHost和standby的writeHost上。即全部的readHost与stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1 ->S1 , M2->S2,并且 M1 与 M2 互为主备),正常情况下, M2,S1, S2 都参与 select 语句的负载均衡
##balance="2":读请求随机分发到当前dataHost内所有的writeHost和readHost上。即所有读操作都随机的在writeHost、 readhost 上分发
##balance="3":读请求随机分发到当前writeHost对应的readHost上。即所有读请求随机的分发wiriterHost 对应的 readhost 执行, writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有

###writeHost和readHost标签,这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是:writeHost指定写实例、readHost指定读实例,组着这些读写实例来满足系统的要求。在一个dataHost内可以定义多个writeHost和eadHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去   
               
#PS:Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost

7. 主服务器上授权

[root@localhost ~]#mysql -uroot -p123123
#授权
GRANT ALL ON *.* TO 'root'@'192.168.10.%' IDENTIFIED BY 'Admin@123';

#查看创建成功
use mysql;
select user,host from user;

8.重启mycat服务,客户机连接mycat

(1)在mycat服务器上,重启mycat服务,查看启动日志,文末出现successfully
 [root@localhost ~]#mycat restart  
 [root@localhost ~]#tail -f /apps/mycat/logs/wrapper.log
 INFO   | jvm 1    | 2021/12/09 21:15:40 | 
INFO   | jvm 1    | 2021/12/09 21:15:40 | MyCAT Server startup successfully. see logs in logs/mycat.log
STATUS | wrapper  | 2021/12/09 21:16:38 | TERM trapped.  Shutting down.
STATUS | wrapper  | 2021/12/09 21:16:39 | <-- Wrapper Stopped
STATUS | wrapper  | 2021/12/09 21:16:40 | --> Wrapper Started as Daemon
STATUS | wrapper  | 2021/12/09 21:16:40 | Launching a JVM...
INFO   | jvm 1    | 2021/12/09 21:16:40 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO   | jvm 1    | 2021/12/09 21:16:40 |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
INFO   | jvm 1    | 2021/12/09 21:16:40 | 
INFO   | jvm 1    | 2021/12/09 21:16:41 | MyCAT Server startup successfully. see logs in logs/mycat.log

(2)查看3306端口,可以监听到主从服务器(192.168.10.40、192.168.10.20)
 [root@localhost ~]# ss -antp|grep 3306
 LISTEN     0      128         :::3306                    :::*                   users:(("java",pid=74936,fd=185))
TIME-WAIT  0      0        ::ffff:192.168.10.40:37344                ::ffff:192.168.10.20:3306               
ESTAB      0      0        ::ffff:192.168.10.40:58160                ::ffff:192.168.10.20:3306                users:(("java",pid=74936,fd=195))

 
(3)在客户机上登录mycat,这时可以不加端口直接进入数据库了
[root@localhost ~]#mysql -uroot -p123456 -h 192.168.10.30
#看是否能查到表   
create table student (id smallint unsigned primary key auto_increment, name varchar(10), age tinyint unsigned,gender enum('M','F') default 'M' );
show databases;
use TESTDB;
show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
+-------------------+

#查看当前的查询来自哪台服务器,可以看到查询功能来自id为2的从服务器
select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+

9.客户端测试读写分离

(1)在主从服务器上都打开通用日志
[root@localhost ~]#mysql -uroot -p123123
#打开通用日志
set global general_log=1;
#查看通用查询日志是否开启
show variables like 'general%';
+------------------+-------------------------------------+
| Variable_name    | Value                               |
+------------------+-------------------------------------+
| general_log      | ON                                  |
| general_log_file | /usr/local/mysql/data/localhost.log |
+------------------+-------------------------------------+

set global general_log=1;
show variables like 'general%';

(2)在主从服务器上实时查看通用日志
[root@localhost ~]#tail -f /usr/local/mysql/data/localhost.log

(3)在客户机上的表中插入数据,并查看主从服务器实时日志,可以看到只有主服务器上有日志变化显示
[root@localhost ~]#mysql -uroot -p123456 -h 192.168.10.30
insert into teachers values(5,'Xiao Ming',46,'F');

(4)在客户机上select查表,并查看主从服务器实时日志,可以看到只有从服务器上有日志变化显示,从而实现了读写分离
select * from teachers;

三、 MHA实操

机器作用
7-4 192.168.10.10MHA管理节点
7-1 192.168.10.40
7-2 192.168.10.20
7-3 192.168.10.30

准备文件

7-4 需要客户端和服务端,其余只需要客户端

1关闭防火墙selinux

systemctl disable --now firewalld
setenforce 0

2.主节点(7-4)安装 管理和客户端工具

[root@localhost opt]#yum install epel-release.noarch -y
#有依赖性用yum安装  需要先安装  epel源

[root@localhost data]#ls
mha4mysql-manager-0.58-0.el7.centos.noarch.rpm  mha4mysql-node-0.58-0.el7.centos.noarch.rpm

[root@localhost opt]#yum -y install mha4mysql-*.rpm

3.其余所有节点(7-1,7-2,7-3)安装客户端

[root@localhost opt]#yum install epel-release.noarch -y
[root@localhost data]# yum install  mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

4. 所有节点 基于key验证

[root@localhost data]#ssh-keygen 
[root@localhost data]#ssh-copy-id  127.0.0.1
#自己和自己连生成 秘钥

[root@localhost data]#cd

[root@localhost data]#rsync -a .ssh   192.168.10.20:/root/
[root@localhost data]#rsync -a .ssh   192.168.10.20:/root/
[root@localhost data]#rsync -a .ssh   192.168.10.30:/root/
#注意.ssh 后不能加/    -a  保留属性

5 主节点(7-4)建立mha文件夹和配置文件

[root@localhost ~]#mkdir /etc/mastermha
[root@localhost ~]#vim /etc/mastermha/app1.cnf
[server default]
user=mhauser
password=Admin@123
manager_workdir=/data/mastermha/app1/
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
ssh_user=root
repl_user=test
repl_password=Admin@123
ping_interval=1
master_ip_failover_script=/usr/local/bin/master_ip_failover
check_repl_delay=0
master_binlog_dir=/data/mysql/


[server1]
hostname=192.168.10.40
candidate_master=1

[server2]
hostname=192.168.10.20
candidate_master=1

[server3]
hostname=192.168.10.30

6 准备切换脚本

[root@localhost ~]#vim  master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
my $vip = '192.168.10.188/24';
my $gateway = '192.168.10.2';
my $interface = 'ens33';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig $interface:$key $vip;/sbin/arping -I $interface -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig $interface:$key down";
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
# $orig_master_host, $orig_master_ip, $orig_master_port are passed.
# If you manage master ip address at global catalog database,
# invalidate orig_master_ip here.
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
# all arguments are passed.
# If you manage master ip address at global catalog database,
# activate new_master_ip here.
# You can also grant write access (create user, set read_only=0, etc) here.
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
`ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}




[root@localhost ~]#cp master_ip_failover   /usr/local/bin/
# 移动文件到对应的地方 之前的配置文件中规定了地方
[root@localhost ~]#chmod +x  /usr/local/bin/master_ip_failover 
#加上执行权限

7实现主从复制

7.1主服务器操作(7-1)

[root@localhost ~]#vim  /etc/my.cnf
#修改文件
[mysqld]
server_id=100
log-bin=/data/mysql/mysql-bin
skip_name_resolve=1
general_log 
#通用日志






[root@localhost data]#mysql -uroot -pabc123
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


mysql> grant replication slave on *.* to test@'192.168.10.%' identified by 'Admin@123';
#建立复制用户
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> grant all on *.* to mhauser@'192.168.10.%' identified by 'Admin@123';
#建立  mha管理账户
Query OK, 0 rows affected, 1 warning (0.00 sec)

7.2从服务器设置(7-2,7-3)

7.2.1 服务器7-2配置

[root@localhost ~]#vim  /etc/my.cnf
#修改文件
server_id=101
log-bin=/data/mysql/mysql-bin
read_only
relay_log_purge=0
skip_name_resolve=1 
general_log 



[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld


[root@localhost data]#mysql -uroot -pabc123
CHANGE MASTER TO
  MASTER_HOST='192.168.10.40',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=154;
  注意最后分号
  
mysql> start slave;
mysql> show slave status\G;
7.2.2服务器7-3配置
[root@localhost ~]#vim  /etc/my.cnf
#修改文件
server_id=102
log-bin=/data/mysql/mysql-bin
read_only
relay_log_purge=0
skip_name_resolve=1 
general_log 



[root@localhost ~]#mkdir /data/mysql/   -p
#建立文件夹
[root@localhost ~]#chown mysql.mysql /data/ -R
#注意修改权限
[root@localhost ~]#systemctl restart mysqld


[root@localhost data]#mysql -uroot -pabc123
CHANGE MASTER TO
  MASTER_HOST='192.168.10.40f',
  MASTER_USER='test',
  MASTER_PASSWORD='Admin@123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=154;
  注意最后分号
  
mysql> start slave;
mysql> show slave status\G;

8.设置虚拟地址

在 mysql 主节点上配置 虚拟地址 也就是7-1

[root@localhost ~]#ifconfig ens33:1 192.168.10.188/24

9在运行前需要先检测环境是否符合

在管理节点 7-3 上执行

9.1 检测 ssh 免密登录是否成功

[root@localhost ~]#masterha_check_ssh --conf=/etc/mastermha/app1.cnf
Thu Jul  4 23:55:53 2024 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Thu Jul  4 23:55:53 2024 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Thu Jul  4 23:55:53 2024 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Thu Jul  4 23:55:53 2024 - [info] Starting SSH connection tests..
Thu Jul  4 23:55:55 2024 - [debug] 
Thu Jul  4 23:55:53 2024 - [debug]  Connecting via SSH from root@192.168.10.40(192.168.10.40:22) to root@192.168.10.20(192.168.10.20:22)..
Thu Jul  4 23:55:54 2024 - [debug]   ok.
Thu Jul  4 23:55:54 2024 - [debug]  Connecting via SSH from root@192.168.10.40(192.168.10.40:22) to root@192.168.10.30(192.168.10.30:22)..
Thu Jul  4 23:55:55 2024 - [debug]   ok.
Thu Jul  4 23:55:56 2024 - [debug] 
Thu Jul  4 23:55:54 2024 - [debug]  Connecting via SSH from root@192.168.10.30(192.168.10.30:22) to root@192.168.10.40(192.168.10.40:22)..
Thu Jul  4 23:55:55 2024 - [debug]   ok.
Thu Jul  4 23:55:55 2024 - [debug]  Connecting via SSH from root@192.168.10.30(192.168.10.30:22) to root@192.168.10.20(192.168.10.20:22)..
Thu Jul  4 23:55:56 2024 - [debug]   ok.
Thu Jul  4 23:55:56 2024 - [debug] 
Thu Jul  4 23:55:54 2024 - [debug]  Connecting via SSH from root@192.168.10.20(192.168.10.20:22) to root@192.168.10.40(192.168.10.40:22)..
Thu Jul  4 23:55:55 2024 - [debug]   ok.
Thu Jul  4 23:55:55 2024 - [debug]  Connecting via SSH from root@192.168.10.20(192.168.10.20:22) to root@192.168.10.30(192.168.10.30:22)..
Thu Jul  4 23:55:55 2024 - [debug]   ok.
Thu Jul  4 23:55:56 2024 - [info] All SSH connection tests passed successfully.

9.2 检测主从复制 是否可以

[root@localhost /]#masterha_check_repl --conf=/etc/mastermha/app1.cnf
#  --conf=/etc/mastermha/app1.cnf  指明配置文件
.........................................................
.........................................................
.........................................................
Checking the Status of the script.. OK 
Fri Jul  5 00:03:44 2024 - [info]  OK.
Fri Jul  5 00:03:44 2024 - [warning] shutdown_script is not defined.
Fri Jul  5 00:03:44 2024 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.


9.3 查看状态未开启

[root@localhost /]#masterha_check_status --conf=/etc/mastermha/app1.cnf
app1 is stopped(2:NOT_RUNNING).

10 开启mha

#开启MHA,默认是前台运行,生产环境一般为后台执行
nohup masterha_manager --conf=/etc/mastermha/app1.cnf &> /dev/null 
#非后台
masterha_manager --conf=/etc/mastermha/app1.cnf 

#查看状态
masterha_check_status --conf=/etc/mastermha/app1.cnf  

11测试

11.1 mha 如何发现主节点宕机

通过发送 SELECT 1 As Value 指令 把1 设置成 value 给主, 主无法执行就认为他死了

[root@localhost mysql]#tail -f   /var/lib/mysql/localhost.log 
2024-07-04T16:11:14.137683Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:15.137991Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:16.137965Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:17.138401Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:18.138703Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:19.138877Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:20.139094Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:21.139400Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:22.140600Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:23.140507Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:24.141510Z	    9 Query	SELECT 1 As Value
2024-07-04T16:11:25.141256Z	    9 Query	SELECT 1 As Value

11.2 查看 mha 服务的日志

[root@localhost ~]#tail  -f  /data/mastermha/app1/manager.log 

IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.10.188/24;/sbin/arping -I ens33 -c 3 -s 192.168.10.188/24 192.168.10.2 >/dev/null 2>&1===

Checking the Status of the script.. OK 
Fri Jul  5 00:08:27 2024 - [info]  OK.
Fri Jul  5 00:08:27 2024 - [warning] shutdown_script is not defined.
Fri Jul  5 00:08:27 2024 - [info] Set master ping interval 1 seconds.
Fri Jul  5 00:08:27 2024 - [warning] secondary_check_script is not defined. It is highly recommended setting it to check master reachability from two or more routes.
Fri Jul  5 00:08:27 2024 - [info] Starting ping health check on 192.168.10.40(192.168.10.40:3306)..
## Fri Jul  5 00:08:27 2024 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..

11.3 模拟 mysql 主节点故障

关闭主mysql服务器

systemctl stop mysqld
在从节点 102 上查看slave 信息  可以看到指向  新的主

```
mysql> show slave status\G;
```

查看日志

[root@localhost ~]#tail  -f  /data/mastermha/app1/manager.log 

----- Failover Report -----

app1: MySQL Master failover 192.168.10.40(192.168.10.40:3306) to 192.168.10.20(192.168.10.20:3306) succeeded

Master 192.168.10.40(192.168.10.40:3306) is down!

Check MHA Manager logs at localhost.localdomain:/data/mastermha/app1/manager.log for details.

Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.10.40(192.168.10.40:3306)
The latest slave 192.168.10.20(192.168.10.20:3306) has all relay logs for recovery.
Selected 192.168.10.20(192.168.10.20:3306) as a new master.
192.168.10.20(192.168.10.20:3306): OK: Applying all logs succeeded.
192.168.10.20(192.168.10.20:3306): OK: Activated master IP address.
192.168.10.30(192.168.10.30:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
192.168.10.30(192.168.10.30:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.10.20(192.168.10.20:3306)
192.168.10.20(192.168.10.20:3306): Resetting slave info succeeded.
#   Master failover to 192.168.10.20(192.168.10.20:3306) completed successfully.

并且虚拟ip也在101 服务器上出现

[root@node2 ~]#ifconfig 

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

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

相关文章

【kubectl详解】最全的kubectl命令用法

文章目录 简介一.命令帮助翻译1.1.基本命令&#xff08;初学者&#xff09;&#xff1a;1.2.基本命令&#xff08;中级&#xff09;&#xff1a;1.3.部署命令&#xff1a;1.4.群集管理命令&#xff1a;1.5.疑难解答和调试命令&#xff1a;1.6.高级命令&#xff1a;1.7.设置命令…

推荐的一键下载1688高保真原图信息

图片在电商中扮演着至关重要的角色。高质量的商品图片能够直观展示产品特性&#xff0c;吸引消费者注意力&#xff0c;提升购买欲望。良好的视觉呈现还能增强品牌形象&#xff0c;提高转化率。此外&#xff0c;图片是跨语言的沟通方式&#xff0c;能够克服语言障碍&#xff0c;…

空调计费系统是什么,你知道吗

空调计费系统是一种通过对使用空调的时间和能源消耗进行监测和计量来进行费用计算的系统。它广泛应用于各种场所&#xff0c;如家庭、办公室、商场等&#xff0c;为用户提供了方便、准确的能源使用管理和费用控制。 可实现功能 智能计费&#xff1a;中央空调分户计费系统通过智…

【网工】关于链路聚合、静态路由、单臂路由的一个小实验

最近刚考完期末放暑假&#xff0c;那几天没看csdn结果有个朋友发了这样一个实验&#xff1a; 虽然晚了点 也不知道这位朋友还需不需要 但还是弄了出来 分享给大家 一起学习 下面是一些关键配置代码参考

Android AlertDialog对话框

目录 AlertDialog对话框普通对话框单选框多选框自定义框 AlertDialog对话框 部分节选自博主编《Android应用开发项目式教程》&#xff08;机械工业出版社&#xff09;2024.6 在Android中&#xff0c;AlertDialog弹出对话框用于显示一些重要信息或者需要用户交互的内容。 弹出…

基于DMAIC降低气缸体水套芯磕碰伤率

在制造业的激烈竞争中&#xff0c;产品质量的提升一直是企业追求的目标。气缸体作为汽车发动机的核心部件&#xff0c;其生产过程中的质量控制尤为重要。今天&#xff0c;深圳天行健企业管理咨询公司就来分享一下如何运用DMAIC&#xff08;定义、测量、分析、改进、控制&#x…

IDC:奇安信、深信服、安恒、绿盟、斗象组成了中国NDR市场的主要玩家

2024 年 6 月 20 日&#xff0c;IDC 正式发布了针对中国网络威胁检测与响应产品的市场份额研究报告——《中国网络威胁检测与响应市场份额&#xff0c;2023&#xff1a;NDR正在向更多技术栈延伸》&#xff08;2024年6月&#xff09;。报告针对2023年中国网络威胁检测与响应市场…

STMCUBEMX_IIC_LL库_AT24C64分页读取和写入

STMCUBEMX_IIC_LL库_AT24C64分页读取和写入 前言&#xff1a; 一个项目中构建的软件系统需要存储非常多的用户参数&#xff0c;大约有几千字节&#xff0c;所以牵扯到自己设计跨页写入算法&#xff0c;注意读出也是需要设计跨页读出算法的&#xff08;手册没强调&#xff0c;但…

App Store迎来了重磅更新,ASO冲榜优化或将成为不可或缺的一部分

近日App Store搜索页面迎来了重磅更新&#xff0c;苹果应用商店中搜索页面原有的热搜关键词消失了取而代之的是直接将排行榜放在了搜索顶部&#xff0c;分别是APP排行和游戏排行两部分。如下图&#xff1a; 很多人应该都是参考排行榜来下载APP的&#xff0c;这次更新之后用户在…

创维汽车开展年中总结会:创新创造·勇开拓 智慧经营·攀高峰

2024年7月3日&#xff0c;回顾上半年的工作成果&#xff0c;总结经验教训&#xff0c;明确下半年的发展方向和重点任务&#xff0c;创维汽车于山西省晋中市榆次区山西联合创维体验中心开展年中总结会。 创维集团、创维汽车创始人黄宏生&#xff1b;开沃集团联合创始人、首席执…

160行代码实现代码雨效果

效果 序言 很喜欢黑客帝国里面那种代码雨的效果&#xff0c;为了锻炼自己的特效编写能力就尝试了一下&#xff0c;花了一下午写出来了。有需要的小伙伴拿去参考. 代码 package com.zgh.myapplication;import android.content.Context; import android.graphics.Canvas; impo…

PLM系统:PLM系统如何重塑产品生命周期管理

PLM系统&#xff1a;重塑产品生命周期管理的未来 在当今快速变化的商业环境中&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统正逐渐成为企业提升竞争力、加速创新并优化运营流程的关键工具。随着技术的不断进步和市场需求的日益复杂化&#xff0c;传统的手动或…

视创云展线上虚拟展厅的优势与特点

一、线上虚拟展厅的无限魅力 1、沉浸式体验&#xff0c;跨越时空界限 视创云展线上虚拟展厅借助前沿的虚拟现实技术&#xff0c;为参观者打造了一场跨越物理界限的奇妙之旅。无论身处世界的哪个角落&#xff0c;只需轻点鼠标&#xff0c;即可瞬间“穿越”至展览现场&#xff…

“免费”的可视化大屏案例分享-智慧园区综合管理平台

一.智慧园区是什么&#xff1f; 智慧园区是一种融合了新一代信息与通信技术的先进园区发展理念。它通过迅捷信息采集、高速信息传输、高度集中计算、智能事务处理和无所不在的服务提供能力&#xff0c;实现了园区内及时、互动、整合的信息感知、传递和处理。这样的园区旨在提高…

Python爬虫康复训练——笔趣阁《神魂至尊》

还是话不多说&#xff0c;很久没写爬虫了&#xff0c;来个bs4康复训练爬虫&#xff0c;正好我最近在看《神魂至尊》&#xff0c;爬个txt文件下来看看 直接上代码 """ 神魂至尊网址-https://www.bqgui.cc/book/1519/ """ import requests from b…

Contact Form 7表单获取提交用户IP及URL等信息

有时候&#xff0c;您可能需要了解Contact Form 7表单提交后的更多的信息&#xff0c;而不仅仅是通过联系人表单字段获取用户的联系信息。例如&#xff0c;需要知道用户是哪个国家&#xff08;通过获取IP&#xff09;&#xff0c;了解用户使用的设备&#xff08;手机还是电脑&a…

什么是空气电容器?

空气电容器是使用空气作为电介质的电容器。简单的空气电容器由两个导电板组成&#xff0c;中间有一个气隙。空气电容器可以制成可变或固定电容形式。固定电容空气电容器很少使用&#xff0c;因为还有许多其他具有优异特性的类型。可变空气电容器由于其结构简单而更常用。它们通…

利用联合概率分布筛选2个维度、三个维度数据

目录 1. 整体分析步骤1:联合分布可视化步骤2:定义筛选条件步骤3:应用筛选条件实例演示第一步:联合分布可视化第二步:定义筛选条件第三步:应用筛选条件数据检查与清洗步骤数据清洗步骤下一步2. 定义筛选条件方法一:基于分位数的筛选方法二:基于高密度区域的筛选进一步分…

Leetcode.342 4的幂

给定一个整数&#xff0c;写一个函数来判断它是否是 4 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 4 的幂次方需满足&#xff1a;存在整数 x 使得 n 4x 示例 1&#xff1a; 输入&#xff1a;n 16 输出&#xff1a;true示…