mysql的主从复制、读写分离--负载均衡

1、什么是mysql的主从复制

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。

MySQL 默认采用异步复制方式,从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。

2、主从复制优点

数据热备:主库故障后,可切换到从数据库继续工作,一定程度上实现高可用。

读写分离:让主库负责写,从库负责读,使数据层能支持更大的并发;在报表统计等业务形态中尤其重要。比如后台生成报表的多表查询sql语句非常的慢,导致锁表,影响前台实时服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台实时业务的响应速度。

架构扩展:业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。

3、主从复制原理

一句话概括就是把主服务器上的 binlog日志复制到从服务器上再执行一遍,具体过程:

(1)master必须启用二进制日志,二进制binlog日志中记录了每一次数据变化事件

(2)slave会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开启一个I/O Thread请求master二进制日志中的事件

(3)master为slave的I/O Thread启动一个dump线程(二进制日志转储线程),检查自己二进制日志中的事件,跟对方请求的位置对比后,向其发送二进制事件

(4)slave接收到master发送过来的数据把它放置到中继日志(Relay log,也是二进制)文件中;并记录该次请求到master的具体哪一个二进制日志文件内部的哪一个位置

(5)slave将启动一个sql Thread从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致;并记录relay log中该次执行的位置信息

(6)最后I/O Thread和SQL Thread将进入睡眠状态,等待下一次被唤醒


mysql主从复制: 

server1中:

停掉nginx、开启mysqld、并且吧mysqld给server2传输过去

nginx -s stop   #停掉nginx
cd 
/etc/init.d/mysqld  start
scp -rp /usr/local/mysql/ server2:/usr/local/
scp /etc/init.d/mysqld server2:/etc/init.d/
scp /etc/my.cnf server2:/etc/
vim /etc/my.cnf
  添加:log-bin=mysql-bin
       server-id=1
/etc/init.d/mysqld restart

 server2中:停掉httpd、配置mysqld

systemctl stop httpd
groupadd -g 1001 mysql
useradd -u 1001 -g mysql -M -d /data/mysql -s /sbin/nologin mysql
id mysql
vim ~/.bash_profile
  第10行:PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
source ~/.bash_profile
which mysql
mkdir -p /data/mysql
chown mysql.mysql /data/mysql/
ps ax    #一定要查看进程,kill掉之前的进程之后在初始化
mysqld --initialize --user=mysql   #重新初始化的时候要把/data/mysql/目录下的东西清空
/etc/init.d/mysqld  start   #还要启动mysqld
cd /data/mysql
cat mysqld.log | grep password
chmod 755 mysqld
mysql_secure_installation
mysql -pwestos
vim /etc/my.cnf
  添加:collation-server=utf8mb4_general_ci
       server-id=2
/etc/init.d/mysqld restart

 

 server1:

mysql -pwestos
-->CREATE USER 'repl'@'%' IDENTIFIED BY 'westos';
-->GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-->SHOW MASTER STATUS;

 server2:

mysql -pwestos
--> stop slave;
-->CHANGE MASTER TO MASTER_HOST='172.25.70.1', MASTER_USER='repl', MASTER_PASSWORD='westos', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=987;
--> start slave;
-->show slave status\G;

 

 说明:以上步骤没有做锁表和库的同步步骤,因为再做此实验时主机和备机的库时一样的;
假如主机中比备机多了一个westos库,要将westos库同步过去的话:

server1主机中:

mysqldump -pwestos westos > dump.sql
vim dump.sql   #查看刚导入的库
scp dump.sql server2:  #把刚导入的库的文件给备机server2传输过去【注意绝对路径】

server2备机中:

cd ~
vim dump.sql
mysqladmin -pwestos create westos
mysql -pwestos westos < dump.sql
mysql -pwestos
-->show databases;#可以看到从主机中同步过来的westos数据库
-->use westos
-->select * from user_tb;

server1主机中:

mysql -pwestos
-->use westos
-->insert into user_tb values ('user1','123');
-->insert into user_tb values ('user2','123');

 在server1和2主从关系搭建好之后:可以在server1主机中创建一个库,在server2查看同步消息

 


mysql主从复制的优化:
server1主机中: 

vim /etc/my.cnf
  添加:gtid_mode=ON
       enforce-gtid-consistency=ON
/etc/init.d/mysqld restart

 server2备机中:

vim /etc/my.cnf
  添加:gtid_mode=ON
       enforce-gtid-consistency=ON
