安装JDK环境 下载jdk1.5或者更新版本,地址 http://java.sun.com/javase/downloads/index.jsp 我用的是:jdk-6u20-linux-i586-rpm.bin 在Amoeba server上执行 chmod +x jdk-6u20-linux-i586-rpm.bin ./ jdk-6u20-linux-i586-rpm.bin ##然后按n次空格键,然后输入yes就可以了!
ln -s /usr/java/jdk1.6.0_20/ /usr/java/jdk1.6 vi /etc/profile #添加如下两行内容 export JAVA_HOME=/usr/java/jdk1.6 export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
#执行下面的命令使更改的内容生效 source /etc/profile
安装amoeba-mysql 下载amoeba-mysql,目前最新版本为amoeba-mysql-1.3.1-BETA.zip mkdir /usr/local/amoeba/ wget http://blogimg.chinaunix.net/blog/upfile2/101027160252.zip unzip 101027160252.zip
配置文件位于conf目录下,执行文件位于bin目录下,解压后发现bin目录下的启动文件没有可执行权限,请执行:chmod -R +x /usr/local/amoeba/bin/
Amoeba For MySQL 的使用非常简单,所有的配置文件都是标准的XML 文件,总共有四个配置文件。分别为: ◆ amoeba.xml:主配置文件,配置所有数据源以及Amoeba 自身的参数设置;实现主从的话配置这个文件就可以了; ◆ rule.xml:配置所有Query 路由规则的信息; ◆ functionMap.xml:配置用于解析Query 中的函数所对应的Java 实现类; ◆ rullFunctionMap.xml:配置路由规则中需要使用到的特定函数的实现类;
下面我们就来通过更改amoeba.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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 <?xml version ="1.0" encoding="gbk" ?> <!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd"> <amoeba:configuration xmlns:amoeba ="http://amoeba.meidusa.com/" > <server> <!-- proxy server绑定的端口 --> <property name ="port" >8066 </property> <!-- proxy server绑定的IP --> <property name ="ipAddress" >192.168 .1.110 </property> <!-- proxy server net IO Read thread size --> <property name ="readThreadPoolSize" >20 </property> <!-- proxy server client process thread size --> <property name ="clientSideThreadPoolSize" >30 </property> <!-- mysql server data packet process thread size --> <property name ="serverSideThreadPoolSize" >30 </property> <!-- socket Send and receive BufferSize(unit:K) --> <property name ="netBufferSize" >128 </property> <!-- Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm). --> <property name ="tcpNoDelay" >true </property> <!-- 对外验证的用户名 --> <property name ="user" >root</property> <!-- 对外验证的密码 --> <property name ="password" >password</property> <!-- query timeout( default: 60 second , TimeUnit:second) --> <property name ="queryTimeout" >60 </property> </server> <!-- 每个ConnectionManager都将作为一个线程启动。 manager负责Connection IO读写/死亡检测 --> <connectionManagerList> <connectionManager name ="defaultManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper" > <property name ="subManagerClassName" >com.meidusa.amoeba.net.AuthingableConnectionManager</property> <!-- default value is avaliable Processors <property name ="processors" >5 </property> --> </connectionManager> </connectionManagerList> <dbServerList> <!-- 一台mysqlServer 需要配置一个pool, 如果多台 平等的mysql需要进行loadBalance, 平台已经提供一个具有负载均衡能力的objectPool:com.meidusa.amoeba.mysql.server.MultipleServerPool 简单的配置是属性加上 virtual ="true" ,该Pool 不允许配置factoryConfig 或者自己写一个ObjectPool。 --> <dbServer name ="server1" > <!-- PoolableObjectFactory实现类 --> <factoryConfig class ="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory" > <property name ="manager" >defaultManager</property> <!-- 真实mysql数据库端口 --> <property name ="port" >3306 </property> <!-- 真实mysql数据库IP --> <property name ="ipAddress" >192.168 .1.121 </property> <property name ="schema" >test</property> <!-- 用于登陆mysql的用户名 --> <property name ="user" >zhang</property> <!-- 用于登陆mysql的密码 --> <property name ="password" >zhang123</property> </factoryConfig> <!-- ObjectPool实现类 --> <poolConfig class ="com.meidusa.amoeba.net.poolable.PoolableObjectPool" > <property name ="maxActive" >200 </property> <property name ="maxIdle" >200 </property> <property name ="minIdle" >10 </property> <property name ="minEvictableIdleTimeMillis" >600000 </property> <property name ="timeBetweenEvictionRunsMillis" >600000 </property> <property name ="testOnBorrow" >true </property> <property name ="testWhileIdle" >true </property> </poolConfig> </dbServer> <dbServer name ="server2" > <!-- PoolableObjectFactory实现类 --> <factoryConfig class ="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory" > <property name ="manager" >defaultManager</property> <!-- 真实mysql数据库端口 --> <property name ="port" >3306 </property> <!-- 真实mysql数据库IP --> <property name ="ipAddress" >192.168 .1.108 </property> <property name ="schema" >test</property> <!-- 用于登陆mysql的用户名 --> <property name ="user" >zhang</property> <!-- 用于登陆mysql的密码 --> <property name ="password" >zhang123</property> </factoryConfig> <!-- ObjectPool实现类 --> <poolConfig class ="com.meidusa.amoeba.net.poolable.PoolableObjectPool" > <property name ="maxActive" >200 </property> <property name ="maxIdle" >200 </property> <property name ="minIdle" >10 </property> <property name ="minEvictableIdleTimeMillis" >600000 </property> <property name ="timeBetweenEvictionRunsMillis" >600000 </property> <property name ="testOnBorrow" >true </property> <property name ="testWhileIdle" >true </property> </poolConfig> </dbServer> <dbServer name ="master" virtual="true" > <poolConfig class ="com.meidusa.amoeba.server.MultipleServerPool" > <!-- 负载均衡参数 1 =ROUNDROBIN , 2 =WEIGHTBASED , 3 =HA--> <property name ="loadbalance" >1 </property> <!-- 参与该pool负载均衡的poolName列表以逗号分割 --> <property name ="poolNames" >server1</property> </poolConfig> </dbServer> <dbServer name ="slave" virtual="true" > <poolConfig class ="com.meidusa.amoeba.server.MultipleServerPool" > <!-- 负载均衡参数 1 =ROUNDROBIN , 2 =WEIGHTBASED , 3 =HA--> <property name ="loadbalance" >1 </property> <!-- 参与该pool负载均衡的poolName列表以逗号分割 --> <property name ="poolNames" >server1,server2</property> </poolConfig> </dbServer> </dbServerList> <queryRouter class ="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter" > <property name ="ruleConfig" >${amoeba.home} /conf/rule.xml</property> <property name ="functionConfig" >${amoeba.home} /conf/functionMap.xml</property> <property name ="ruleFunctionConfig" >${amoeba.home} /conf/ruleFunctionMap.xml</property> <property name ="LRUMapSize" >1500 </property> <property name ="defaultPool" >master</property> <property name ="writePool" >master</property> <property name ="readPool" >slave</property> <property name ="needParse" >true </property> </queryRouter> </amoeba:configuration>
启动amoeba /usr/local/amoeba/bin/amoeba &
检验启动是否成功(使用的是默认的8066端口):
1 2 3 4 [root@Centos2 amoeba] root 24580 0.2 19.2 408912 49264 pts/1 Sl 12:52 0:11 /usr/java/jdk1.6/bin/java -server -Xms256m -Xmx256m -Xss128k -Damoeba.home =/usr/local/amoeba -Dclassworlds.conf=/usr/local/amoeba/bin/amoeba.classworlds -classpath /usr/local/amoeba/lib/classworlds-1.0 .jar org.codehaus.classworlds.Launcher [root@Centos2 amoeba] tcp 0 0 ::ffff:192.168.1.159:8066 :::* LISTEN 24580/java
测试 测试之前先要保证amoeba-server有访问两个主从服务器test库的权限,在主从mysql上都执行:(至关重要!!)grant all on test.* to zhang@'192.168.1.%' identified by 'zhang123';
#用户名密码要和前面配置的一致 flush privileges;
测试的时候和我们平时使用一样,amoeba-mysql对我们应用透明,就是个mysql的代理了! 登录mysql使用如下命令(用户名密码和上面配置的要一致): mysql -uroot -ppassword -h192.168.1.159 -P8066
登录上去后,为了测试读和写必须,先把mysql的主从复制停掉,才能更清楚地看出读写的服务器是哪台,在从上使用stop slave;登录到amoeba-mysql上,使用命令mysql -uroot -ppassword -h192.168.1.159 -P8066,然后执行写和读操作,查看写的是哪台服务器,读的是哪台服务器,实验结果显示:写只在主上进行,读在主和从都进行,比率是1:1
测试步骤: 还没有停掉从同步之前,创建一个表: create table zhang (id int(10) ,name varchar(10),address varchar(20)); 在从上执行stop slave; 然后在主从上各插入一条不同数据(供测试读的时候用), 在主上插入:insert into zhang values(‘1’,’zhang’,’this_is_master’); 在从上插入:insert into zhang values(‘2’,’zhang’,’this_is_slave’); 接下来通过登录amoeba-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 [root@Centos2 ~] Welcome to the MySQL monitor. Commands end with Your MySQL connection id is 14556042 Server version: 5.1.45-mysql-amoeba-proxy-1.3.1-BETA Source distribution Type 'help mysql> use test Database changed mysql> select * from zhang +------+-------+----------------+ | id | name | address | +------+-------+----------------+ | 1 | zhang | this_is_master | +------+-------+----------------+ 1 row in set (0.02 sec) mysql> select * from zhang +------+-------+---------------+ | id | name | address | +------+-------+---------------+ | 2 | zhang | this_is_slave | +------+-------+---------------+ 1 row in set (0.02 sec) mysql> insert into zhang values('3','hhh','test_write') Query OK, 1 row affected (0.01 sec) mysql> select * from zhang +------+-------+----------------+ | id | name | address | +------+-------+----------------+ | 1 | zhang | this_is_master | | 3 | hhh | test_write | +------+-------+----------------+ mysql> select * from zhang +------+-------+---------------+ | id | name | address | +------+-------+---------------+ | 2 | zhang | this_is_slave | +------+-------+---------------+
简单主从权重配置 大家可能会想到,我们加入只有两台数据库服务器,一台主,一台从,按照上面的配置只能是主和从的读取比率是1:1,而写又全部在主上进行,这样主的压力就很大了,所以如果能让主和从的读设置权重,比如设置成1:3,这样就可以很好的解决主从不压力均衡的问题!通过研究确实可以!
配置就是将上面的读的池的配置更改一下: 将<property name="poolNames">server1,server2</property>
更改成<property name="poolNames">server1,server2,server2,server2</property>
我测试的结果刚好为1:3,如下:
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 mysql> select * from zhang; + | id | name | address | + | 1 | zhang | this_is_master | | 3 | hhh | test_write | + 2 rows in set (0.01 sec)mysql> select * from zhang; + | id | name | address | + | 2 | zhang | this_is_slave | + 1 row in set (0.04 sec)mysql> select * from zhang; + | id | name | address | + | 2 | zhang | this_is_slave | + 1 row in set (0.01 sec)mysql> select * from zhang; + | id | name | address | + | 2 | zhang | this_is_slave | +
学习链接:Amoeba搞定mysql主从读写分离 开发者博客链接: http://amoeba.sourceforge.net/wordpress/ amoeba 中文文档下载地址:http://amoeba.meidusa.com/amoeba.pdf amoeba 未来发展方向:http://amoeba.meidusa.com/amoeba-big-picture.pdf