MySQL主从复制与读写分离
文章目录
一、主从复制与读写分离原理
1、mysq支持的复制类型
①STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。
②ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
③MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
2、主从复制的工作过程
① Master节点将数据的改变记录成二进制日志(binlog),当Master上的数据发生改变时,则将其改变写入二进制日志中
② slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个1/o线程请求Master的二进制事件
③ 同时Master节点为每个I/o线程启动一个dump线程,用于向其发送二进制事件,并保存至slave节点本地的中继日志(Relaylog)中,Slave节点将启动sgL线程从中继日志中读取二进制日志,在本地重放,即解析成sql语句逐一执行,使得其数据和Master节点的保持一致,最后I/o线程和sQL线程将进入睡眠状态,等待下一次被唤醒。
注:中继日志通常会位于os缓存中,所以中继日志的开销很小
复制过程有一个很重要的限制,即复制在slave上是串行化的,也就是说Master上的并行更新操作不能在slave上并行操作
2、MySQL读写分离原理
1.1 什么是读写分离
读写分离
基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE)
而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数掘库。
在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份。
什么时候要读写分离
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性操作,而从数据库处理select查询。数据库复制被用来把主数据库上事务性操作导致的变更同步到集群中的从数据库。
1.2 常见的 MysQL读写分离
分为以下两种:
① 基于程序代码内部实现
在代码中根据select、insert进行路由分类,这类方法也是目前生产环境应用最广泛的。
优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。
② 基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。MySQL-Proxy、Atlaso、Amoeba
二、搭建主从复制
1、准备环境
Master服务器:192.168.174.122 mysq15.7
slave1 服务器:192.168.174.133 mysq15.7
slave2服务器:192.168.174.144 mysq15.7
Amoeba 服务器:192.168.174.10 jdk1.6、Amoeba
客户端服务器:192.168.174.10 mysql
关闭防火墙和核心防护
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
2、主从服务器时间同步
1、主服务器设置
建议全部同步阿里时间
yum install ntp -y
vim letc/ntp.conf--末尾添加--
server 127.127.80.0
fudge 127.127.80.0 stratum 8
service ntpd start
2、从服务器设置
yum install ntp ntpdate -y
配置文件:vim /etc/ntp.conf
netstat -anptu l grep 123
手动司步:
ntpdate 后面跟ip或者域名
#或者全部同步阿里时间
ntpdate ntp.aliyun.com
3、主从MySQL配置
1、主服务器配置
vim /etc/my.cnf
server-id = 11
log-bin=master-bin #添加,服务器开启二进制日志
binlog_format=MIXED
log-slave-updates=true #添加,允许slave从master复制数据时可以写入到自己的二进制日志
----------------------
systemctl restart mysqld
mysql -u root -p4455
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.174.%’ IDENTIFIED BY'123456'; #给从服务器授权
FLUSH PRIVILEGES;
show master status;
2、从服务器配置
vim /etc/my.cnf
server-id = 22 #修改,注意id与Master的不同,两个slave的id也要不同
relay-log=relay-log-bin #添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index #添加,定义中继日志文件的位置和名称,一般和relay-log在同一目录
relay_log_recovery=1 #选配项
#当slave从库宕机后,假如relay-log损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,并且重新从malter上获取日志,这样就保证了relay-log 的完整性。默认情况下该功能是关闭的,将relay_log_recovery的值设置为1时,可在slave 从库上开启该功能,建议开启。
------------------------
systemctl restart mysqld
mysql -u root -p4455
> CHANGE master to
master_host='192.168.174.10',master_user='myslave',master_password='123456' ,master_log_file='master-bin.000001',master_log_pos=848; #配置同步,注意master_log_file和master_log_pos的值要与Master查询的一致
------------------------
> start slave; #启动同步
> show slave status\G #查看slave状态
slave_IO Running: Yes #负责与主机的io通信
slave_sQL_Running: Yes #负责自己的slave mysql进程
----------------------
#一股slave_IO_Running: No的可能性:
① 网络不通
② my.cnf配置有问题
③ 密码、file文件名、pos偏移量不对
④ 防火墙没有关闭
3、验证主从复制
主服务器上进入执行
> create database db_test;
去从服务器上查看
> show databases;
4、搭建读写分离
1、Amoeba服务器配置
①安装Java环境
因为 Amoeba基于是 jdkl.5开发的,所以官方推荐使用jdk1.5或1.6版本,高版本不建议使用
cd /opt/
cp jdk-6u14-linux-x64.bin /usr/local/
cd /usr/local/
chmod +x jdk-6u14-linux-x64
./jdk-6u14-linux-x64.bin #按yes,按enter
mv jdk1.6.0_14/ /usr/local/jdk1.6
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
----------------------------------
source /etc/profile
java -version
②安装Amoeba软件
mkdir /usr/local/amoeba
tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
chmod -R 755 /usr/local/amoeba/
/usr/local/amoeba/bin/amoeba #如显示amoeba start | stop说明安装成功
2、配置 Amoeba读写分离,两个slave读负载均衡
#先在Master,slave1、slave2的mysql上开放权限给 Amoeba 访问
grant all on *.* to test@'192.168.174.%' identified by '123456';
#再回到amoeba服务器配置amoeba服务:
cd /usr/local/amoeba/conf/
cp amoeba.xml amoeba.xml.bak
vim amoeba.xml
--30行--<property name="user">amoeba</property>
--32行--<property name="password">123456</property>
--115行--<property name="defaultPool">master</property>
--117-去掉注释-<property name="writePool">master</property>
<property name="readPool">slaves</property>
-----------------------------------------------------------
cp dbServers.xml dbservers.xml.bak
vim dbServers.xml
--23行--注释掉瞭作用:默认进入test库以防mysql中没有test库时,会报错
<!--<property name="schema">test</property> -->
--26--修改
<property name="user">test</property>
--28-30--去掉注释
<property name="password">123456</property>
--45--修改,设置主服务器的名Master
<dbServer name="master"parent="abstractServer">
--48--修改,设置主服务器的地址
<property name="ipAddress">192.168.174.122</property>
--52--修改,设置从服务器的名slavel
<dbServer name="slave1" parent="abstractServer">
--55--修改,设置从服务器1的地址
<property name="ipAddress">192.168.174.133</property>
--58--复制上面6行粘贴,设置从服务器2的名slave2和地址
<dbserver name="slave2"parent="abstractServer">
<property name="ipAddress">192.168.174.144</property>
--65行--修改
<dbserver name="slaves" virtual="true">
--71行--修改
<property name="poolNames">slave1,slave2</property>
/usr/local/amoeba/bin/amoeba start &
#启动Amoeba软件,按ctrl+c返回
netstat -anpt | grep java
#查看8066端口是否开启,默认端口为TCP 8066
3、测试读写分离
yum install -y mariadb-server mariadb
systemctl start mariadb.service
在客户端服务器上测试:
mysql -u amoeba -p123456 -h 192.168.174.10 -P8066 #通过amoeba服务器代理访问mysql,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器
注:
在主服务器上:
> use db_test;
> create table test (id int (10) , name varchar (10) , address varchar (20)
在两台从服务器上:stop slave;
#关闭同步
use db_test;