Amoeba(变形虫)项目,该开源框架于2008年开始发布一款 Amoeba for Mysql软件。这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的 时候充当SQL路由功能,专一于分布式数据库代理层(Database Proxy)开发。座落与 Client、DB Server(s)之间,对客户端透明。具备负载均衡、高可用性、SQL 过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。 经过Amoeba你可以完成多数据源的高可用、负载均衡、数据切片的功能,目前Amoeba已在不少企业的生产线上面使用前端
优势:java
(1)下降费用,简单易用mysql
(2)提升系统总体可用性linux
(3)易于扩展处理能力与系统规模c++
(4)能够直接实现读写分离及负载均衡效果,而不用修改代码sql
缺点:数据库
(1)不支持事务与存储过程vim
(2)暂不支持分库分表,amoeba目前只作到分数据库实例centos
(3)不适合从amoeba导数据的场景或者对大数据量查询的query并不合适(好比一次请求返回10w以上甚至更多数据的场合)服务器
3.什么是读写分离
读写分离(Read/Write Splitting),基本的原理是让主数据库处理事务性增、改、删操做(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操做。
数据库复制被用来把事务性操做致使的变动同步到集群中的从数据库。
client linux6-1 IP:192.168.234.186
主MySQL centos7-1 IP:192.168.234.174
从MySQL01 centos7-2 IP:192.168.234.177
从MySQL02 centos7-5 IP:192.168.234.184
amoeba服务器 centos7-3 IP:192.168.234.181
yum install gcc 、 gcc-c++ 、make、cmake
ncurses-devel、bison、libaio-devel -y
groupadd -r mysql
useradd -g mysql -r -d /mydata/data mysql
tar zxvf mysql-5.5.24.tar.gz -C /opt
cd /opt/mysql-5.5.24.tar.gz
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
-DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock
-DDEFAULT_CHARSET=utf8
-DDEFAULT_COLLATION=utf8_general_ci
-DWITH_EXTRA_CHARSETS=all
-DWITH_MYISAM_STORAGE_ENGINE=1
-DWITH_INNOBASE_STORAGE_ENGINE=1
-DWITH_MEMORY_STORAGE_ENGINE=1
-DWITH_READLINE=1
-DENABLED_LOCAL_INFILE=1
-DMYSQL_DATADIR=/home/mysql
-DMYSQL_USER=mysql
-DMYSQL_TCP_PORT=3306
make && make install
4.更改mysql的主目录为mysql组
chown -R mysql.mysql /usr/local/mysql
5.配置mysql环境变量
echo "export PATH=\$PATH:/usr/local/mysql/bin" > /etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh
6.复制MySQL启动脚本和服务配置文件分别到/etc/my.cnf和/etc/init.d/mysqld
cp support-files/my-medium.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
7.给予相应的权限而且加入开机自启动项
chmod 755 /etc/init.d/mysqld
chkconfig --add /etc/init.d/mysqld
chkconfig mysqld --level 35 on
8.初始化数据库
/usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--ldata=/var/lib/mysql \
--basedir=/usr/local/mysql \
--datadir=/home/mysql
9.创建软连接
ln -s /var/lib/mysql/mysql.sock /home/mysql/mysql.sock
10.配置启动脚本
vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/home/mysql
11.启动MySQL服务
systemctl start mysqld.service
12.设置MySQL用户的密码
mysqladmin -u root password 'abc123'
[root@localhost ~]# vim /etc/my.cnf ...省略 log-bin=master-bin //这里原来的mysql修改成master log-slave-updates=true //添加,表示从服务器更新二进制日志 ...省略 server-id = 11
从新启动mysql服务,而且给予从服务器访问权限
[root@localhost ~]# systemctl restart mysqld.service //重启MySQL服务 [root@localhost ~]# mysql -u root -p Enter password: mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.234.%' IDENTIFIED BY '123456'; //给予从服务器访问权限 Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; //刷新生成二进制文件 Query OK, 0 rows affected (0.00 sec) mysql> show master status; //查看pos偏移量 +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000001 | 477 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.01 sec)
[root@localhost ~]# systemctl stop firewalld.service localhost ~]# setenforce 0 [root@localhost ~]# yum install ntpdate -y [root@localhost ~]# systemctl start ntpd.service [root@localhost ~]# vim /etc/my.cnf ...省略 server-id = 22 relay-log=relay-log-bin //从主服务器上同步日志文件记录到本地 relay-log-index=slave-relay-bin.index //定义relay-log的位置和名称
重启MySQL服务,而且指定从服务器同步的对象服务器
[root@localhost ~]# mysql -u root -p Enter password: mysql> change master to master_host='192.168.234.174',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=477; //设置同步的对象服务器及用户密码 Query OK, 0 rows affected (0.01 sec) mysql> start slave; //开启主从同步 Query OK, 0 rows affected (0.01 sec) mysql> show slave status\G; //查看slave状态 *************************** 1. row *************************** Slave_IO_State: Reconnecting after a failed master event read Master_Host: 192.168.234.174 Master_User: myslave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 564 Relay_Log_File: localhost-relay-bin.001259 Relay_Log_Pos: 254 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes //这里必须是yes Slave_SQL_Running: Yes //这里必须是yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 564 Relay_Log_Space: 561 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 1360 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 11 1 row in set (0.00 sec)
从服务器2(slave2 CentOS7-5)和上面同样的配置
在主服务器上添加一个数据库school,查看两个从服务器是否可以同步获取到school数据库
主服务器添加数据库school
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | #mysql50#.mozilla | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.01 sec) mysql> create database school; //添加school数据库 Query OK, 1 row affected (0.00 sec)
在两台从服务器上查看是否同步获取到school数据库
slave1 CentOS7-2
mysql> show databases; //查看有哪些数据库 +--------------------+ | Database | +--------------------+ | information_schema | | #mysql50#.mozilla | | mysql | | performance_schema | | school | //这里就同步获取到school数据库 | test | +--------------------+ 6 rows in set (0.01 sec)
slave2 CentOS7-5
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | #mysql50#.mozilla | | mysql | | performance_schema | | school | //这里slave2也同步获取到一个school的数据库 | test | +--------------------+ 6 rows in set (0.00 sec)
到这里若是两台从服务器都能获取到school数据库,就说明主从同步已经没问题了,那么接下来就是在amoeba服务器(CentOS7-3)上部署读写分离了
由于Amoeba是java程序开发的,因此Amoeba服务器上要先安装jdk环境
[root@localhost ~]# systemctl stop firewalld.service [root@localhost ~]# setenforce 0 [root@localhost mysql]# cp jdk-6u14-linux-x64.bin /usr/local/ [root@localhost mysql]# ./jdk-6u14-linux-x64.bin 。。。省略 Do you agree to the above license terms? [yes or no] y //前面一直按Enter直到这里输入y(yes),而后就等jdk环境安装完成
而后安装Amoeba服务
[root@localhost local]# mv jdk1.6.0_14/ jdk1.6 [root@localhost local]# vim /etc/profile //添加amoeba的环境变量 //G到行尾添加 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 [root@localhost local]# source /etc/profile //刷星使环境变量当即生效 [root@localhost local]# mkdir /usr/local/amoeba //建立一个amoeba的工做目录 [root@localhost local]# tar zxvf /abc/mysql/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ //解压安装amoeba至工做目录 [root@localhost local]# chmod -R 755 amoeba/ //递归给予amoeba及子文件执行权限 [root@localhost local]# /usr/local/amoeba/bin/amoeba //检查amoeba是否安装成功 amoeba start|stop //看到这样的提示就说明amoeba服务安装完成
而后在三台MySQL服务器上添加权限开放给amoeba访问,用户使用test,密码是123123
grant all on . to test@'192.168.234.%' identified by '123123';
修改amoeba服务器的配置文件
[root@localhost amoeba]# vim conf/amoeba.xml 。。。省略 <!-- --> //删除这里,表示开启 30 <property name="user">amoeba</proper ty> //这里修改用户为以前设置的amoeba 31 <!-- --> //删除这里,表示开启 32 <property name="password">123456</pr operty> //添加密码为以前设置的密码123456 33 。。。省略 115 <property name="defaultPool">master</property> //这里修改成默认使用master主服务器 116 117 118 <property name="writePool">master</property> //容许主服务器写入 119 <property name="readPool">slaves</property> //容许从服务器读取 [root@localhost amoeba]# vim conf/dbServers.xml //修改数据库的配置文件 <!-- mysql user --> 26 <property name="user">test</property> //这里修改成test,即便用test用户去读取MySQL的数据 27 <!-- mysql pseeword //这里有一个<!--表示注释的意思,因此要删除 28 <property name="password">123123</property> //密码为前面设置的密码123123 --> //删除 <dbServer name="master" parent="abstractServer"> //修改原来的server1为master 45 <factoryConfig> 46 <!-- mysql ip --> 47 <property name="ipAddress">192.168.234.174</property> //这里改成主服务器的IP地址 48 </factoryConfig> 49 </dbServer> 50 51 <dbServer name="slave1" parent="abstractServer"> //server2改成slave1 52 <factoryConfig> 53 <!-- mysql ip --> 54 <property name="ipAddress">192.168.234.177</property> //slave1(即CentOS7-2)IP地址 55 </factoryConfig> 56 </dbServer> 57 #添加 58 <dbServer name="slave2" parent="abstractServer"> 59 <factoryConfig> 60 <!-- mysql ip --> 61 <property name="ipAddress">192.168.234.184</property> //slave2(即CentOS7-5)IP地址 62 </factoryConfig> 64 <dbServer name="slaves" virtual="true"> //服务器池名为slaves 65 <poolConfig class="com.meidusa.amoeba.server.MultipleServerP ool"> 66 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGH TBASED , 3=HA--> 67 <property name="loadbalance">1</property> 68 69 <!-- Separated by commas,such as: server1,server2,se rver1 --> 70 <property name="poolNames">slave1,slave2</property> //服务器池内的两台服务器的名称 71 </poolConfig> 72 </dbServer>
开启amoeba服务,而且检查端口是否开启
[root@localhost amoeba]# /usr/local/amoeba/bin/amoeba start & //开启amoeba服务器,而且放入后台执行 [2] 3996 [root@localhost amoeba]# log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml 2018-07-08 15:02:45,493 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0 log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf 2018-07-08 15:02:46,450 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066. //这里能够看到开始监听端口8066 2018-07-08 15:02:46,476 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:38438. ^C [root@localhost amoeba]# netstat -ntap | grep java //查看java的程序 tcp6 0 0 :::8066 :::* LISTEN 3996/java //而后就能够看到有一个8066的端口已经开启了 tcp6 0 0 127.0.0.1:38438 :::* LISTEN 3996/java tcp6 0 0 192.168.234.181:37510 192.168.234.174:3306 ESTABLISHED 3996/java tcp6 0 0 192.168.234.181:38208 192.168.234.177:3306 ESTABLISHED 3996/java tcp6 0 0 192.168.234.181:47642 192.168.234.184:3306 ESTABLISHED 3996/java
而后这里该部署的部署完成了,剩下的就是验证是否可以实现读写分离了
这里先简单说明下验证过程:先在主服务器的school库中建立一个表zyc,而后两台从服务器关闭slave,在主服务器的zyc表中插入数据1,从服务器1的zyc表(注:建立表时同步并未关闭,因此从服务器会同步生成一个zyc表)中插入数据2,从服务器2的zyc表中插入数据3,而后使用客户机Linux6-1访问amoeba服务器,会看到显示的数据会在两个从服务器的二、3数据间切换,并不会显示主服务器写入的数据1;在客户机Linux6-1上写入数据,而后只有在主MySQL服务器能查询到,两个从服务器却查看不到;最后开启两个从服务器的同步,在客户机查看数据,就会看到数据显示为21四、314间切换。
//主服务器添加表 mysql> create table zyc (id int(5),name varchar(10)); Query OK, 0 rows affected (0.03 sec) mysql> show tables; +------------------+ | Tables_in_school | +------------------+ | zyc | +------------------+ 1 row in set (0.00 sec) //两个从服务器即会同步获取表信息 #从服务器1 CentOS7-2 mysql> use school; Database changed mysql> show tables; +------------------+ | Tables_in_school | +------------------+ | zyc | +------------------+ 1 row in set (0.00 sec) mysql> stop slave; Query OK, 0 rows affected (0.00 sec) #从服务器2 CentOS7-5 mysql> use school; Database changed mysql> show tables; +------------------+ | Tables_in_school | +------------------+ | zyc | +------------------+ 1 row in set (0.01 sec) mysql> stop slave; Query OK, 0 rows affected (0.01 sec) #主服务器插入数据1 mysql> insert into zyc values (1,'zhangsan'); Query OK, 1 row affected (0.01 sec) mysql> select * from zyc; +------+----------+ | id | name | +------+----------+ | 1 | zhangsan | +------+----------+ 1 row in set (0.00 sec) #从服务器1插入数据2 mysql> insert into zyc values (2,'lisi'); Query OK, 1 row affected (0.01 sec) mysql> select * from zyc; +------+------+ | id | name | +------+------+ | 2 | lisi | +------+------+ 1 row in set (0.01 sec) #从服务器2插入数据3 mysql> insert into zyc values (3,'wangwu'); Query OK, 1 row affected (0.01 sec) mysql> select * from zyc; +------+--------+ | id | name | +------+--------+ | 3 | wangwu | +------+--------+ 1 row in set (0.00 sec) #此时使用客户机去访问amoeba服务器会看到数据只显示两个从服务器的 mysql> select * from zyc; +------+--------+ | id | name | +------+--------+ | 2 | lisi | +------+--------+ 1 row in set (0.00 sec) mysql> select * from zyc; +------+--------+ | id | name | +------+--------+ | 3 | wangwu | +------+--------+ 1 row in set (0.00 sec) #而后打开两个从服务器的同步,在客户机插入数据4 mysql> insert into zyc values (4,'zhaoliu'); Query OK, 1 row affected (0.01 sec) select * from zyc; +------+----------+ | id | name | +------+----------+ | 2 | lisi | +------+----------+ | 1 | zhangsan | +------+----------+ | 4 | zhaoliu | +------+----------+ select * from zyc; +------+----------+ | id | name | +------+----------+ | 3 | wangwu | +------+----------+ | 1 | zhangsan | +------+----------+ | 4 | zhaoliu | +------+----------+
最后的实验结论为:主服务器负责写入数据;从服务器负责读取数据;且两个从服务器会与主服务器进行同步,而两个从服务器间则不会同步
若是您实验到最后获得的也是这样的结果,那么恭喜您读写分离的实验您成功了!
这样就实现了MySQL的读写分离及主从同步