/etc/init.d/mysqld restart
mysql -pwestos
-->stop slave;
-->change master to master_host='172.25.70.1', master_user='repl', master_password='westos', master_auto_position=1;   #使用gtid
-->start slave;
-->show slave status\G;
   -->Slave_IO_Running: Yes
      Slave_SQL_Running: Yes

 server1主机中:

mysql -pwestos
--> use westos
--> insert into user_tb values ('user3','123');  #给表插入信息

 server2备机中:

mysql -pwestos
> show databases;   #查看所有的库
> use westos  进入westos库中
> select * from user_tb;   #看user_tb表中信息。可以看到主机中的表信息已经同步了


 mysql半同步复制【io线程的优化】
server1主机中:

mysql -pwestos
--> install plugin rpl_semi_sync_master soname 'semisync_master.so';
--> select plugin_name, plugin_status
 -> from information_schema.plugins
 -> where plugin_name like '%semi%';
--> set global rpl_semi_sync_master_enabled = 1;
vim /etc/my.cnf
  添加:rpl_semi_sync_master_enabled = 1
/etc/init.d/mysqld restart
mysql -pwestos
--> show variables like 'rpl%';

 

 server2备机中:

mysql -pwestos
--> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
--> set global rpl_semi_sync_slave_enabled = 1;
vim /etc/my.cnf
  添加:rpl_semi_sync_slave_enabled = 1
/etc/init.d/mysqld restart  #执行数据库重启命令后,再看'rpl%'的status会直接时ON的状态,但不执行的话需要关闭在开启之后'rpl%'的status才会是ON状态
【stop slave io_thread #关闭slave的io。start slave io_thread #开启slave的io】
mysql -pwestos
--> show variables like 'rpl%';
--> show status like 'rpl%';

 server1主机中:

mysql -pwestos
--> show status like 'rpl%'; #此时是ON的状态
--> use westos;
--> insert into user_tb values ('user4','123');

 server2备机中:

mysql -pwestos
--> select * from westos.user_tb; #可以同步到刚才建立的表里信息
--> stop slave io_thread;

 server1主机中:

mysql -pwestos
--> insert into user_tb values ('user7','123'); #会等待10秒,此时是异步
--> show status like 'rpl%'; 

 server2备机中:

mysql -pwestos
--> start slave io_thread;

server1主机中:

mysql -pwestos
--> insert into user_tb values ('user8','123');
--> show status like 'rpl%';

 server2备机中:

mysql -pwestos
--> select * from westos.user_tb; #可以同步到刚才建立的表里信息


 mysql延迟:
server2备机中:

mysql -pwestos
--> show processlist;
> STOP SLAVE SQL_THREAD;
> change master to master_delay = 30;
> START SLAVE SQL_THREAD;

server1主机中:

mysql -pwestos
--> insert into user_tb values ('user9','123');

server2备机中:

mysql -pwestos
> show slave status\G;
> show slave status\G;  #一致刷这个命令,等到30秒完了可以看到备机中有刚才主机中建立的user5的信息了
> select * from westos.user_tb;

 

 


mysql多主模式

server2(1的备机,3的主机)机中:

vim /etc/my.cnf
  添加:slave_parallel_workers=16
      slave_parallel-type=LOGICAL_CLOCK
      master_info_repository=TABLE
      relay_log_info_repository=TABLE
      relay_log_recovery=ON
/etc/init.d/mysqld restart 
mysql -pwestos
--> show processlist;
cd /usr/local/
ls
scp -rp /usr/local/mysql/ server3:/usr/local/
scp /etc/init.d/mysqld server3:/etc/init.d/
scp /etc/my.cnf server3:/etc/

 

server3(2的备机中):

groupadd -g 1001 mysql
useradd -u 1001 -g mysql -M -d /data/mysql -s /sbin/nologin mysql
id mysql
vim ~/.bash_profile
source ~/.bash_profile
which mysql
mkdir -p /data/mysql
chown mysql.mysql /data/mysql/
mysqld --initialize --user=mysql
cd /data/mysql
cat mysqld.log | grep password
chmod 755 mysqld
mysql_secure_installation
mysql -pwestos
vim /etc/my.cnf
  改为:server-id=3
  注释掉:#rpl_semi_sync_slave_enabled = 1
        #slave_parallel_workers=16
        #slave_parallel-type=LOGICAL_CLOCK
        #master_info_repository=TABLE
        #relay_log_info_repository=TABLE
        #relay_log_recovery=ON
