Author:andy.feng(FH.CN)
Email:[email protected]
Blog : http://linuxguest.51cto.com
Data:2011/6/2
Amoeba开发博客:http://amoeba.meidusa.com/wordpress/
Amoeba官方手册:http://docs.hexnova.org/amoeba/index.html
Amoeba项目代码:http://sourceforge.net/projects/amoeba/files/
推荐阅读PDF>>>
目录
Amoeba安装手册 1
Amoeba简介 2
本手册内容简介 3
开始安装 3
一、下载amoeba软件 3
二、安装amoeba依耐关系 3
安装java支持 3
配置amoeba环境变量 4
测试jdk和AMOEBA_HOME是否设置成功 4
三、安装amoeba软件 4
四、配置amoeba读写分离,两个slave读负载均衡 4
配置dbServers.xml 4
配置amoeba.xml 6
启动amoeba 7
五、测试amoeba读写分离 7
六、优化amoeba 9
一、优化amoeba-mysql-mmm架构。 9
二、优化amoeba配置 10
七、压力测试 11
八、将discuz转移到amoeba-mysql-mmm架构上 11
AMOEBA简介
Amoeba(变形虫)项目,该开源框架于2008年 开始发布一款 Amoeba for Mysql软件。这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的 时候充当SQL路由功能,专注于分布式数据库代理层(Database Proxy)开发。座落与 Client、DB Server(s)之间,对客户端透明。具有负载均衡、高可用性、SQL 过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。 通过Amoeba你能够完成多数据源的高可用、负载均衡、数据切片的功能,目前Amoeba已在很多 企业的生产线上面使用。
本手册内容简介
我们在安装完mysql-mmm的架构(参考我的文章《mysql-mmm-2.2.1-install》)上完成amoeba的安装,功能主要实现读写分离,在两台slave上实现读负载均衡。本手册重点是配置,而不是讲解原理,原理请参见官方手册。
安装环境和mysql-mmm-2.2.1相同,也是RHEL5.4,eth1的IP地址是10.1.1.12,就是mysql-mmm-2.2.1的mmm-monitor机器。不清楚环境的读者,请先阅读mysql-mmm-2.2.1-install文档。
开始安装
一、下载AMOEBA软件
#mkdir /usr/local/amoeba/
#cd /usr/local/amoeba/
#wget http://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz/download
#md5sum amoeba-mysql-binary-2.1.0-RC5.tar.gz
44f6708652a46f28a95338f35f5d4083 amoeba-mysql-binary-2.1.0-RC5.tar.gz
二、安装AMOEBA依耐关系
安装JAVA支持
# java -version
java version "1.4.2"
gij (GNU libgcj) version 4.1.2 20080704 (Red Hat 4.1.2-46)
amoeba推荐的jdk是1.5或者1.6,所以我们升级到1.6.
下载jdk
http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u25-download-346242.html
#mkdir /soft && cd /soft
#wget http://download.oracle.com/otn-pub/java/jdk/6u25-b06/jdk-6u25-linux-i586.bin
安装jdk
# chmod 755 jdk-6u25-linux-i586.bin
# ./jdk-6u25-linux-i586.bin
# mv jdk1.6.0_25/ /usr/local/jdk
配置jdk
#vim /etc/profile
在文件最后添加如下内容
######for java
#export JAVA_HOM=/usr/local/jdk
#CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#export PATH=$JAVA_HOME/bin: $PATH
#export PATH=$PATH:/usr/local/jdk/bin
JAVA_HOME=/usr/local/jdk
PATH=$JAVA_HOME/bin:$PATH
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME PATH CLASSPATH
配置AMOEBA环境变量
#vim /etc/profile
在结尾添加如下内容
#####for amoeba
AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
# . /etc/profile
测试JDK和AMOEBA_HOME是否设置成功
# java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) Client VM (build 20.0-b11, mixed mode, sharing
# cd $AMOEBA_HOME && pwd
/usr/local/amoeba
三、安装AMOEBA软件
# tar -zxvf amoeba-mysql-binary-2.1.0-RC5.tar.gz
# cd bin/
#chmod 755 *
# amoeba //如果显示下面的内容,证明amoeba的依耐关系安装完成
amoeba start|stop
四、配置AMOEBA读写分离,两个SLAVE读负载均衡
# cd $AMOEBA_HOME/conf
配置DBSERVERS.XML
# vim dbServers.xml
修改第20行
原 <property name="port">3306</property>
改 <property name="port">9188</property>//mysql服务器的通用端口
修改26行
原 <property name="user">root</property>
改 <property name="user">andy</property>//mysql服务器的通用用户名
修改28,29,,30行
原
28 <!-- mysql password
29 <property name="password">password</property>
30 -->
改 //删除28和30行,原来的第29行变成第28行
28 <property name="password">andy</property>//mysql服务器的通用用户密码
复制一下代码,并在此代码下面粘贴两次
42 <dbServer name="server1" parent="abstractServer">
43 <factoryConfig>
44 <!-- mysql ip -->
45 <property name="ipAddress">127.0.0.1</property>
46 </factoryConfig>
47 </dbServer>
修改后的效果如下:添加两个db服务器定义,并且分别设置三个mysql server的ip地址,ip地址使用的是mysql-mmm的虚拟IP。
42 <dbServer name="server1" parent="abstractServer">
43 <factoryConfig>
44 <!-- mysql ip -->
45 <property name="ipAddress">10.1.1.20</property>
46 </factoryConfig>
47 </dbServer>
48
49 <dbServer name="server2" parent="abstractServer">
50 <factoryConfig>
51 <!-- mysql ip -->
52 <property name="ipAddress">10.1.1.21</property>
53 </factoryConfig>
54 </dbServer>
55
56 <dbServer name="server3" parent="abstractServer">
57 <factoryConfig>
58 <!-- mysql ip -->
59 <property name="ipAddress">10.1.1.22</property>
60 </factoryConfig>
61 </dbServer>
注意:这里要引入一个细节
# mmm_control show
db1(10.1.1.15) master/ONLINE. Roles: reader(10.1.1.23), writer(10.1.1.20)
db2(10.1.1.14) master/ONLINE. Roles: reader(10.1.1.21)
db3(10.1.1.13) slave/ONLINE. Roles: reader(10.1.1.22)
# Role writer is assigned to it's preferred host db1.
上面的server2和server3使用的是db2和db3的reader ip,而server1使用的writer的ip。
修改配置文件的最下方
64 <dbServer name="ReadPool" virtual="true"> //定义虚拟节点池的名字
65 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
66 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
67 <property name="loadbalance">1</property> //负载均衡算法
68
69 <!-- Separated by commas,such as: server1,server2,server1 -->
70 <property name="poolNames">server2,server3</property> //虚拟节点池的成员
71 </poolConfig>
72 </dbServer>
配置AMOEBA.XML
# vim amoeba.xml
11 <property name="port">8066</property> //amoeba监听端口,不用修改
修改第30行
原 <property name="user">root</property>
改 <property name="user">amoeba</property>//修改amoeba的用户名为amoeba
修改第32行
原 <property name="password"></property>
改 <property name="password">amoeba</property>//修改amoeba的用户名为amoeba
查找queryRouter字段,修改成如下:
106 <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
107 <property name="ruleLoader">
108 <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
109 <property name="ruleFile">${amoeba.home}/conf/rule.xml</property>
110 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
111 </bean>
112 </property>
113 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
114 <property name="LRUMapSize">1500</property>
115 <property name="defaultPool">server1</property>
116
117 <property name="writePool">server1</property>
118 <property name="readPool">ReadPool</property>
119 <property name="needParse">true</property>
120 </queryRouter>
启动AMOEBA
# amoeba start //启动amoeba
log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml
2011-06-02 19:04:05,491 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.1.0-RC5
log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf
2011-06-02 19:04:08,874 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066.
2011-06-02 19:04:08,876 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:5234.
# netstat -tulnp | grep java //检测是否启动成功
tcp 0 0 :::8066 :::* LISTEN 28836/java
tcp 0 0 ::ffff:127.0.0.1:5305 :::* LISTEN 28836/java
五、测试AMOEBA读写分离
测试流程:
1、 确保10.1.1.20,10.1.1.21,10.1.1.22不在同一台机器上,然后关闭mmm_monitor。
# mmm_control show
db1(10.1.1.15) master/ONLINE. Roles: reader(10.1.1.23), writer(10.1.1.20)
db2(10.1.1.14) master/ONLINE. Roles: reader(10.1.1.21)
db3(10.1.1.13) slave/ONLINE. Roles: reader(10.1.1.22)
# /etc/init.d/mysql-mmm-monitor stop
检查db1,db2,db3上的IP地址
db1:
# ip add
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:80:3f:03:46:c5 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.15/24 brd 10.1.1.255 scope global eth1
inet 10.1.1.20/32 scope global eth1
inet 10.1.1.23/32 scope global eth1
inet6 fe80::280:3fff:fe03:46c5/64 scope link
valid_lft forever preferred_lft forever
4: sit0: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
db2:
# ip add
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:80:3f:03:46:51 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.14/24 brd 10.1.1.255 scope global eth1
inet 10.1.1.21/32 scope global eth1
inet6 fe80::280:3fff:fe03:4651/64 scope link
valid_lft forever preferred_lft forever
4: sit0: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
db3:
# ip add
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:80:3f:03:47:cf brd ff:ff:ff:ff:ff:ff
inet 10.1.1.13/24 brd 10.1.1.255 scope global eth1
inet 10.1.1.22/32 scope global eth1
inet6 fe80::280:3fff:fe03:47cf/64 scope link
valid_lft forever preferred_lft forever
4: sit0: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
在db2和db3上停止mysql 复制
db2:
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
db3:
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
2、 通过amoeba访问数据库,在test中建立amoeba表
amoeba:
# mysql -uamoeba -p -P8066 -h10.1.1.12 //密码也是amoeba
mysql>use test;
mysql> create table amoeba (id int(11),name varchar(32));
mysql> insert into amoeba values (1,'db1');
db2:
#mysql
mysql>use test;
mysql> create table amoeba (id int(11),name varchar(32));
mysql> insert into amoeba values (2,'db2');
db3:
mysql>use test;
mysql> create table amoeba (id int(11),name varchar(32));
mysql> insert into amoeba values (3,'db3');
amoeba:
查询刚才建立的amoeba表
mysql> select * from amoeba;
+------+------+
| id | name |
+------+------+
| 2 | db2 |
+------+------+
1 row in set (0.00 sec)
mysql> select * from amoeba;
+------+------+
| id | name |
+------+------+
| 3 | db3 |
+------+------+
1 row in set (0.01 sec)
mysql> select * from amoeba;
+------+------+
| id | name |
+------+------+
| 2 | db2 |
+------+------+
1 row in set (0.00 sec)
mysql> select * from amoeba;
+------+------+
| id | name |
+------+------+
| 3 | db3 |
+------+------+
1 row in set (0.00 sec)
查询是很均匀的分配到db2和db3上。
到此读写分离和读负债均衡配置功能基本完成。
六、优化AMOEBA
一、优化AMOEBA-MYSQL-MMM架构。
由于之前我们为了方便测试,所以架构并不优化,存在以下问题。
当db1,db2,db3中出现数次offline后,reader的ip地址可能变乱,如下
# mmm_control show
db1(10.1.1.15) master/ONLINE. Roles: reader(10.1.1.22), writer(10.1.1.20)
db2(10.1.1.14) master/ONLINE. Roles: reader(10.1.1.23)
db3(10.1.1.13) slave/ONLINE. Roles: reader(10.1.1.21)
针对这种情况,db1的压力就会更大,而db2却没有任何压力,针对这种情况有以下三种方案
方案一、可以通过mmm_contor来调整ip地址,让10.1.1.22和10.1.1.21,10.1.1.20分配在不同的机器上。
缺点:需手工维护,保证db1上没有10.1.1.21和10.1.1.22这两个IP
优点:压力负载均衡效果好
方案二、调整read库,放入三个reader虚拟IP
缺点:不过相对来说10.1.1.20的压力会大一些,
优点:纯自动化切换,受db offline影响最小。
方案三、综合方案一和方案二,调整read库,放入三个reader的虚拟ip,将db3的虚拟ip权重调整的高于两个master。
缺点:需要手工保证db3使用权重较高的虚拟ip,
优点:压力负载均衡效果好,受db offline影响小
根据自己的情况来选择以上三种方案吧。如果服务器很稳定,就选择方案一,如果经常切换就方案二,如果master之间经常切换,slave很少切换就选择方案三。
我们这里就选择方案一,暂时不对架构调整。
二、优化AMOEBA配置
我们对配置做一个简单的优化、毕竟优化这个东西是一门长期而且有难度的工作,需要在一边使用一边更具自己的实际情况制定出合适的优化方案,以后有机会单独出一篇amoeba优化的文章。
amoeba优化注意以下几点:
1、 查询的类型,是属于并发少,但是语句复杂的查询,还是属于并发高,语句不复杂的查询。
2、 查询的结果,查询结果返回的数据量大小
3、 最终的优化效果取决于后端真实mysqldb的配置,比如并发数,每个并发的缓存分配等,以及mysqldb自身的优化
简单的优化配置:
1、 修改amoeba启动参数,增加JAVA虚拟机的内存
修改amoeba执行程序,查找DEFAULT_OPTS,修改为以下内容:
DEFAULT_OPTS="-server -Xms1024m -Xmx1024m -Xss256k"
2、 amoeba.xml中关于多线程和网络的优化
vim amoeba.xml
<property name="readThreadPoolSize">500</property>
<property name="clientSideThreadPoolSize">500</property>
<property name="serverSideThreadPoolSize">500</property>
<property name="sendBufferSize">256</property>
<property name="receiveBufferSize">128</property>
这些值对并发的影响到底如何,需要测试。这里 只是根据手册的描述来修改。
3、 amoeba.xml中还有一个处理客户端连接和网络信息使用CPU核数的配置,不过默认配置是主机拥有的CPU核的数量,一般不用修改,如果你的amoeba负载较高,并且机器上还有其他服务,你就可以降低这个配置,避免系统或者其他服务没有资源,或者出现资源争抢,从而导致整理的处理能力下降。
查找amoeba.xml文件中connectionManagerList关键字,修改
<!--
default value is avaliable Processors
<property name="processors">5</property>
-->取消注释,并设置processors数量。
七、压力测试
我们这里使用amoeba自带的benchmark工具。
1、 编辑查询规则文件。
# cat /tmp/amoeba_test.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties version="1.0">
<entry key="class">com.meidusa.amoeba.mysql.net.packet.QueryCommandPacket</entry>
<entry key="command">3</entry>
<entry key="query"><![CDATA[
select * mysql.user;
]]>
</entry>
</properties>
2、# ./benchmark –help
3、# ./benchmark -P 8066 -c 10 -f /tmp/amoeba_test.xml -h 10.1.1.12 -n 10000 -u amoeba -p amoeba
你可以通过改变并发度来查看并发对性能的影响,在找到并发度的瓶颈的时候,在调整原来的参数,寻找最佳的配置参数。
注意:
1、 在调整并发度的时候,后端mysqldb的最大连接总和必须大于benchmark的并发度,不然会出现mysql拒绝服务器的问题。
2、 如果你一台机器能够完全满足应用,就没有必要使用amoeba,应为使用amoeba后,虽然负载上能够得到很大的扩展,但是效率上比直连大打折扣,这个就是有利必有弊吧。
八、将DISCUZ转移到AMOEBA-MYSQL-MMM架构上
将已经在运行的discuz论坛数据库切换到amoeba-mysql-mmm环境上。
步骤:
1、 在mysql-mmm的writer上建立discuz和ucenter两个数据库(也就是你网站或者论坛使用到得数据名称,前提是数据库默认字符集必须和原来的相同)
2、 关闭原来的论坛,导出数据库数据。
3、 把数据导入到刚才新建立的两个数据库中,并查看另外一个master和slave是否同步,等待同步完成。
4、 修改discuz和ucenter数据库配置,指向amoeba。
5、 测试、完成。
本文出自 “fenghao.cn's Soft..” 博客,请务必保留此出处http://linuxguest.blog.51cto.com/195664/584788