MySQL主从复制与读写分离
简介
在实际的生产环境中。如果对MySQL数据库的读和写都在一台数据库服务器中操作,无论是在 安全性、高可用性还是高并发等各个方面都是不能满足实际需求的。本章将首先讲解MySQL主从复 制和MySQL读写分离的原理,然后介绍如何配置MySQL主从复制和MySQL读写分离。
MySQL主从复制原理
MySQL的主从复制和MySQL的读写分离两者有着紧密联系,首先要部署主从复制,只有主从复 制完成了,才能在此基础上进行数据的读写分离。
1.MySQL支持的复制类型
(1)基于语句的复制。在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL 默认采用基于语句的复制,效率比较高。
(2)基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
(3)混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采 用基于行的复制。
2.复制的工作过程
MySQL度制的工作过程如图
(1)在每个事务更新数据完成之前,Master在二进制日志记录这些改变。写入二进制日志完成 后.Master通知存储引擎提交事务。
(2) Slave 将 Master 的 Binary log复制到其中继日志。首先,Slave 开始一个工作线程一-/0线 程,/0线程在Master上打开一个普通的连接,然后开始Binlog dump process, Binlog dump process 从Master 的二进制日志中读取事件,如果已经跟上Master.它会睡眠并等待Master产生新的事件。/O 线程将这些事件写入中继日志。
(3) SQL slave thread (SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件, 并重放其中的事件而更新 Slave 的数据,使其与Master 中的数据一致。只要该线程与V/0线程保持一 致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
复制过程有一个很重要的限制,即复制在 Slave上是串行化的,也就是说 Master上的并行更新 操作不能在Slave上并行操作。
MySQL读写分离原理
简单来说,读写分离(图10.3)就是只在主服务器上写,只在从服务器上读。基本的原理是让 主数据库处理事务性查询,而从数据库处理select查询。数据库复制被用来把事务性查询导致的变 更同步到群集中的从数据库。
目前较为常见的MySQL读写分离分为两种。
1.基于程序代码内部实现
在代码中根据 select, inser 进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是 性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;缺点是需要开发人员来 实现,运维人员无从下手。
2.基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端的请求后通过判断后转发到后端数 据库,有两个代表性程序。
(1)MySQL-Proxy.MySQL-Proxy为MySQL开源项目,通过其自带的Iu脚本进行SQL判断,虽 然是MySQL官方产品,但是MySQL官方并不建议将MySQL-Proxy 用到生产环境。
(2) Amoeba(变形虫)。由陈思儒开发,其曾就职于阿里巴巴。该程序用 Java语言进行开发, 阿里巴巴将其用于生产环境。它不支持事务和存储过程。
经过上述简单的比较,通过程序代码实现MySQL读写分离自然是一个不错的选择,但是并不是 所有的应用都适合在程序代码中实现读写分离,例如一些大型复杂的Java应用,如果在程序代码中 实现读写分离对代码改动就较大。所以,像这种大型复杂的应用一般会考虑使用代理层来实现。本 章后续案例通过Amoeba实现。
案例环境
初始配置
关闭防火墙
systemctl disable firewalld --now
关闭Selinux
setenforce 0
sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
配置IP DNS 网关
nmtui
挂载光盘
mount /dev/cdrom /mnt/
mount: /dev/sr0 写保护,将以只读方式挂载
MySQL安装
主从两台配置一样
安装所需组件包
[root@lgc ~]# yum -y install gcc gcc-c++ ntp vim net-tools ncurses-devel autoconf
上传mysql安装包 mysql-5.6.36.tar.gz cmake-2.8.6.tar.gz
解压cmakne
[root@lgc ~]# tar zxf cmake-2.8.6.tar.gz
编译安装cmake
[root@lgc ~]# cd cmake-2.8.6/
[root@lgc cmake-2.8.6]# ./configure && gmake && gmake install
解压mysql
[root@lgc cmake-2.8.6]# cd
[root@lgc ~]# tar zxf mysql-5.6.36.tar.gz
编译安装mysql
[root@lgc ~]# cd mysql-5.6.36
[root@lgc mysql-5.6.36]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all
[root@lgc mysql-5.6.36]# make && make install
创建mysql用户和组
[root@lgc mysql-5.6.36]# groupadd mysql
[root@lgc mysql-5.6.36]# useradd -M -s /sbin/nologin mysql -g mysql
修改mysql安装目录权限 复制默认配置文件
[root@lgc mysql-5.6.36]# chown -R mysql:mysql /usr/local/mysql
[root@lgc mysql-5.6.36]# cp support-files/my-default.cnf /etc/my.cnf
Mysql数据库 初始化
[root@lgc mysql-5.6.36]# cd
[root@lgc ~]# cd /usr/local/mysql/
[root@lgc mysql]# ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
添加mysql 到系统服务
[root@lgc mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@lgc mysql]# chmod +x /etc/init.d/mysqld
[root@lgc mysql]# chkconfig --add mysqld
启动MySQL服务
[root@lgc ~]# systemctl start mysql
添加mysql操作指令关联系统
[root@lgc ~]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile && . /etc/profile
用户登录测试
[root@lgc ~]# mysql -u root
Mysql主从复制
主配置
[root@lgc ~]# cd /usr/local/mysql/
[root@lgc mysql]# cat << EOF >> /etc/ntp.conf
server 127.127.1.0
fudge 127.127.1.0 stratum 8
EOF
[root@lgc mysql]# systemctl start ntpd
从配置
Ntp服务 slave配置
[root@lgc ~]# yum -y install ntpdate
[root@lgc ~]# ntpdate 192.168.55.48
主服务器
修改配置文件
[root@lgc mysql]# sed -i 's/# server_id = .*/server_id = 11/' /etc/my.cnf
[root@lgc mysql]# sed -i '/server_id = 11/a\log_bin = master-bin' /etc/my.cnf
[root@lgc mysql]# sed -i '/log_bin = master-bin/a\log-slave-updates = true' /etc/my.cnf
[root@lgc mysql]# systemctl restart mysqld
创建授权用户 myslave 123456
[root@lgc ~]# mysql -u root
mysql> grant replication slave on *.* to 'myslave'@'192.168.55.%' identified by '123456';
mysql> grant replication slave on *.* to 'root'@'192.168.55.%' identified by '123456'; //给后续amoeba主机使用授权root用户
mysql> flush privileges;
mysql> show master status;
从服务器配置
修改配置文件
[root@lgc mysql]# sed -i 's/# server_id = .*/server_id = 22/' /etc/my.cnf
[root@lgc mysql]# sed -i '/server_id = 22/a\relay-log = relay-log-bin' /etc/my.cnf
[root@lgc mysql]# sed -i '/relay-log = relay-log-bin/a\relay-log-index = slave-relay-bin.index' /etc/my.cnf
[root@lgc mysql]# systemctl restart mysqld
连接主服务器
[root@lgc mysql]# mysql -u root
mysql> change master to master_host='192.168.55.48',master_user='myslave',master_passwoord='123456',master_log_file='master-bin.000001',master_log_pos=624;
mysql> start slave;
mysql> show slave status\G;
MySQL读写分离
部署Java 运行环境
上传安装包 jdk-6u14-linux-x64.bin
[root@Haproxy ~]# chmod +x jdk-6u14-linux-x64.bin
[root@Haproxy ~]# ./jdk-6u14-linux-x64.bin
[root@Haproxy ~]# mv jdk1.6.0_14 /usr/local/jdk1.6
添加java 运行环境变量
[root@Haproxy ~]# 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/
[root@Haproxy ~]# source /etc/profile
[root@Haproxy ~]# java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
//Amoeba是基于jdk1.5开发的,所以官方推荐使用jdk1.5或1.6版本,高版本不建议使用
部署amoeba
上传amoeba软件包
创建amoeba主目录
[root@Haproxy ~]# mkdir /usr/local/amoeba
[root@Haproxy ~]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
[root@Haproxy ~]# chmod -R 755 /usr/local/amoeba/
[root@Haproxy ~]# cd /usr/local/amoeba/
[root@Haproxy amoeba]# vim conf/amoeba.xml
<property name="user">root</property> //客户端连接的用户
<property name="password">123456</property> //客户端连接密码
取消注释
<property name="writePool">server1</property> //写入数据池名称
<property name="readPool">server2</property> //读取数据池名称
编辑数据库连接文件
[root@Haproxy amoeba]# vim conf/dbServers.xml
<property name="port">3306</property>
<property name="schema">test</property> //默认库 名称
<property name="user">root</property> //链接数据库用户名
<property name="password">123456</property> //链接数据库密码 如有注释要取消
<dbServer name="server1" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.55.48</property>
</factoryConfig>
</dbServer>
<property name="ipAddress">192.168.55.49</property>
//修改ipaddress 127.0.0.1 为mysql 主和从的IP
[root@Haproxy amoeba]# /usr/local/amoeba/bin/amoeba
amoeba start|stop //显示此内容说明Amoeba安装成功
启动amoeba
[root@Haproxy amoeba]# nohup ./bin/amoeba start &
[root@Haproxy amoeba]# netstat -anpt | grep java
..没启动查看进程删除java进程 重新启动
[root@Haproxy amoeba]# ps -aux
[root@Haproxy amoeba]# kill -9 9034
安装mysql客户端
[root@Haproxy ~]# yum -y install mariadb //mariadb的yum安装等同于源码包安装的mysql
测试
amoeba主机上连接
[root@Haproxy ~]# mysql -u root -p123456 -h 192.168.55.47 -P8066 //通过代理访问mysql
MySQL [(none)]> create table info (id int(10),name varchar(20)); //创建表info
MySQL [(none)]> insert into info values('1','liming');
MySQL [(none)]> insert into info values('2','libai'); //插入数据
在从服务器上停止同步
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
在主服务器上info表中添加zhangshang
mysql> insert into info values('3','zhangshang');
Query OK, 1 row affected (0.00 sec)
amoeba主机上查询验证
MySQL [(none)]> select * from info;
主服务器上查询
mysql> select * from info;
由于从服务器停止了同步,amoeba主机上查询到的只有1和2的数据,在主服务器上创建的数据3是查询不到的。
amoeba主机读取从服务器,主服务器创建数据同步到从服务器,停止从服务器同步后,主机便不能读取停止同步之后创建的数据。
原文地址:https://blog.csdn.net/m0_73258133/article/details/136443157
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!