/etc/init.d/mysqld start

注意:以上启动不成功进入/data/mysql/目录执行rm -rf * 之后再次初始化

server1中:

mysqldump -pwestos westos > dump.sql
scp dump.sql server3:

server3(2的备机中):

cd ~
mysqladmin -pwestos create westos
mysql -pwestos westos < dump.sql
mysql -pwestos
--> use westos
--> select * from user_tb;  #同步过来2上的库里的信息了

server2(1的备机,3的主机)机中:

vim /etc/my.cnf
  添加:log-bin=mysql-bin
       log-slave-updates=ON
/etc/init.d/mysqld restart 
mysql -pwestos
--> grant replication slave on *.* to repl@'%' identified by 'westos';
--> flush privileges;
--> select * from westos.user_tb;

server3(2的备机中):

mysql -pwestos

--> change master to master_host='172.25.70.2', master_user='repl', master_password='westos', master_auto_position=1;
--> start slave;
--> show slave status\G;


server1中:

mysql -pwestos
> use westos
> insert into user_tb values ('user10','123');

#过30秒后2和3都会同步到刚才在westos数据库中建立的user_tb表里的信息,因为上一个实验做了30秒的延迟。


组复制:(一组最少三个成员,最多九个成员)
先清除之前的数据库;因为组复制对数据库的校验非常高

server1中:

 注意:引导程序只由一台服务器完成即可,这里server1引导了,所以接下来的server2和server3就不需要这一步了。

 server2:

清除之前的数据,在修改密码时必须一致

 

 server1中查看

 server3同理:  清除之前的数据

  server1中查看:三台机子都是online状态

 server2、server3 。在server2和3中查看刚才server1的消息已经同步过来了

 server2中写入数据(可以直接同步到server3和server1中)

 server1和3中:

  server3中写入数据(可以直接同步到server2和server1中)

  server1和2中:

 server3:停掉mysqld服务

 server1中只有server1和2是online状态

 server2中:可以同步过来刚server1中写的表数据

 server3:开启server3中的mysqld服务

  server1中:三台机子都是online状态

 server3:开启server3之后还能同步到刚才关掉服务时server1写的表数据


 读写分离--负载均衡
server1中:

mysql -pwestos
--> show variables like 'slow%';
--> set global slow_query_log=ON;
--> show variables like 'long%';
--> show variables like 'slow%';
--> select sleep(10);;

 

 sleep 等待了十秒开启虚拟机server4;
在server4中:

lftp 172.25.254.250;
~> cd pub/docs/mysql/
~> get mysql-router-community-8.0.21-1.el7.x86_64.rpm
~> exit
rpm -ivh mysql-router-community-8.0.21-1.el7.x86_64.rpm  #安装rpm包
cd /etc/mysqlrouter/
vim mysqlrouter.conf 
  给最后添加:
  [routing:ro]   #只读
  bind_address = 0.0.0.0
  bind_port = 7001          #端口号
  destinations = 172.25.11.2:3306,172.25.11.3:3306
  routing_strategy = round-robin  #轮循

  [routing:rw]    #读写
  bind_address = 0.0.0.0
  bind_port = 7002
  destinations = 172.25.11.1:3306,172.25.11.2:3306
  routing_strategy = first-available  #从前往后找,先找1在找2
systemctl start mysqlrouter.service   #开启服务
netstat -antlp  #查看刚才配置文件的两个端口是否启动

server1中:

mysql -pwestos
--> grant all on test.* to dmq@'%' identified by 'westos';
--> flush privileges;

真机中:

mysql -h 172.25.11.4 -P 7001 -u dmq -p test #7001是只读
--> show tables;
--> select * from t1;

server2:
yum install -y lsof
lsof -i :3306  #查看mysql的端口号连接哪一台服务器

 server3:
yum install -y lsof
lsof -i :3306


 
说明:用真机执行mysql -h 172.25.11.4 -P 7001 -u dmq -p test。在server2或server3中用lsof -i :3306命令查看,会轮流在2或3上,实现负载均衡 

server1:
yum install -y lsof
lsof -i :3306

 真机中:
mysql -h 172.25.11.4 -P 7002 -u dmq -p test #7002是只读

说明:用真机执行mysql -h 172.25.11.4 -P 7002 -u dmq -p test。在server1或server2中用lsof -i :3306命令查看,会轮流在1或2上,实现负载均衡 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值