MySQL主从复制与读写分离

一、部署原由、

原因:

  • 保证主库和从库数据一直,防止单点故障,数据丢失
  • 在企业应用中,成熟的业务通常数据量都比较大
  • 单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
  • 配置多台主从数据库服务器以实现读写分离

二、MySQL主从复制原理

2.1 MySQL的复制类型

  • 基于语句的复制
  • 基于行的复制
  • 混合类型的复制

2.2 MySQL主从复制的工作过程

在这里插入图片描述
Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。

2.3复制的基本过程如下:

  1. Master将用户对数据库更新的操作以二进制格式保存到Binary Log日志文件中

  2. Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
    IO进程:从数据库复制主数据库上二进制日志的进程

  3. Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;

  4. Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”

  5. Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行.
    Sql进程:将二进制日志内容翻译成SQL语句写进从数据库

三、MySQL读写分离原理

  1. 只在主服务器上写,只在从服务器上读

  2. 主数据库处理事务性查询,从数据库处理SELECT查询

  3. 数据库复制用于将事务性查询的变更同步到集群中的从数据库

  4. 读写分离方案

    基于程序代码内部实现
    基于中间代理层实现
        -1、MySQL-Proxy
        -2、Amoeba
    

3.1 MySQL读写分离的工作过程

在这里插入图片描述

四、部署详情

4.1 部署原理

主从数据库之间先时间同步,后主从复制,amoeba配置读写分离,授权。最后客户机登录验证

4.2 部署准备

MySQL主数据库20.0.0.11
MySQL从数据库120.0.0.12
MySQL从数据库220.0.0.13
Amoeba20.0.0.14
客户端20.0.0.15

改名:

[root@server1 ~]# hostnamectl set-hostname master
[root@server2 ~]# hostnamectl set-hostname slave1
[root@server3 ~]# hostnamectl set-hostname slave2
[root@server4 ~]# hostnamectl set-hostname amoeba
[root@server5 ~]# hostnamectl set-hostname client

所有设备关闭防火墙:

