天天看点

MySQL主从复制-读写分离一、MySQL主从复制二、MySQL读写分离原理三、部署主从同步(操作)

文章目录

  • 一、MySQL主从复制
    • 1、mysql的复制类型
    • 2、mysql主从复制的工作原理
      • 2.1主从复制相关线程
      • 2.2跟复制功能相关的文件
      • 2.3MySQL主从复制延迟
  • 二、MySQL读写分离原理
    • 1、原理
    • 2、为什么要做读写分离
    • 3、实现方式
  • 三、部署主从同步(操作)
    • 1.环境配置
    • 2.初始环境准备
    • 3.搭建mysql主从复制
    • 3.1配置主服务器(192.168.239.3)
    • 3.2配置从服务器 (192.168.239.4、192.168.239.6)
    • 3.3验证主从同步
    • 4.搭建Amoeba 实现读写分离(192.168.239.5)
    • 4.1安装Java环境
    • 4.2配置amoeba
    • 4.3在客户端测试(192.168.239.7)

一、MySQL主从复制

1、mysql的复制类型

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

2、mysql主从复制的工作原理

  • 主服务器 master 记录数据库通过 dump 线程将操作记录到 Binary log
  • 从服务器开启 I/O 线程向主服务器发送同步日志请求
  • 主服务器把二进制日志内容发送给从服务器
  • 从服务器将二进制日志记录的操作同步到relay log (中继日志) (存在从服务器的缓存中)
  • 从服务器中的sql线程将relay log日志记录的操作在从服务器执行后写入从服务器数据库。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N8IC2Ck8-1670146008850)(C:\Users\10445\AppData\Roaming\Typora\typora-user-images\image-20221204170932592.png)]

2.1主从复制相关线程

主节点:

dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log events

从节点:

I/O Thread:向Master请求二进制日志事件,并保存于中继日志中

SQL Thread:从中继日志中读取日志事件,在本地完成重放

2.2跟复制功能相关的文件

master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等

relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地relay log日志的对应关系

mariadb-relay-bin.00000#: 中继日志,保存从主节点复制过来的二进制日志,本质就是二进制日志

2.3MySQL主从复制延迟

1、master服务器高并发,形成大量事务

2、网络延迟

3、主从硬件设备导致 cpu主频、内存io、硬盘io/

4、本来就不是同步复制、而是异步复制 从库优化Mysql参数。比如增大innodb_buffer_pool_size,让更多操作在Mysql内存中完成,减少磁盘操作。 从库使用高性能主机。包括cpu强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了i/o面性。 从库使用SSD磁盘 网络优化,避免跨机房实现同步

二、MySQL读写分离原理

1、原理

读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性查询,而从数据库处理 select 查询。数据库复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库。

2、为什么要做读写分离

因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的。

但是数据库的“读”(读10000条数据可能只要5秒钟)。

所以读写分离,解决的是,数据库的写入,影响了查询的效率

PS:什么时候用读写分离

数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询(select)多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

3、实现方式

常见的 MySQL 读写分离分为以下两种:

① 基于程序代码内部实现

在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。

优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。

但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。

② 基于中间代理层实现

代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。

(1)MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua脚本进行SQL 判断。

(2)Atlas是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。

(3)Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。

Amoeba:是一个以MySql为底层数据存储,并对应提供MySQL协议接口的proxy(代理),外号变形虫

读取请求发送给从服务器是,采用轮询调度算法

amoeba使用的java语言编写,配置文件为xml

amoeba主要负责对外的一个代理IP

访问这个IP时,发送的请求为“写”请求,则会转给主服务器

当发送的请求为“读”时,会通过调度转发给从服务器,使用轮询算法,轮流分配给两台从服务器

amoeba可以视为调度器,如果主服务器挂掉(单点故障),则会有MHA解决这个问题

三、部署主从同步(操作)

1.环境配置

1 master服务器: 192.168.229.3
2 slave1服务器: 192.168.229.4
3 slave1服务器: 192.168.229.6
4 Amoeba服务器: 192.168.229.5
           

2.初始环境准备

1 #四台服务器上都初始化
2 systemctl stop firewalld
3 setenforce 0
           

3.搭建mysql主从复制

3.1配置主服务器(192.168.239.3)

1. #开启二进制日志
vim /etc/my.cnf
 
log-bin=master-bin        #开启二进制日志
binlog_format=MIXED       #二进制日志格式
log-slave-updates=true    #开启从服务器同步
 
2. #重启服务
systemctl restart mysqld.service 
 
3. #登入mysql,给从服务器在网段授权
mysql -uroot -p123456
grant replication slave on *.* to 'myslave'@'192.168.239.%' identified by '123456';
 
#刷新数据库
flush privileges;
 
#查看主服务器二进制文件
show master status;
开启二进制日志
           

3.2配置从服务器 (192.168.239.4、192.168.239.6)

1 #开启二进制日志
 2 vim /etc/my.cnf
 3 server-id = 11 #slave1和slave2的id不能相同,我slave2设置的22
 4 relay-log=relay-log-bin
 5 relay-log-index=slave-relay-bin.index
 6  
 7 #重启服务
 8 systemctl restart mysqld.service 
 9  
10 #登入mysql,配置同步注意master_log_file和master_log_pos的值要和master查询的一致
11 mysql -uroot -p123456
12 change master to master_host='192.168.239.4',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
13  
14 #启动同步,如果报错,执行restart slave试试
15 start slave;
16 show slave status\G;
17 ##以下两个必须要是YES
18 #Slave_IO_Running: Yes
19 #Slave_SQL_Running: Yes
20  
21  
22 #########slave2:192.168.239.6与以上操作相同######
           

