基于amoeba实现mysql数据库的读写分离/负载均衡
时间:2022-03-14 02:24
一、Amoeba的简述:[来自百度百科]
Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy。它集中地响应应用的请求,依据用户事先设置的规则,将SQL请求发送到特定的数据库上执行。基于此可以实现负载均衡、读写分离、高可用性等需求。与MySQL官方的MySQL Proxy相比,作者强调的是amoeba配置的方便(基于XML的配置文件,用SQLJEP语法书写规则,比基于lua脚本的MySQL Proxy简单)。
Amoeba相当于一个SQL请求的路由器,目的是为负载均衡、读写分离、高可用性提供机制,而不是完全实现它们。用户需要结合使用MySQL的 Replication等机制来实现副本同步等功能。amoeba对底层数据库连接管理和路由实现也采用了可插拨的机制,第三方可以开发更高级的策略类来替代作者的实现。这个程序总体上比较符合KISS原则的思想。目前 Amoeba 已在很多 企业的生产线上面使用。
二、Amoeba解决的问题及目前存在的劣势:
1.主要解决的问题:
(1). 数据切分后复杂数据源整合
(2). 提供数据切分规则并降低数据切分规则给数据库带来的影响
(3). 降低数据库与客户端连接
(4). 读写分离路由
2.劣势:
(1).目前还不支持事务
(2).暂时不支持存储过程(近期会支持)
(3).不适合从amoeba导数据的场景或者对大数据量查询的query并不合适(比如一次请求返回10w以上甚至更多数据的场合)
(4).暂时不支持分库分表,amoeba目前只做到分数据库实例,每个被切分的节点需要保持库表结构一致
三、基于 Amoeba 实现mysql数据库读写分离的配置
1.测试环境,amoeba的要求,软件提供,简要原理图:
(1).测试环境:
红帽6.3系统
amoeba服务器地址:192.168.1.104
mysql数据库:192.168.1.102:3306(master -- rw)/192.168.1.100:3306(slave -- r)
注:为了方便测试读写分离,我这里是不配置主从。
(2).amoeba的要求:
Amoeba 是基于 java 开发,所以如果要运行 Amoeba,必须先安装 jdk 以便可以运行
(3).软件下载:[大家可以到 (开源中国)下载]
当前测试环境使用的amoeba软件下载地址:
amoeba参考手册:
amoeba项目代码:
(4).简要原理图:
2.我们这里将amoeba相关软件放在/tmp目录下,这里我们先配置JDK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
[root @centos tmp]
[root @centos tmp]
[root @centos local ]
[root @centos local ]
[root @centos local ]
[root @centos local ]
[root @centos local ]
[root @centos java]
[root @centos java]
export JAVA_HOME=/usr/locla/java
export PATH= $JAVA_HOME /bin: $JAVA_HOME /jre/bin: $PATH
[root @centos java]
|
3.配置amoeba中的dbServer.xml(后端mysql 服务器连接配置)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
[root@centos java]
[root@centos tmp]
[root@centos tmp]
[root@centos tmp]
[root@centos amoeba]
[root@centos conf]
.........................(省略)
<dbServer name= "abstractServer" abstractive= "true" >
<factoryConfig class= "com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory" >
<property name= "manager" >${defaultManager}< /property >
<property name= "sendBufferSize" >64< /property >
<property name= "receiveBufferSize" >128< /property >
<!-- mysql port -->
<property name= "port" >3306< /property >
<!-- mysql schema -->
<property name= "schema" >kongzhong< /property >
<!-- mysql user -->
<property name= "user" >kongzhong123< /property >
<!-- mysql password -->
<property name= "password" >kongzhong123< /property >
< /factoryConfig >
<poolConfig class= "com.meidusa.amoeba.net.poolable.PoolableObjectPool" >
<property name= "maxActive" >500< /property >
<property name= "maxIdle" >500< /property >
<property name= "minIdle" >10< /property >
<property name= "minEvictableIdleTimeMillis" >600000< /property >
<property name= "timeBetweenEvictionRunsMillis" >600000< /property >
<property name= "testOnBorrow" > true < /property >
<property name= "testOnReturn" > true < /property >
<property name= "testWhileIdle" > true < /property >
< /poolConfig >
< /dbServer >
<dbServer name= "master" parent= "abstractServer" >
<factoryConfig>
<!-- mysql ip -->
<property name= "ipAddress" >192.168.1.102< /property >
< /factoryConfig >
< /dbServer >
<dbServer name= "slave" parent= "abstractServer" >
<factoryConfig>
<!-- mysql ip -->
<property name= "ipAddress" >192.168.1.100< /property >
< /factoryConfig >
< /dbServer >
<dbServer name= "ReadPool" virtual= "true" >
<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" >slave< /property >
< /poolConfig >
< /dbServer >
< /amoeba :dbServers>
|
4. 配置 Amoeba 监听端口[amoeba.xml]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
[root @centos conf]
.........................(省略)
<proxy>
<!-- service class must implements com.meidusa.amoeba.service.Service -->
<service name= "Amoeba for Mysql" class= "com.meidusa.amoeba.net.ServerableConnectionManager" >
<!-- port -->
<property name= "port" >3306</property>
<!-- bind ipAddress -->
<!--
<property name= "ipAddress" >127.0.0.1</property>
-->
.........................(省略)
<property name= "authenticator" >
<bean class= "com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator" >
<property name= "user" >kongzhong</property>
<property name= "password" >kongzhong</property>
<property name= "filter" >
<bean class= "com.meidusa.amoeba.server.IPAccessController" >
<property name= "ipFile" >${amoeba.home}/conf/access_list.conf</property>
</bean>
</property>
</bean>
</property>
</service>
.........................(省略)
<queryRouter class= "com.meidusa.amoeba.mysql.parser.MysqlQueryRouter" >
<property name= "ruleLoader" >
<bean class= "com.meidusa.amoeba.route.TableRuleFileLoader" >
<property name= "ruleFile" >${amoeba.home}/conf/rule.xml</property>
<property name= "functionFile" >${amoeba.home}/conf/ruleFunctionMap.xml</property>
</bean>
</property>
<property name= "sqlFunctionFile" >${amoeba.home}/conf/functionMap.xml</property>
<property name= "LRUMapSize" >1500</property>
<property name= "defaultPool" >master</property>
<!-- -->
<property name= "writePool" >master</property>
<property name= "readPool" >ReadPool</property>
<property name= "needParse" >true</property>
</queryRouter>
|
5. 配置amoeba及JAVA的环境变量
1
2
3
4
5
|
[root @centos conf]
JAVA_HOME=/usr/locla/java
AMOEBA_HOME=/usr/ local /amoeba
export PATH= $PATH : $AMOEBA_HOME /bin: $JAVA_HOME /bin: $JAVA_HOME /jre/bin
[root @centos conf]
|
6.启动amoeba测试
1
2
3
4
5
6
|
[root @centos conf]
[root @centos conf]
[root @centos conf]
|
7.在两台数据库做刚才设置中的相应操作
(1).在主DB server上操作
1
2
3
4
5
6
7
8
9
10
|
mysql> create database kongzhong;
mysql> use kongzhong
mysql> create table t1(name varchar(10));
mysql> insert into t1 values ( ‘102‘ );
mysql> grant all privileges on kongzhong.* to ‘kongzhong123‘ @ ‘192.168.1.104‘ identified by ‘kongzhong123‘ ;
mysql> flush privileges;
|
(2).在从DB server上操作
1
2
3
4
5
6
7
8
9
10
|
mysql> create database kongzhong;
mysql> use kongzhong
mysql> create table t1(name varchar(10));
mysql> insert into t1 values ( ‘100‘ );
mysql> grant all privileges on kongzhong.* to ‘kongzhong123‘ @ ‘192.168.1.104‘ identified by ‘kongzhong123‘ ;
mysql> flush privileges;
|
8.在任何一台机器上登陆测试,这里的ip地址指向amoeba所在服务器的ip地址
1
2
3
4
|
[root @client102 ~]
[root @client100 ~]
[root @client104 ~]
|
9.遇到的问题
(1).报错1:
1
2
3
4
5
6
7
8
9
10
11
|
The stack size specified is too small, Specify at least 160k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit .
解决方法:
[root @centos bin]
[root @centos amoeba]
将下面这行
DEFAULT_OPTS= "-server -Xms1024m -Xmx1024m -Xss128k"
修改为:
DEFAULT_OPTS= "-server -Xms256m -Xmx256m -Xss256k"
|
(2).报错2:
1
2
3
4
|
Error: JAVA_HOME environment variable is not set.
解决方法:
[root @centos local ]
[root @centos local ]
|
10.需要注意的问题,思路延伸
(1).取消日志生成,不然磁盘容易爆满
1
2
3
4
5
|
[root @centos conf]
修改log4j.xml 取消日志文件生成(太大了,磁盘很容易满)
<param name= "file" value= "${amoeba.home}/logs/project.log" />
改成
<param name= "file" value= "<![CDATA[${amoeba.home}/logs/project.log>/dev/null]]>" />
|
(2).性能优化
1
2
3
4
|
[root @centos amoeba]
DEFAULT_OPTS= "-server -Xms256m -Xmx256m -Xss128k"
改成
DEFAULT_OPTS= "-server -Xms512m -Xmx512m -Xmn100m -Xss1204k"
|