[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0

4.3 部署流程

4.31 主从数据库时间同步

主数据库上
1.设置时间同步

[root@master ~]# vi /etc/resolv.conf          #编辑配置文件
添加
nameserver 8.8.8.8
[root@master ~]# yum -y install ntpdate ntp   #安装ntp软件
[root@master ~]# ntpdate ntp.aliyun.com       #时间同步
[root@master ~]# date                         #查看当前日期
[root@master ~]# vi /etc/ntp.conf             #编辑配置文件

添加修改
 8: restrict default nomodify   #定义默认访问规则,nomodify禁止远程主机修改本地服务器配置
 
17: restrict 20.0.0.0 mask 255.255.255.0 nomodify notrap
#从20.0.0.1-20.0.0.254的主机都可以使用我们的ntp服务来时间同步

21: fudge 127.127.1.0 stratum 10
#设置本机的时间层级为10级,0级表示时间层级为0级,是向其他服务器提供时间同步源的意思,不要设置为022: server 127.127.1.0   #设置本机为时间同步源

[root@master ~]# systemctl restart ntpd   重启服务
[root@master ~]# netstat -anptu | grep ntpd  查看端口状态

在这里插入图片描述
在这里插入图片描述
2.部署任务计划

[root@master ~]# crontab -e
*/30 * * * * /usr/sbin/ntpdate ntp.aliyun.com
#每隔30分钟进行一次同步对象为阿里云时钟网站的时间同步
[root@master ~]# date  #查看当前日期

在这里插入图片描述
在这里插入图片描述
从数据库1,2上

[root@slave1 ~]# yum -y install ntpdate   #安装ntp
[root@slave1 ~]# ntpdate 20.0.0.11       #设置同步源
[root@slave1 ~]# date        #查看当前日期
[root@slave1 ~]# crontab -e  #部署任务计划
*/3 * * * * /usr/sbin/ntpdate 20.0.0.11
#每隔3分钟进行一次同步对象为20.0.0.11(主数据库)的时间同步
[root@slave1 ~]# date        查看当前日期

在这里插入图片描述
在这里插入图片描述
以上主从时间同步设置完成

4.32 配置主从复制

在主数据库上

[root@master ~]# vi /etc/my.cnf   #开启二进制日志

添加:
log_bin=master_bin    #同步的二进制日志开启前缀
log_slave_updates=true   #允许日志同步给从数据库

[root@master ~]# systemctl restart mysqld  #重启服务

[root@master ~]# mysql -uroot -p123123   #登录数据库

mysql> grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123123';   #设置授权

--------------------解析---------------------------------
grant replication slave  #授权复制权限从数据库 
on *.* :#可复制所有库,所有表,
'myslave'@'20.0.0.%' :#授权用户,用户登录范围,网段,
identified by : #识别密码
-----------------------------------------------------------

mysql> flush privileges;    #刷新权限

mysql> show master status;  #查看主数据库状态信息

在这里插入图片描述
在这里插入图片描述

数据库1上

[root@slave1 ~]# vi /etc/my.cnf

添加修改:
server-id = 2  #服务id为2
relay_log=relay-log-bin   #二进制日志的中继日志前缀
relay_log_index=slave-relay-bin.index  #中继日志索引

[root@slave1 ~]# systemctl restart mysqld

[root@slave1 ~]# mysql -uroot -p123123  #登录数据库

mysql> change master to master_host='20.0.0.11',master_user='myslave',master_password='123123',master_log_file='master_bin.000001',master_log_pos=599;

----------------------------解析--------------------------
master_host='20.0.0.11':#主数据库ip地址
master_user='myslave':#主数据库授权用户名
master_password='123123':#授权密码
master_log_file='master_bin.000001':#主从同步日志文件
master_log_pos=599:日志开始路径,主从复制位置
-------------------------------------------------------

mysql> start slave;           开启从状态

mysql> show slave status\G    查看从数据库状态信息

补充:
解析线程错误:
1.I/0线程显示为NO:主库与从库网络不通、主库未授权给从库
若从库查看连接主库I/0线程状态为conneting,-直是这个状态,考虑双方的防火墙是否开启。
2.SQL线程显示为NO:从库日志和位置点与主不同步

在这里插入图片描述

在这里插入图片描述
数据库2上同理配置

[root@slave2 ~]# vi /etc/my.cnf

添加修改:
server-id = 3             #服务id为3
relay_log=relay-log-bin   #二进制日志的中继日志前缀
relay_log_index=slave-relay-bin.index  #中继日志索引

[root@slave2 ~]# systemctl restart mysqld

[root@slave2 ~]# mysql -uroot -p123123

mysql> change master to master_host='20.0.0.11',master_user='myslave',master_password='123123',master_log_file='master_bin.000001',master_log_pos=599;

mysql> start slave;

mysql> show slave status\G

在这里插入图片描述
在这里插入图片描述

4.33 进行主从测试

主数据库上

mysql> show databases;  #查看数据库信息
mysql> create database wang;  #创建新的数据库wang
mysql> show databases;  #查看数据库信息

在这里插入图片描述
在从数据库上进行查看是否新生成wang库

mysql> show databases; #查看库信息

在这里插入图片描述
因为ameoba用户授权给用户时默认的数据库为test
所以在主数据库时创建数据库test

mysql> create database test;
mysql> show databases;

在这里插入图片描述

4.34 设置读写分离

前端数据库ameoba上
时间同步

[root@amoeba ~]# yum -y install ntpdate  #安装ntp软件
[root@amoeba ~]# ntpdate 20.0.0.11       #设置同步源
[root@amoeba ~]# crontab -e              #设置任务计划
*/30  *  *  *  *  /usr/sbin/ntpdate 20.0.0.11

添加jdk安装包
[root@amoeba ~]# ls -lh
[root@amoeba ~]# tar zxvf jdk-8u91-linux-x64.tar.gz    #解压缩

root@amoeba ~]# cp -rv jdk1.8.0_91/ /usr/local/java   
-rv:#递归,显示过程
[root@amoeba ~]# vi /etc/profile #设置环境变量

