Mysql读写分离的原理及配置--amoeba

it2023-04-01  78

文章目录

一、概述1.1 为什么要读写分离?1.2 原理1.3 目前比较常见的MySQL读写分离分为二种: 二、实验过程2.1:实验所需要的安装包2.2:实验配置阶段 三、实验过程

一、概述

1.1 为什么要读写分离?

在企业应用中,在大量的数据请求下,单台数据库将无法承担所有的读写操作配置多台数据库服务器以实现读写分离读写分离建立在主从复制的基础上

1.2 原理

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

1.3 目前比较常见的MySQL读写分离分为二种:

第一种

基于程序代码内部实现 在代码中根据select、insert进行路由分类,这类方法也是目前生产环境应用广泛的,优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。

第二种

基于中间代理层实现 代理一般位于客户端和服务器之间,代理服务器接受到客户端的请求后通过判断后转发到后端数据库,有二个代表性程序:

MySQL-Proxy。 ----MySQL的开源项目,通过自带的lua脚本进行SQL判断,MySQL官方不建议用这个在生产环境中

Amoeba(变形虫) ----由陈思儒开发,曾就职于阿里巴巴,该程序由Java语言开发,阿里将其用于生产环境

但是它不支持事物和存储过程。

二、实验过程

2.1:实验所需要的安装包

2.2:实验配置阶段

在开始实验前,我们需要先配置三台MySQL服务器的主从复制。具体配置方法在我上一篇博客中如果是图形化界面,那就已经有了java环境,我们需要先卸载原有的java环境! [root@localhost ~]# java -version ##确定java版本 1.8.0_181的 有点高 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-headless-1.8.0.181-7.b13.el7.x86_64 [root@localhost ~]# rpm -e --nodeps java-1.8.0-openjdk-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 [root@localhost ~]# rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.191-2.6.15.5.el7.x86_64 然后上传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 [root@localhost opt]# vi /etc/profile '//将如下配置文件插到最底下' export JAVA_HOME=/usr/local/java export JRE_HOME=/usr/local/java/jre '//java环境jre java的虚拟机 简称JVM' 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) 安装amoeba [root@localhost opt]# yum -y install unzip ###如果unzip命令没有,必须装下,如果装了,此步骤跳过## ## 这里我已经把amoeba软件包放入 /opt 目录下了 [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 ## 进入修改配置 ## 在32行,修改如下代码 JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m" JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k" 修改java虚拟机内存大小 = >> wq 保存 制作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 = >> wq 保存 [root@localhost opt]# chmod +x /etc/init.d/amoeba ## 添加执行权限 [root@localhost opt]# chkconfig --add amoeba [root@localhost opt]# service amoeba start ## 通过上面写的脚本,才能使用这句代码,开启amoeba ctrl + c '//开启后 ctrl + c 停止就行了' [root@localhost opt]# yum install net-tools ## 没有netstat命令则进行安装 [root@localhost opt]# netstat -anpt | grep 8066 //默认监听在8066端口 在三台mysql数据库中为amoeba授权 ##登录20.0.0.25主服务器### [root@localhost ~]# mysql -u root -p '//输入密码12345' mysql> create database test; Query OK, 1 row affected (0.01 sec) mysql> GRANT ALL ON *.* TO test@'20.0.0.%' IDENTIFIED BY '12345'; mysql> FLUSH PRIVILEGES; mysql> quit ##登录20.0.0.24从服务器1### [root@localhost ~]# mysql -u root -p ####输入密码12345 mysql> GRANT ALL ON *.* TO test@'20.0.0.%' IDENTIFIED BY '12345'; mysql> FLUSH PRIVILEGES; mysql> quit ##登录20.0.0.23从服务器2### [root@localhost ~]# mysql -u root -p ####输入密码12345 mysql> GRANT ALL ON *.* TO test@'20.0.0.%' IDENTIFIED BY '12345'; mysql> FLUSH PRIVILEGES; mysql> quit [root@localhost opt]# cd /usr/local/amoeba [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> '//上面修改后如下' <!-- --> 这种注释一定要去掉 82 <property name="LRUMapSize">1500</property> 83 <property name="defaultPool">master</property> 84 <property name="writePool">master</property> 85 <property name="readPool">slaves</property> 86 <property name="needParse">true</property> ## 该另一个配置文件 [root@localhost amoeba]# vi conf/dbServers.xml --26-29--去掉注释-- <property name="user">test</property> ## 授权,连主数据库的。这是账号 <property name="password">12345</property> ## 这是密码 -----------------以上是授权数据库账号和密码的--------------------- --------主服务器地址----------- ## 修改成下面的配置 43 <dbServer name="master" parent="abstractServer"> 46 <property name="ipAddress">20.0.0.25</property> --------从服务器地址----------- --50--从服务器主机名1-- <dbServer name="slave1" parent="abstractServer"> --53--从服务器IP地址1-- <property name="ipAddress">20.0.0.24</property> ## 在配置文件中,slave2是没有的,在下面添加从服务器主机2 <dbServer name="slave2" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <property name="ipAddress">20.0.0.23</property> </factoryConfig> </dbServer> ----------改另一个配置------------ <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> 修改完配置之后,重启一下amoeba [root@localhost amoeba]# service amoeba restart [root@localhost amoeba]# netstat -anpt | grep java tcp6 0 0 :::8066 :::* LISTEN 9058/java tcp6 0 1 20.0.0.22:33820 20.0.0.25:3306 SYN_SENT 9058/java

