在实际的生产环境中,如果对数据库的读和写都在同一个数据库服务器中操作,无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。
因此,一般来说都是通过主从复制的方式来同步数据,通过读写分离来提升数据库的并发负载能力。如图,这样的操作大量减轻了主服务器的压力。
MySQL主从复制的工作过程
1.在每个事务更新数据完成之前,Master 在二进制日志记录这些改变。写入二进制日志完成后,Master通知存储引擎提交事务。
2.Slave将Master 的Binary log复制到其中继日志。
Slave开始一个工作线程——I/O线程,I/O线程在Master上打开一个普通的连接,然后开始Binlog dump process。Binlog dump process从主Master 的二进制日志中读取事件,如果已经跟上Master,它会睡眠并等待Master 产生新的事件, I/O线程将这些事件写入中继日志。
3.SQL 线程 (SQL从线程)从中继日志读取事件.并重放其中的事件至更新Slave的数据,使其与Master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于centOS系统的缓存中,所以中继日志的开销很小。
需要注意的是Master上的并行更新操作不能在Slave 上并行操作。
MySQL读写分离
关于MySQL读写分离,可以简单理解为只在主服务器上写,只在从服务器上读。在应用层面上不再赘述。
目前较为常见的MySQL读写分离方法:
一是基于程序代码内部实现,但对程序内部代码改动较大
二是基于中间代理层实现,本次实验以Amoeba(变形虫)为例
实验流程:
一、准备:两台linux服务器,一台搭建Amoeba、mysql主服务器,另一台搭建mysql从服务。实验开始之前确保两台linux部署并开启了mysql服务。
二、配置MySQL主从复制
1.配置MySQL Master主服务器
1)在/etc/my.cnf中修改或者增加下面内容
vim /etc/my.cnf
server_id = 11 //主从mysql的id不能一样
log_bin = master-bin //定义二进制文件前缀
log-slave-updates = true //允许从mysql更新日志
2)重启mysqld服务
./mysqld.sh restart
3)登录MySQL程序,给从服务器授权
mysql -u root -p
grant replication slave on *.* to 'myslave'@'47.93.222.225' identified by '123456';
flush privileges; //刷新授权信息
检查当前的二进制文件和偏移量
2.配置从MySQL服务器
1).修改配置文件/etc/my.cnf
[mysqld]
server_id = 22
relay-log = relay-log-bin //定义中继日志前缀
relay-log-index = slave-relay-bin.index
2)由于笔者是通过移植的方式安装的MySQL程序,两台服务器的MySQL程序uuid重复,需要更其一改使其不重复。
cd /usr/local/mysql/data/
vim auto.cnf
[auto]
server-uuid=ab7d9b26-943e-11ee-8435-000c29f730d8 //只需更改一个字符即可
更改完成后mysqld.sh restart 重启mysqld服务
3)配置从服务器与主服务器同步
mysql -u root -p
change master to master_host='39.107.84.218',master_user='myslave',master_password='123456',master_log_file='master-bin.000003',master_log_pos=120;
//指定主mysql的ip,二进制文件,偏移量。二进制文件名称和偏移量在配置主mysql时有提及。
start slave; //开启主从复制;
show slave status\G; //查看从mysql状态,确定I/O线程和SQL线程都是yes状态
需要注意的是如果Slave_IO_Running显示connecting的状态,先测试能否远程登录msater mysql系统。并在云服务器的安全组中打开两台mysql服务器的相应端口的访问策略
3.测试数据同步
在主mysql上创建yuexiameishao库,创建好之后,在从mysql上查看是否同步
确定完全同步,完成mysql主从复制
三、配置 MySQL读写分离
1.搭建jdk环境。因为Amoeba是基于jdk1.5开发的,所以官方推荐使用jdk1.5或1.6版本,高版本不建议使用。下载编译好的jdk程序传输到mysql主服务器
chmod +x jdk-6u14-linux-x64.bin
./jdk-6u14-linux-x64.bin //运行jdk环境
输入yes。等待运行,出现Press Enter to contiune.....就说明运行成功,ctrl+c退出安装过程
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 //刷新环境变量
查看JDK版本信息,JDK1.6版本添加成功,java环境已配置成功
2.安装并配置Amoeba软件
mkdir /usr/local/amoeba
tar -zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ //对Amoeba(变形虫)源码包解包
~]# cd /usr/local/amoeba/
chmod -R 755 /usr/lcoal/amoeba
3.配置amoeba读写分离
mysql -u root -p
grant all on *.* to 'test'@'47.93.222.225' identified by '123456'; //授权amoeba通过本机和从mysql的test用户访问
grant all on *.* to 'test'@'39.107.84.218' identified by '123456';
(在mysql从服务器上也添加这两条授权信息。)
flush privileges;
quit 退出mysql数据库系统
修改amoeba配置文件
cd /usr/local/amoeba/conf
vim amoeba.xml
定义master用于写操作,slave用于从操作
修改dbServer.xml文件,定义用于读和写的服务器ip
vim dbServer.xml
定义amoeba用于访问mysql数据库的用户名和密码,在mysql主从数据库中已添加授权
定义mysql主从服务器
访问slaces群集。调度到server1,如果有多个从mysql服务器,可以实现读操作的高可用负载均衡
4.启动ameoba
/usr/local/amoeba/bin/amoeba start&
出现端口号,说明启动成功
5.验证读写分离
关闭主从复制功能,使用amoeba代理登录的方式登录MySQL服务器,由于是代理登录,等同于在其他客户机上对MySQL进行操作。
1)在MySQL从服务器上关闭主从复制模块
mysql -u root -p
stop slave;
2)在主MySQL上进行操作,验证写操作只在主MySQL执行
将端口8066加入安全组
使用代理登录的方式登录amoeba登录MySQL
mysql -u amoeba -p123456 -h 39.107.84.218 -P8066 //使用变形虫代理登录
create database yuexiameishao1
查看库列表
查看从服务器的库列表,没有yuexiameishao1库,实现了写操作再主MySQL上执行
3)在从Mysql服务器上操作,验证读操作由从MySQL执行
mysql -u root -p
create database yue;
use yue;
create table test(name char(32),password char(48));
insert into test values('zhangsan','123456'); //写入一些信息,和主MySQL做区分
在主MySQL上做验证,使用amoeba代理登录的方式查看yue库test表,如果存在上面创建的表内容,整明实现了读操作只在从MySQL上执行。
mysql -u amoeba -p123456 -h 39.107.84.218 -P8066
查看表信息,是刚才从MySQL数据库的表内容
至此实现MySQL的读写分离和主从复制。