结尾添加:
export JAVA_HOME=/usr/local/java
export JRE_HOME=/usr/local/java/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export CLASSPATH=./:$JAVA_HOME/lib:$JRE_HOME/lib

[root@amoeba ~]# source /etc/profile  #设置生效
[root@amoeba ~]# echo $CLASSPATH    #输出类路径信息
[root@amoeba ~]# java -version      #查看版本

在这里插入图片描述
在这里插入图片描述
安装amoeba管理软件
1.添加 amoeba-mysql-3.0.5-RC-distribution.zip

[root@amoeba ~]# ls -lh
[root@amoeba ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip #解压缩
[root@amoeba ~]# mv amoeba-mysql-3.0.5-RC/ /usr/local/amoeba  #剪贴
[root@amoeba ~]# chmod -R 755 /usr/local/amoeba/       #授权
[root@amoeba ~]# vi /usr/local/amoeba/jvm.properties   #编辑配置文件
在32行下添加,并注释32行数据
JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k"  #缓存空间大小设置

在这里插入图片描述
2.创建启动脚本

[root@amoeba ~]# vi /etc/init.d/amoeba
#!/bin/bash
#chkconfig: 35 20 90
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
NAME=Amoeba
AMOEBA_BIN=/usr/local/amoeba/bin/launcher
SHUTDOWN_BIN=/usr/local/amoeba/bin/shutdown
PIDFILE=/usr/local/amoeba/Amoeba-MySQL.pid
SCRIPTNAME=/etc/init.d/amoeba
case "$1" in
start)
echo -n "Starting $NAME..."
$AMOEBA_BIN
echo "done"
;;
stop)
echo -n "Stopping $NAME..."
$SHUTDOWN_BIN
echo "done"
;;
restart)
$SHUTDOWN_BIN
sleep 1
$AMOEBA_BIN
;;
*)
echo "Usage:$SCRIPTNAME {start|stop|restart}"
exit 1
;;
esac

[root@amoeba ~]# chmod +x /etc/init.d/amoeba  #添加权限
[root@amoeba ~]# chkconfig --add amoeba  #加入系统管理
[root@amoeba ~]# service amoeba start  #重启服务
[root@amoeba ~]# netstat -anpt | grep 8066  #查看端口状态
tcp6       0      0 :::8066                 :::*                    LISTEN      60877/java 

在这里插入图片描述
在这里插入图片描述

4.341 在主从数据库上进行授权配置

主从数据库都设置

mysql> grant all privileges on *.* to 'test'@'20.0.0.%' identified by '123.com';
mysql> flush privileges;
4.342 在前端上授权客户端登录时用户名和密码

编辑配置文件

[root@amoeba ~]# cd /usr/local/amoeba/  
[root@amoeba amoeba]# vi conf/amoeba.xml   

设置客户端连接amoeba前端服务器时使用的用户名和密码
     <property name="user">amoeba</property>  #28行,修改用户名
      <property name="password">123123</property   #30行,修改密码

在这里插入图片描述

4.343 设置读与写数据库的池
<property name="defaultPool">master</property>  #83行修改默认池
删除注释
 <property name="writePool">master</property> #主数据库负责写
 <property name="readPool">slaves</property>  #从数据库负责读

在这里插入图片描述
编辑配置文件

[root@amoeba amoeba]# vi conf/dbServers.xml 

定义amoeba登录上数据库的授权用户名与密码
      <!-- mysql user -->
      <property name="user">test</property>    #修改
        
        <property name="password">123.com</property>   #修改

设置主服务,地址

        <dbServer name="master"  parent="abstractServer">
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">20.0.0.11</property>
                </factoryConfig>
        </dbServer>
         
设置从服务器1,地址

        <dbServer name="slave1"  parent="abstractServer">
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">20.0.0.12</property>
                </factoryConfig>
        </dbServer>
        
复制从服务器1,地址配置数据
设置从服务器2,地址
        <dbServer name="slave2"  parent="abstractServer">
            <factoryConfig>
                       <!-- mysql ip -->
                       <property name="ipAddress">20.0.0.13</property>
                </factoryConfig>
        </dbServer>

