在实际生产环境中,如果对数据库的读和写都在同一个数据库服务器中操作,无论是安全性、高可用性,还是高并发等各个方面都是完全不能满足实际需求的,因此,一般来说都是通过主从复制(Master-Slave)的方式来同步数据,再通过读写分离来提升数据库的并发负载能力这样的方案来进行部署与实施。
MySQL 的主从复制和读写分离两者有着紧密关联,首先要部署主从复制,才能在此基础上进行数据的读写分离。
- MySQL 主从复制的复制类型
1) 基于语句的数据。在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句。 MySQL 默认采用基于语句的复制,效率比较高。
2) 基于行的复制。把改变的内容复制过去,而不是把命令从服务器上执行一遍。
3) 混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,采用基于行的复制。 - MySQL 读写分离原理
简单来说,读写分离就是只在主服务器上写,只在从服务器上读。基本原理是让主数据库处理事务性查询,而从数据库处理 select 查询。数据库复制被用来把事务性查询导致的变更同步到群集中的从服务器。
部署环境
主机 | 操作系统 | IP地址 | 主要软件 |
Master | CentOS 7.4 x86_64 | 192.168.100.200 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz |
Slave1 | CentOS 7.4 x86_64 | 192.168.100.201 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz |
Slave2 | CentOS 7.4 x86_64 | 192.168.200.202 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz |
Amoeba | CentOS 7.4 x86_64 | 192.168.200.203 | mysql-5.7.17.tar.gz 、ntp 、boost_1_59_0.tar.gz 、amoeba-mysql-binary-2.2.0.tar.gz 、jdk-6u14-linux-x64.bin |
Client | CentOS 7.4 x86_64 | 192.168.200.204 | mysql-5.7.17.tar.gz |
搭建 MySQL 主从复制
- 建立时间同步环境,在主节点上搭建时间同步服务器
systemctl stop firewalld.service
setenforce 0
yum -y install ntp #一般系统自带,没有的话yum安装
vim /etc/ntp.conf #添加下面的行
server 127.127.100.0 #本地为时钟源
fudge 127.127.100.0 stratum 8 #设置时间层级为8(一般限制15内)
systemctl restart ntpd #重启服务
- 在从服务器上进行时间同步
systemctl stop firewalld.service
setenforce 0
yum -y install ntpdate
/usr/sbin/ntpdate 192.168.100.200 #进行时间同步
- 在4台主机上安装 MySQL数据库
这边选择的是5.7版本,直接进行简单的编译安装即可。 - 配置 Master 主服务器
# vim /etc/my.cnf
server-id = 11 #修改
log-bin=master-bin #主服务器日志文件
log-slave-updates=true #从服务器更新二进制日志
# systemctl restart mysqld.service
# mysql -u root -p123456 #登录Mysql 给从服务器授权
mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.100.%' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;
mysql> show master status;
- 配置 Slave 从服务器(Slave1、Slave2配置相同)
# vim /etc/my.cnf
server-id = 22 #另一台从服务器也是22(不能和 Master 服务器相同)
relay-log=relay-log-bin #从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index #定义relay-log的位置和名称
# systemctl restart mysqld.service
- 登录 Slave 服务器,按 Master 服务器结果更改下面命令中 master_log_file 和 master_log_pos 的参数
# mysql -u root -p123456
mysql> change master to master_host='192.168.100.200',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
mysql> start slave; #启动同步
mysql> show slave status\G; #查看状态
- 验证主从复制效果
在 Master 服务器上创建一个 test 表,从服务器上查看。
搭建 MySQL 数据库的读写分离
Amoeba(变形虫)项目开源框架于2008年发布了一款 Amoeba for MySQL 软件。这个软件致力于 MySQL 的分布式数据库前端代理层,它主要为应用层访问 MySQL 时充当 SQL 路由,并具有负载均衡、高可用性、SQL 过滤、读写分离、可路由相关到目标数据库、可并发请求多台数据库。通过 Amoeba 已在很多企业的生产线上使用,其版本可在官网下载。
- 在 Amoeba 服务器上安装 Java 环境
systemctl stop firewalld.service
setenforce 0
cp jdk-6u14-linux-x64.bin /usr/local/
cd /usr/local
./jdk-6u14-linux-x64.bin #回车,输入"yes",回车
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 #刷新环境变量
- 安装并配置 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 #显示此内容说明 Amoeba 安装成功
- 在三台主从 MySQL 服务器上开放权限给 Amoeba 访问(三台服务器都要添加)
grant all on *.* to test@'192.168.100.%' identified by '123456';
- 在 Amoeba 服务器上编辑 amoeba.xml 配置文件
# vim /usr/local/amoeba/conf/amoeba.xml
--30行--
<property name="user">amoeba</property> #用户访问amoeba服务器的身份验证
--32行--
<property name="password">123456</property>
--115行--
<property name="defaultPool">master</property> #默认权限
--117-去掉注释-
<property name="writePool">master</property> #赋予master写权限
<property name="readPool">slaves</property> #赋予slaves读权限
# vi conf/dbServers.xml
-23行注释掉 作用:默认进入test库 以防mysql中没有test库时,会报错
<!-- <property name="schema">test</property> -->
--26--29--去掉注释-- #赋予amoeba用户权限
<property name="user">test</property>
<property name="password">123456</property>
-----42-主服务器地址---
<dbServer name="master" parent="abstractServer">
<property name="ipAddress">192.168.100.200</property>
--52-从服务器主机名-
<dbServer name="slave1" parent="abstractServer">
--55-从服务器1地址-
<property name="ipAddress">192.168.100.201</property>
--(这里上面6行复制修改)从服务器2地址
<dbServer name="slave2" parent="abstractServer">
<property name="ipAddress">192.168.100.202</property>
--64行--
<dbServer name="slaves" virtual="true">
--70行--
<property name="poolNames">slave1,slave2</property>
- 开启服务
/usr/local/amoeba/bin/amoeba start&
netstat -anpt | grep java
- 测试读写分离
- 客户机
systemctl stop firewalld.service
setenforce 0
mysql -u amoeba -p123456 -h 192.168.100.203 -P8066 #使用amoeba远程登录MySQL
- Master 服务器
mysql -u root -p
mysql> create database wang;
mysql> use wzn;
mysql> create table wzn (id int(10),name varchar(10),address varchar(20));
- Slave 服务器
mysql -u root -p
mysql> stop slave;
mysql> use wang;
mysql> use wzn;
# Slave1 服务器
mysql> insert into zang values('2','wzn','this_is_slave1');
# Slave2 服务器
mysq> insert into zang values('3','wzn','this_is_slave2');
- 此时我们通过客户机访问,使用
select * from wzn;
可以看到在两台 Slave 服务器上分别创建的数据。 - 我们在客户端上插入一条数据,此时查看表 wzn ,是看不到刚写的数据的,因为数据是写在 Master 服务器上,此时同步没有开启,但是我们登录 Master数据库可以看到数据写入成功。尝试开启同步,我们可以看到,数据同步到 Slave 数据库之后,我们可以看到新建的数据了。
由此可以证实:数据的写入是在 Master 服务器上;数据的读取是在 Slave 服务器上。
转载于:https://blog.51cto.com/13625676/2154246