用amoeba实现Mysql读写分离
Amoeba 是什么:
Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。
主要解决:
• 降低 数据切分带来的复杂多数据库结构
• 提供切分规则并降低 数据切分规则 给应用带来的影响
• 降低db 与客户端的连接数
• 读写分离
这里我们主要利用amoeba实现数据库的读写分离功能
实验环境:rhel 6.5 mysql 5.7
Master mysql 172.25.64.1
Slave mysql 172.25.64.2
Amoeba 172.25.64.3
准备条件:首先我们要实现mysql的主动复制,然后因为amoeba框架是居于jdk开发的,所以我们需要安装jdk环境。
在amoeba主机上面:
安装jdk
tar zxf jdk-7u79-linux-x64.tar.gz -C /usr/local/ ##解压到/usr/local目录下面
cd /usr/local/
ln -s jdk1.7.0_79/ java ##为了方便,做一个软连接
Vim /etc/profile ##系统路径设置
79 export JAVA_HOME=/usr/local/java
80 export CLASSPATH=.:JAVA_HOME/lib:JAVA_HOME/jre/lib
81 export PATH=PATH:JAVA_HOME/bin
source /etc/profile ##加载路径
java -version ##查看是否安装成功
unzip amoeba-mysql-3.0.5-RC-distribution.zip
cd amoeba-mysql-3.0.5-RC
Amoeba的配置文件在本环境下位于/usr/local/amoeba/conf目录下。配置文件比较多,但是仅仅使用读写分离功能,只需配置两个文件即可,分别是dbServers.xml和amoeba.xml
cd conf/ ##配置文件存放位置
vim dbServers.xml
1
2
3
4 <amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">
5
6
12
13 <dbServer name="abstractServer" abstractive="true">
14 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServ erConnectionFactory">
15 <property name="connectionManager">${defaultManager} property>
16 <property name="sendBufferSize">64property>
17 <property name="receiveBufferSize">128property>
18
19
20 <property name="port">3306property> ##设置amoeba要连接数据库的端口,默认是3306
21
22
23 <property name="schema">testdbproperty> ###设置缺省的数据库,当连接amoeba时,操作表必须显式的指定数据库名,即采用dbname.tablename的方式,不支持 use dbname指定缺省库,因为操作会调度到各个后端dbserver
24
25
26 <property name="user">test1property> ###设置amoeba连接后端数据库服务器的账号和密码,因此需要在所有后端数据库上创建该用户,并授权amoeba服务器可连接
27
28 <property name="password">YIYI+bushe24property> ##amoeba连接后端数据库服务器的密码,因为5.7对数据库的密码的健壮性有要求,所以我们设置密码的时候需要考虑密码的健壮性。
29 factoryConfig>
30
31 <poolConfig class="com.meidusa.toolkit.common.poolable.Poola bleObjectPool">
32 <property name="maxActive">500property> ##最大连接数
33 <property name="maxIdle">500property> ##最大空闲连接数
34 <property name="minIdle">1property> ##最新空闲连接数
35 <property name="minEvictableIdleTimeMillis">600000 property>
36 <property name="timeBetweenEvictionRunsMillis">60000 0property>
37 <property name="testOnBorrow">trueproperty>
38 <property name="testOnReturn">trueproperty>
39 <property name="testWhileIdle">trueproperty>
40 poolConfig>
41 dbServer>
42
43 <dbServer name="writedb" parent="abstractServer"> ##设置后端可写的dbserver,命名为writedb
44 <factoryConfig>
45
46 <property name="ipAddress">172.25.64.1property> ##可以进行写操作的数据库的ip地址
47 factoryConfig>
48 dbServer>
49
50 <dbServer name="slave" parent="abstractServer"> ##设置后端可读的dbserver
51 <factoryConfig>
52
53 <property name="ipAddress">172.25.64.2property> ##可以进行读操作的数据库的ip地址
54 factoryConfig>
55 dbServer>
56
57 <dbServer name="myslave" virtual="true"> ###设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为myslave
58 <poolConfig class="com.meidusa.amoeba.server.MultipleServerP ool">
59
60 <property name="loadbalance">1property> ##调度算法
61
62
63 <property name="poolNames">slaveproperty> ##myslave组成员,是上面所定义的dbserver读操作
64 poolConfig>
65 dbServer>
66
67 amoeba:dbServers>
Vim amoeba.xml
1
2
3
4 <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
5
6 <proxy>
7
8
9 <service name="Amoeba for Mysql" class="com.meidusa.amoeba.mysql.server.MySQLService">
10
11 <property name="port">8066property> ##amoeba监听的端口,默认是8066
12
13 ##监听的接口
14
17
18 <property name="connectionFactory">
19 <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">
20 <property name="sendBufferSize">128property>
21 <property name="receiveBufferSize">64property>
22 bean>
23 property>
24
25 <property name="authenticateProvider">
26 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
27
28 <property name="user">rootproperty> ##提供客户端连接amoeba时需要使用这里设定的账号 (这里的账号密码和amoeba连接后端数据库服务器的密码无关)
29
30 <property name="password">123456property>
31
32 <property name="filter">
33 <bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">
34 <property name="ipFile">${amoeba.home}/conf/access_list.confproperty>
35 bean>
36 property>
37 bean>
38 property>
39
40 service>
41
42 <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">
43
44
45 <property name="executeThreadSize">128property>
46
47
48 <property name="statementCacheSize">500property>
49
50
51 <property name="serverCharset">utf8property>
52
53
54 <property name="queryTimeout">60property>
55 runtime>
56
57 proxy>
58
59
63 <connectionManagerList>
64 <connectionManager name="defaultManager" class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper">
65 <property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManagerproperty>
66 connectionManager>
67 connectionManagerList>
68
69
70 <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">
71 <property name="configFile">${amoeba.home}/conf/dbServers.xmlproperty>
72 dbServerLoader>
73
74 <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
75 <property name="ruleLoader">
76 <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
77 <property name="ruleFile">${amoeba.home}/conf/rule.xmlproperty>
78 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xmlproperty>
79 bean>
80 property>
81 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xmlproperty>
82 <property name="LRUMapSize">1500property>
83 <property name="defaultPool">writedbproperty> ##设置amoeba默认的池,这里设置为writedb
84
85
86 <property name="writePool">writedbproperty> ##这两个选项默认是注销掉的,需要取消注释,这里用来指定前面定义好的两个读写池。
87 <property name="readPool">myslaveproperty>
88
89 <property name="needParse">trueproperty>
90 queryRouter>
91 amoeba:configuration>
Master:
mysql> GRANT ALL ON testdb.* TO ‘test1’@’172.25.64.3’ IDENTIFIED BY ‘YIYI+bushe24’;
Query OK, 0 rows affected, 1 warning (0.12 sec)
Slave:
mysql> GRANT ALL ON testdb.* TO ‘test1’@’172.25.64.3’ IDENTIFIED BY ‘YIYI+bushe24’;
Query OK, 0 rows affected, 1 warning (0.00 sec)
[root@server3 amoeba]# bin/launcher
The stack size specified is too small, Specify at least 228k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
错误文字上看,应该是由于stack size太小,导致JVM启动失败,修改jvm.properties文件JVM_OPTIONS参数
vim jvm.properties
32 JVM_OPTIONS=”-server -Xms1024m -Xmx1024m -Xss256k -XX:PermSize=16m -XX:MaxPe rmSize=96m” ##将这一行改成这样
然后再次启动。
[root@server3 amoeba]# netstat -unlpt | grep java ##查看监听的端口
tcp 0 0 :::8066 :::* LISTEN 1506/java
远程登陆mysql客户端通过指定amoeba配置文件中指定的用户名、密码、和端口以及amoeba服务器ip地址链接mysql数据库
[root@server1 ~]# mysql -h172.25.64.3 -uroot -P8066 -p ##用客户端进行远程登陆,然后创建testdb数据库,并且插入数据。
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 21622515
Server version: 5.1.45-mysql-amoeba-proxy-3.0.4-BETA MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| testdb |
+——————–+
2 rows in set (0.00 sec)
mysql> use testdb;
Database changed
mysql> create table bushe(
-> name varchar(15) not null,
-> pass varchar(15) not null);
Query OK, 0 rows affected (1.69 sec)
mysql> insert into bushe values(‘yiyi’,’249494’);
Query OK, 1 row affected (0.25 sec)
mysql> select * from bushe;
+——+——–+
| name | pass |
+——+——–+
| yiyi | 249494 |
+——+——–+
1 row in set (0.00 sec)
然后分别在master和slave上面进行查看数据,我们可以在master和slave上面查看到我们远程登陆amoeba插入的数据。
接下来我们stop master 的mysql,这样我们把写服务器停掉之后,那么我们通过登陆amoeba将只能进行查询操作,而不能进行插入操作了。
[root@server1 ~]# /etc/init.d/mysqld stop
Stopping mysqld: [ OK ]
[root@server1 ~]# mysql -h172.25.64.3 -uroot -P8066 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 21622515
Server version: 5.1.45-mysql-amoeba-proxy-3.0.4-BETA MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> use testdb;
Database changed
mysql> insert into bushe values(‘user1’,’1111’);
ERROR 1044 (42000): Amoeba could not connect to MySQL server[172.25.64.1:3306],Connection refused ##我们可以看到不能进行插入操作了,连接被拒绝
mysql> select * from bushe; ##因为slave读服务器还好着,所以我们可以进行读操作。
+——+——–+
| name | pass |
+——+——–+
| yiyi | 249494 |
+——+——–+
1 row in set (0.00 sec)
然后我们再启动master mysql stop slave mysql 继续测试.
Master /etc/init.d/mysqld start
Slave /etc/init.d/mysqld stop
然后我们继续用客户端远程登陆amoeba服务器进行测试:
[root@server1 ~]# mysql -h172.25.64.3 -uroot -P8066 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 21622515
Server version: 5.1.45-mysql-amoeba-proxy-3.0.4-BETA
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| testdb |
+——————–+
2 rows in set (0.01 sec)
mysql> use testdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> insert into bushe values(‘user2’,’2222’); ##这里我们可以看到插入成功
Query OK, 1 row affected (0.25 sec)
mysql> select * from bushe;
ERROR 1044 (42000): poolName=myslave, no valid pools ##查询失败,这是因为我们把dbserver中的slave停掉了,然后虚拟组中没有可用的池了,所以查询失败
mysql>