设置定义池
        <dbServer name="slaves" virtual="true">
                <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
                        <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
                        <property name="loadbalance">1</property>

                        <!-- Separated by commas,such as: server1,server2,server1 -->
                        <property name="poolNames>slave1,slave2</property>
                </poolConfig>
        </dbServer>

 
[root@amoeba amoeba]# cd
[root@amoeba ~]# /usr/local/amoeba/bin/shutdown   #关闭服务一定使用自带脚本关闭及启动服务
kill -15 16477
[root@amoeba ~]# /usr/local/amoeba/bin/launcher  #启动服务
[root@amoeba ~]# netstat -anpt | grep 8066  查看8066端口状态
tcp6       0      0 :::8066                 :::*                    LISTEN      60877/java    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完成以上匹配

4.344 开始设置客户机
[root@client ~]# yum -y install mariadb*  #安装软件
[root@client ~]# systemctl start mariadb.service   #启动服务
[root@client ~]# mysql  #登录数据库
MariaDB [(none)]> exit  #退出
[root@client ~]# mysql -uamoeba -p123123 -h 20.0.0.14 -P8066  #登录前端数据库
用户名amoeba,密码123123,ip地址20.0.0.14,端口号8066

在这里插入图片描述

4.4 测试部署效果读写分离

4.41 测试读写分离

在master主数据库上创建的数据库或者表,两个从数据库会同步----通过amoeba操作的

在客户端上

[root@client ~]# mysql -uamoeba -p123123 -h 20.0.0.14 -P8066
MySQL [(none)]> use test;  #使用数据库
MySQL [test]> create table tree(id int(10),name varchar(128),guanli varchar(128)); #创建表tree
MySQL [test]> insert into tree values(1,'zhangsan','this is master'); #插入数据记录

主数据库上查看

[root@master ~]# mysql -uroot -p123123
mysql> use test; #使用数据库
mysql> select * from tree;  #查询所有内容字段

从数据库1,2查看

[root@slave1 ~]#  mysql -uroot -p123123   #从1
[root@slave2 ~]#  mysql -uroot -p123123    #从2
mysql> select * from test.tree;

在这里插入图片描述
在这里插入图片描述

4.42 关闭主从同步复制,查看情况

主从复制关闭,再次添加数据,此时因为主数据库负责写操作,从数据库负责读操作,所以此时应只有主数据库上可以查看到新增的数据,从数据库上无变化

客户端添加数据记录
MySQL [test]> insert into tree values(2,'dao','that was master2');

数据库上
mysql> stop slave; #关闭主从同步

客户端再次添加数据记录
MySQL [test]> insert into tree values(3,'small','this is master3');

主数据库上查看     #能查看到最新添加数据
mysql> select * from tree;

从数据库上查看   #关闭主从同步后数据查看不到
mysql> select * from test.tree;
4.43 关闭主从同步复制,查看情况

在从数据库上
写入不同的数据,查看客户端读取时情况

在从数据库1上

mysql> delete from test.tree;   #删除test库中的表tree
mysql> select * from test.tree;  #查看test库中的表tree中的所有内容
mysql> insert into test.tree values(10,'wang','this is slave1');#插入数据记录
mysql> select * from test.tree; #查看所有内容

在从数据库2上

mysql> delete from test.tree;
mysql> select * from test.tree;
mysql> insert into test.tree values(20,'dao','this is slave2');
mysql> select * from test.tree;

在客户端进行读取查看

MySQL [test]> select * from test.tree;   #slave1关闭主从同步创的数据,客户机依然能查看到
说明客户机提供Amoeba写入数据,写在主数据库上,从Amoeba中读取数据库信息,是从从数据库中读取的

此时在主数据库上查看日志状态信息

mysql> show master status;  #查看主数据库的状态信息

在这里插入图片描述

4.44 恢复从数据库1与主数据库的主从同步

从数据库1上

mysql> change master to master_host='20.0.0.10',master_user='myslave',master_password='abc123',master_log_file='master_bin.000001',master_log_pos=2421;
mysql> start slave;   #开启从状态
mysql> show slave status\G  #查看从数据库状态信息

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值