前言
关于主从复制
如果小伙伴不懂得Mysql主从复制可以直接点击,本章不做讲解
MySQL读写分离原理
●简单来说,主服务器写,从服务器读,基本的原理是让主数据库处理事务性查询,二从数据库处理Select查询数据库复制被用来把事务性查询导致的变更同步到群集中的从数据库。
目前比较常见的MySQL读写分离分为二种:
基于程序代码内部实现: |
---|
在代码中根据select、insert进行路由分类,这类方法也是目前生产环境应用广泛的,优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。 |
基于中间代理层实现: |
代理一般位于客户端和服务器之间,代理服务器接受到客户端的请求后通过判断后转发到后端数据库,有二个代表性程序 |
◆MySQL-Proxy。 ----MySQL的开源项目,通过自带的lua脚本进行SQL判断,MySQL官方不建议用这个在生产环境中 |
◆Amoeba(变形虫) ----由陈思儒开发,曾就职于阿里巴巴,该程序由Java语言开发,阿里将其用于生产环境但是它不支持事物和存储过程。 |
读写分离的配置与验证
(1)实验拓扑图
(2)实验环境
主机 | 操作系统 | IP地址 | 主要软件 |
---|---|---|---|
amoeba | centos-7.6 | 20.0.0.22 | amoeba-mysql-3.0.5-RC-distribution.zip与 jdk-8u144-linux-x64.tar.gz |
Master | centos-7.6 | 20.0.0.21 | mysql-boost-5.7.20.tar.gz |
Slave1 | centos-7.6 | 20.0.0.25 | mysql-boost-5.7.20.tar.gz |
Slave2 | centos-7.6 | 20.0.0.26 | mysql-boost-5.7.20.tar.gz |
客户机 | centos-7.6 | 20.0.0.23 | mysql-boost-5.7.20.tar.gz |
IP: 21 23 25 26 都需要安装Mysql
其中:21 25 26 配置主从复制
不会编译安装mysql与搭建主从复制的小伙伴:点击此段文字有详细步骤
(3)卸载原有的java环境
如果你是虚拟机一定要卸载,如果是生产环境请看情况而定
#20.0.0.22下操作
###确定java版本 1.8.0_181的 有点高
[root@localhost ~]# java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
[root@localhost ~]# rpm -qa |grep java
java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el7.x86_64
tzdata-java-2018e-3.el7.noarch
python-javapackages-3.4.1-11.el7.noarch
java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64
javapackages-tools-3.4.1-11.el7.noarch
java-1.7.0-openjdk-1.7.0.191-2.6.15.5.el7.x86_64
java-1.7.0-openjdk-headless-1.7.0.191-2.6.15.5.el7.x86_6
##查出openjdk相关的文件并且全部卸载它###
[root@localhost ~]# rpm -e --nodeps java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64
[root@localhost ~]# rpm -e --nodeps python-javapackages-3.4.1-11.el7.noarch
[root@localhost ~]# rpm -e --nodeps tzdata-java-2018e-3.el7.noarch
[root@localhost ~]# rpm -e --nodeps javapackages-tools-3.4.1-11.el7.noarch
[root@localhost ~]# rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.191-2.6.15.5.el7.x86_64
[root@localhost ~]# rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el7.x86_64
[root@localhost ~]# rpm -e --nodeps java-1.7.0-openjdk-1.7.0.191-2.6.15.5.el7.x86_64
##安装JDK##
上传JDK到opt目录
[root@localhost ~]# cd /opt
[root@localhost opt]# tar xzvf jdk-8u144-linux-x64.tar.gz
[root@localhost opt]# cp -rv jdk1.8.0_144/ /usr/local/java
#去末行添加JAVA环境,不然跑不起来
[root@localhost opt]# vi /etc/profile
export JAVA_HOME=/usr/local/java
export JRE_HOME=/usr/local/java/jre
export PATH=$PATH:/usr/local/java/bin
export CLASSPATH=./:/usr/local/java/lib:/usr/local/java/jre/lib
[root@localhost opt]# source /etc/profile
[root@localhost opt]# java -version ###java环境变成1.8.0_144的##
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
(4)安装amoeba:20.0.0.22
官网:https://sourceforge.net/projects/amoeba/files/
##20.0.0.22下操作
###这里我已经下载放到opt下
#如果unzip命令没有
[root@localhost opt]# yum -y install unzip
[root@localhost opt]# unzip amoeba-mysql-3.0.5-RC-distribution.zip -d /usr/local/
#改名,太长不方便
[root@localhost opt]# mv /usr/local/amoeba-mysql-3.0.5-RC/ /usr/local/amoeba
#改权限,没权限操作会报错
[root@localhost opt]# chmod -R 755 /usr/local/amoeba/
[root@localhost opt]# vi /usr/local/amoeba/jvm.properties
JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k"
#修改,放大空间
##制作amoeba管理脚本
[root@localhost opt]# vi /etc/init.d/amoeba
#!/bin/bash
#chkconfig: 35 62 62
#
export JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
NAME=Amoeba
AMOEBA_BIN=/usr/local/amoeba/bin/launcher
SHUTDOWN_BIN=/usr/local/amoeba/bin/shutdown
PIDFILE=/usr/local/amoeba/Amoeba-MySQL.pid
SCRIPTNAME=/etc/init.d/amoeba
case "$1" in
start)
echo -n "Starting $NAME... "
$AMOEBA_BIN
echo " done"
;;
stop)
echo -n "Stoping $NAME... "
$SHUTDOWN_BIN
echo " done"
;;
restart)
$SHUTDOWN_BIN
sleep 1
$AMOEBA_BIN
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}"
exit 1
;;
esac
[root@localhost opt]# chmod +x /etc/init.d/amoeba
##交给service管理,这里做了下一条命令才能执行
[root@localhost opt]# chkconfig --add amoeba
[root@localhost opt]# service amoeba start
[root@localhost opt]# ctrl + c
#默认监听在8066端口
netstat -anpt | grep 8066
#开启继续,没开启回去检查
(5)在三台mysql数据库中为amoeba授权
切记,以下操作每一条参与主从复制服务的都要操作
##登录20.0.0.21终端###
[root@localhost ~]# mysql -u root -p ####输入密码abc123
mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> GRANT ALL ON *.* TO 'test'@'20.0.0.%' IDENTIFIED BY 'abc123';
mysql> FLUSH PRIVILEGES;
mysql> quit
##登录20.0.0.25终端###
[root@localhost ~]# mysql -u root -p ####输入密码abc123
mysql> GRANT ALL ON *.* TO 'test'@'20.0.0.%' IDENTIFIED BY 'abc123';
mysql> FLUSH PRIVILEGES;
mysql> quit
##登录20.0.0.26终端###
[root@localhost ~]# mysql -u root -p ####输入密码abc123
mysql> GRANT ALL ON *.* TO 'test'@'20.0.0.%' IDENTIFIED BY 'abc123';
mysql> FLUSH PRIVILEGES;
mysql> quit
(6)修改amoeba配置文件:操作谨慎
#20.0.0.22下操作
[root@localhost amoeba]# vi conf/amoeba.xml
---28行-----设置客户端连接amoeba前端服务器时使用的用户名和密码----
<property name="user">amoeba</property>
----30行---------
<property name="password">123456</property>
------------------------------------以上配置用于客户端连接用户名密码-------------
---83-去掉注释<!-- -->-同时把默认的server1改成master,把默认的servers改成slaves
<property name="defaultPool">master</property>
<property name="writePool">master</property>
<property name="readPool">slaves</property>
[root@localhost amoeba]# vi conf/dbServers.xml
--26-29--去掉注释--
<property name="user">test</property>
<property name="password">abc123</property>
------主服务器地址---
43 <dbServer name="master" parent="abstractServer">
46 <property name="ipAddress">192.168.100.42</property>
--50-从服务器主机名-
<dbServer name="slave1" parent="abstractServer">
--53-从服务器地址-
<property name="ipAddress">192.168.100.43</property>
-----------------省略------------------------
--末尾--
<dbServer name="slaves" virtual="true"> #####name后面改成 slaves
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>
<!-- Separated by commas,such as: server1,server2,server1 -->
<property name="poolNames">slave1,slave2</property> #####poolNames后面改成 slave1,slave2
</poolConfig>
</dbServer>
[root@localhost amoeba]# service amoeba restart
Ctrl+c
[root@localhost amoeba]# netstat -anpt | grep java
##过滤JAVA环境,有继续,无回头检查配置文件
(7)用客户端测试
20.0.0.23操作
service firewalld stop
setenforce 0
yum install -y mysql
mysql -u amoeba -p123456 -h 20.0.0.22 -P8066
在主mysql上创建数据库
[root@localhost ~]# mysql -u root -pabc123 ###输入mysql密码 abc123
mysql> use test;
Database changed
mysql> create table zhang1 (id int(10),name varchar(10),address varchar(20));
Query OK, 0 rows affected (0.05 sec)
#在从1 mysql关闭同步
[root@localhost ~]# mysql -u root -p ###输入mysql密码 abc123
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> use test;
Database changed
mysql> insert into zhang1 values('2','zhang','this_is_slave1');
Query OK, 1 row affected (0.00 sec)
#在从2 mysql关闭同步
[root@localhost ~]# mysql -u root -p ###输入mysql密码 abc123
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> use test;
Database changed
mysql> insert into zhang1 values('3','zhang','this_is_slave2');
Query OK, 1 row affected (0.00 sec)
#登录客户端
[root@localhost ~]# mysql -u amoeba -p123456 -h192.168.32.14 -P8066
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bdqn |
| db_test |
| mysql |
| performance_schema |
| sys |
| test | #####发现数据库test
+--------------------+
7 rows in set (0.01 sec)
MySQL [(none)]> use test; ####进入数据库test
Database changed
MySQL [test]> select * from zhang1; ###查看zhang1信息 发现进入slave1 数据中的数据
| id | name | address |
+------+-------+----------------+
| 2 | zhang | this_is_slave1 |
+------+-------+----------------+
1 row in set (0.00 sec)
MySQL [test]> select * from zhang1; ###查看zhang1信息 发现进入slave2 数据中的数据
+------+-------+----------------+
| id | name | address |
+------+-------+----------------+
| 3 | zhang | this_is_slave2 |
+------+-------+----------------+
1 row in set (0.01 sec)
#########上述实验,实现数据读取负载均衡#######
###在客户机上继续写输数据,按照正常的规则应该是slave1 和slave2是看不见的
MySQL [(none)]> use test;
Database changed
MySQL [test]> insert into zhang1 values('4','zhang','write_test');
Query OK, 1 row affected (0.01 sec)
######登录masta###
[root@localhost ~]# mysql -u root -p
mysql> use test;
Database changed
mysql> select * from zhang1;
+------+-------+----------------+
| id | name | address |
+------+-------+----------------+
| 1 | zhang | this_is_master |
| 4 | zhang | write_test |
+------+-------+----------------+
2 rows in set (0.00 sec)
######登录slave1
[root@localhost ~]# mysql -u root -p
mysql> use test;
Database changed
mysql> select * from zhang1;
+------+-------+----------------+
| id | name | address |
+------+-------+----------------+
| 2 | zhang | this_is_slave1 |
+------+-------+----------------+
1 row in set (0.00 sec)
######登录slave2
[root@localhost ~]# mysql -u root -p
mysql> use test;
Database changed
mysql> select * from zhang1;
+------+-------+----------------+
| id | name | address |
+------+-------+----------------+
| 3 | zhang | this_is_slave2 |
+------+-------+----------------+
1 row in set (0.00 sec)
#######上述验证结果如下###
#在客户端上操作写入数据,数据是往master上写的,在salve1和slave2上看不到写的数据