MySQL主从复制
MySQL的复制类型
1,基于语句的复制(STATEMENT,MySQL默认类型)
2,基于行的复制(POW)
3,混合类型的复制(MIXED)
MySQL主从复制的工作过程
当主数据库的数据更新时,会将数据写入自己的二进制文件,而这时,从数据库会生成一个I/O线程连接到主数据库。I/O线程会读取主数据库二进制文件中更新的数据到从数据库中的中继日志文件中。从数据库在得到数据后会生成一个SQL线程,SQL线程会将数据进行重放,已达到将主数据库的数据复制到从数据库中的目的。
MySQL主从复制延迟
1,master服务器高并发,形成大量事务
2,网络延迟
3,主从硬件设备导致(cpu,内存,磁盘等)
4,本来就不是同步复制,而是异步复制
解决主从复制延迟
1,从数据库优化MySQL参数,如增大innodb_buffer_pool_size
2,从数据库提高性能主机,如cpu,内存
3,从数据库使用SSD磁盘,加大存储速度
4,网络优化,避免跨机房实现同步
主从复制实例
master:192.168.226.70 mysql5.7 ntp(时间同步装置)
slave1:192.168.226.80 mysql5.7 ntp(时间同步装置)
slave2:192.168.226.90 mysql5.7 ntp(时间同步装置)
1,主服务器配置
yum install -y ntp #安装时间同步装置
vim /etc/ntp.conf
--在底部添加--
server 127.127.226.0 #设置本地为时钟源
fudge 127.127.226.0 stratum 8 #设置时间层级为8
2,从服务器配置
yum install -y ntp ntpdaye
service ntpd start
/usr/sbin/ntpdate 192.168.226.70 #进行时间同步
crontab -e #开启周期性任务
*/30 * * * * /usr/sbin/ntpdate 192.168.226.70 #每30分钟同步一次
3,主服务器mysql配置
vim /etc/my.cof
server-id = 11
log-bin=master-bin #添加,主服务器开启二进制日志
binlog_format = MIXED
log-slave-updates=true #添加,允许从服务器更新二进制文件
systemctl restart mysqld
mysql -uroot -p123456
grant replication slave on *.* to 'zzy'@'192.168.226.%' identified by '123456';
#给同网段所有主机授予所有库所有表的全部权限。
flush privileges;
show maser status;
4,从服务器mysql配置
从服务器1:
vim /etc/my.cnf
server-id = 22
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
systemctl restart mysqld
mysql -uroot -p123456
change master to master_host='192.168.226.70',master_user='zzy',master_password='123456',master_log_file='master-bin.000002',master_log_pos=1952;
start slave;
show slave status\G;
从服务器2:
server-id = 33
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
systemctl restart mysqld
mysql -uroot -p123456
change master to master_host='192.168.226.70',master_user='zzy',master_password='123456',master_log_file='master-bin.000002',master_log_pos=1952;
start slave;
show slave status\G;
注:出现IO与SQL为yes即可。IO负责与主服务器通信,SQL负责自己的slave mysql进程
验证主从复制
主服务器上创建数据库
create database jmi;
在从数据库上查看即可
show databases;
MySQL读写分离
1,什么是读写分离
让主数据库处理增,删,改操作,让从数据库处理select查询操作
2,为什么要读写分离
因为写的操作十分耗时,而读则很快速。这样的话,写入的操作会影响到查询的效率
3,什么时候要读写
当程序使用的数据库较多,更新少,查询多是会做读写分离。
4,MySQL读写分离原理
在主服务器上进行写的操作,在从服务器上进行读的操作,再利用数据复制将主服务器上的写入的数据更新到从服务器上,这样客户端在读取从服务器时,也能读取到写在主服务器上的数据。
常见的两种读写分离
1,基于程序代码内部实现
在代码中根据select,insert进行路由分类,这是目前运用最广泛的。
优点是性能好,在代码中实现,所以不用增加额外的设备开支。
2,基于中间代理层实现
代理一般位于客户端与服务器之间,代理服务器接到客户端的请求后,通过判断是读还是写,转发给后端的主或从服务器。
(1)MySQL-Proxy。为mysql开源项目,通过其自带的lua脚本进行SQL的判断
(2)Atlas。由奇虎360开发的web平台部基础架构团队开发维护的一个基于mysql协议的数据中间层项目。
(3)Amoeba。由陈思儒开发,由Java语言开发。
使用amoeba部署读写分离
master :192.168.226.70
slave1:192.168.226.80
slave2:192.168.226.90
amoeba:192.168.226.40
client:192.168.226.50
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
1,amoeda服务配置
安装jdk环境
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
mv jdk.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
chomd -R 755 /usr/local/amoeba/
/usr/local/amoeba/bin/amoeba
##显示 amoeba start|stop 即安装成功
在主和从数据库开放权限给amoeba访问
grant all on *.* to 'test'@'192.168.226.%' identified by '123456';
在amoeba服务器配置amoeba服务
cd /usr/local/amoeba/conf
vim amoeba.xml
vim dbServers.xml
/usr/local/amoeba/bin/amoeba start & #启动amoeba软件可以按ctrl+c返回,但不会退出软件
netstat -natp | grep java #出现8066端口即成功
MySQL读写分离测试
在客户端
yum install mariadb-server mariadb
systemctl start mariadb.server
mysql -u amoeba -p123456 -h 192.168.226.50 -P8066
连接成功
测试
在主服务器上创建一个数据库和表
并写入字段及字段类型
在两台从服务器上关闭同步功能
并在两台从服务器上分别向在主服务器中创建的表中插入数据
接着在主服务器上向创建的表中插入一条数据
在客户端服务器上查看表信息
查看到的信息会是两台从服务器上的信息,因为是轮询模式,所以会相继显示两台从服务器上的信息。
因为,关闭了同步功能,而又部署了读写分离,所有,在主服务器上写入的信息,不会显示。在从服务器上写入的因为是可读的所以会轮询显示。
(客户端上的写操作会给到主服务器,查询则会给到从服务器,关闭了同步功能,主从复制也关闭,所以,数据不会得到更新)
在客户端上写入一条数据
在主服务器上查询表信息,只能看到在客户端写入的信息,看不到从服务器上的。
再开启同步功能
进行查询
可以发现,已同步过来,但因为1和2两条数据是分别在两台从数据库上插入的,所以不会出现在一起。