三、实验过程

测试用客户端 20.0.0.27

[root@localhost ~]# service firewalld stop ## 关闭防火墙 [root@localhost ~]# setenforce 0 ## 关闭核心防护 [root@localhost ~]# yum install -y mysql [root@localhost ~]# mysql -u amoeba -p123456 -h 20.0.0.22 -P8066 ##### 登录20.0.0.22 amoeba服务端

在主mysql上创建数据库 20.0.0.25

[root@localhost ~]# mysql -u root -p ###输入mysql密码 12345 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关闭同步 20.0.0.24

[root@localhost ~]# mysql -u root -p ###输入mysql密码 12345 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关闭同步 20.0.0.23

[root@localhost ~]# mysql -u root -p ###输入mysql密码 12345 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)

在主mysql上插入数据 20.0.0.25

[root@localhost ~]# mysql -u root -p ###输入mysql密码 12345 mysql> use test; Database changed mysql> insert into zhang1 values('1','zhang','this_is_master'); Query OK, 0 rows affected (0.05 sec)

登录客户端 20.0.0.27

[root@localhost ~]# mysql -u amoeba -p123456 -h 20.0.0.22 -P8066 MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | db_test | | mysql | | performance_schema | | sys | | test | #####发现数据库test +--------------------+ 6 rows in set (0.01 sec) '//这时候我们查找数据,只能找到在从服务器1和从服务器2的数据。' '//此时读写分离已经生效,从服务器负责读的功能,而我们客户端查找就相当于读的功能。' '//上述实验,可以查看从1和从2,证明实现数据读取负载均衡' MySQL [(none)]> use test; '//进入数据库test' Database changed MySQL [test]> select * from zhang1; '//查看zhang信息 发现进入slave1 数据中的数据' | id | name | address | +------+-------+----------------+ | 2 | zhang | this_is_slave1 | +------+-------+----------------+ 1 row in set (0.00 sec) MySQL [test]> select * from zhang; '//查看zhang信息 发现进入slave2 数据中的数据' +------+-------+----------------+ | id | name | address | +------+-------+----------------+ | 3 | zhang | this_is_slave2 | +------+-------+----------------+ 1 row in set (0.01 sec)

在客户机上 20.0.0.27 继续写输数据,按照正常的规则应该是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) ##登录mastar 20.0.0.25 主服务器 ## 我们可以查看到刚才在客户端写入的数据 [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 20.0.0.24 从服务器1 ## 发现是没有刚才写入的数据的! [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 20.0.0.23 ## 发现是没有刚才写入的数据的! [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)
最新回复(0)