3.3验证主从同步

1 #在主服务器上创建一个库
2 create database kgc;
3  
4 #在从服务器上查看
5 show databases;

2.4搭建Amoeba 实现读写分离(192.168.239.5)
2.4.1安装Java环境

 1 ################安装 Java 环境###############
 2 1.#下载安装包:jdk-6u14-linux-x64.bin、amoeba-mysql-binary-2.2.0.tar.gz 
 3 cd /opt
 4  
 5 2.#把jdk复制到/usr/local下
 6 cp jdk-6u14-linux-x64.bin /usr/local/
 7  
 8 3.#赋予jdk权限并执行
 9 chmod +x /usr/local/jdk-6u14-linux-x64.bin
10 cd /usr/local/
11 ./jdk-6u14-linux-x64.bin  #一路回车到底,最后输入yes 自动安装
12  
13 4.#jdk改个名字
14 mv jdk1.6.0_14/ jdk1.6
15  
16 5.#配置环境并刷新
17 vim /etc/profile
18 export JAVA_HOME=/usr/local/jdk1.6
19 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
20 export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
21 export AMOEBA_HOME=/usr/local/amoeba
22 export PATH=$PATH:$AMOEBA_HOME/bin
23  
24 source /etc/profile      #刷新配置文件
           

4.搭建Amoeba 实现读写分离(192.168.239.5)

4.1安装Java环境

1 ################安装 Java 环境###############
 2 1.#下载安装包:jdk-6u14-linux-x64.bin、amoeba-mysql-binary-2.2.0.tar.gz 
 3 cd /opt
 4  
 5 2.#把jdk复制到/usr/local下
 6 cp jdk-6u14-linux-x64.bin /usr/local/
 7  
 8 3.#赋予jdk权限并执行
 9 chmod +x /usr/local/jdk-6u14-linux-x64.bin
10 cd /usr/local/
11 ./jdk-6u14-linux-x64.bin  #一路回车到底,最后输入yes 自动安装
12  
13 4.#jdk改个名字
14 mv jdk1.6.0_14/ jdk1.6
15  
16 5.#配置环境并刷新
17 vim /etc/profile
18 export JAVA_HOME=/usr/local/jdk1.6
19 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
20 export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
21 export AMOEBA_HOME=/usr/local/amoeba
22 export PATH=$PATH:$AMOEBA_HOME/bin
23  
24 source /etc/profile      #刷新配置文件
           

4.2配置amoeba

############## 安装amoeba ###########
 
1.#在/usr/local目录下创建amoeba目录
mkdir /usr/local/amoeba
 
2.#切换至opt解压amoeba
cd /opt/
tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
 
cd /usr/local/ 切换至目录查看
 
 
3.#给目录/usr/local/amoeba赋予执行权限
chmod -R 755 /usr/local/amoeba/
 
4.#运行amoeba
/usr/local/amoeba/bin/amoeba
 
 
###########配置 Amoeba读写分离 ####
5.#先在Master、Slave1mysql上开放权限给 Amoeba 访问
grant all on *.* to test@'192.168.239.%' identified by '123456';
flush privileges;
 
6.#备份amoeba配置
cd /usr/local/amoeba/conf/
cp amoeba.xml amoeba.xml.bak
cp dbServers.xml dbServers.xml.bak
 
7.#修改amoeba配置
vim amoeba.xml
30 <property name="user">amoeba</property>
#设置登录用户名
32<property name="password">123456</property>
#设置密码
 
115<property name="defaultPool">master</property>
#设置默认池为master
118<property name="writePool">master</property>
#设置写池
119<property name="readPool">slaves</property>
#设置读池
 
vim dbServers.xml 
23 <!-- <property name="schema">test</property> -->
#23行注释
26<property name="user">test</property>
#设置登录用户
28 <!--  mysql password -->
#删除
29<property name="password">123456</property>
#解决28注释,添加密码
 
45<dbServer name="master"  parent="abstractServer">
#服务池名
48<property name="ipAddress">192.168.239.3</property>
#添加地址
 
52<dbServer name="slave1"  parent="abstractServer">
55<property name="ipAddress">192.168.239.4</property>
复制6行 添加另一从节点
59<dbServer name="slave2"  parent="abstractServer">
62<property name="ipAddress">192.168.239.6</property>
 
66<dbServer name="slaves" virtual="true">
#定义池名
72<property name="poolNames">slave1,slave2</property>
#写上从节点名
 
8.#启动amoeba,并测试
amoeba start
netstat -ntap |grep java
           

vim amoeba.xml

vim dbServers.xml

4.3在客户端测试(192.168.239.7)

1 #安装mariadb
 2 yum install mariadb mariadb-server.x86_64 -y
 3  
 4 #登入并查看数据库
 5 mysql -uamoeba -p123456 -h 192.168.239.5 -P8066
 6  
 7  
 8 #测试同步
 9 ##在主服务器服务器上新建表
10 use kgc;
11 create table info(id int(10),name char(40));
12 show tables;
13  
14 ##在客户机上,插入数据会同步到所有数据库中
15  use kgc;
16  insert into info values(1,'zhangsan');
17  
18 ##在主从服务器上查看
19  
20 #测试读写分离
21 #停止slave1和slave2的slave同步功能
22 stop slave;
23  
24 #在master、slave1和slave2上插入数据