说明:
要实现mysql的主从读写分离,目前主要有以下几种方案:
1.通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。
2.通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。
3.自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。
4.利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单,但是目前还不支持事务。
本文主要讲如何通过amoeba实现mysql读写分离。
实现:
1.java环境的安装,Amoeba框架是基于Java SE1.5开发的,建议使用Java SE 1.5版本。目前Amoeba经验证在JavaTM SE 1.5和Java SE 1.6能正常运行
可以到http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html#jdk-6u41-oth-JPR免费注册,下载
我这里下载jdk-6u41-linux-x64-rpm.bin,下载完成后执行sh jdk-6u41-linux-x64-rpm.bin开始安装,将会安装到/usr/java/jdk1.6.0_41目录。
2.amoeba编译安装
# cd /usr/local/src/tmp # mkdir /usr/local/amoeba # wget http://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/2.2.x/amoeba-mysql-binary-2.2.0.tar.gz/download # tar xzf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
3.配置java的用户环境变量
# vi ~/.bash_profile 修改为以下内容: PATH=$PATH:$HOME/bin:/usr/local/amoeba/bin JAVA_HOME=/usr/java/jdk1.6.0_41 export JAVA_HOME export PATH # source ~/.bash_profile //立即生效
4.1 /usr/local/amoeba/conf/dbServers.xml配置,此文件定义由Amoeba代理的数据库如何连接,比如最基础的:主机IP、端口、Amoeba使用的用户名和密码等等。
Amoeba for mysql读写分离主要涉及两个文件:/usr/local/amoeba/conf/dbServers.xml和/usr/local/amoeba/conf/amoeba.xml
abstractServer配置
${defaultManager} 64 128 3306 dbname root root 500 500 10 600000 600000 true true
此部分定义真实mysql服务器的端口,数据库名称,mysql用户及密码。
主从数据库定义:
192.168.0.1 192.168.0.2 192.168.0.3 1 Slave1,Slave2
此部分定义主服务器,从服务器,及从服务器连接池。这里只定义数据库地址,它们的用户及密码就是上面的abstractServer里的设置。注意用来连接真实mysql服务器的用户必须拥有远程连接权限。
4.2 /usr/local/amoeba/conf/amoeba.xml配置,此文件定义了amoeba代理的相关配置
amoeba连接验证配置:
root root ${amoeba.home}/conf/access_list.conf
这里定义连接amoeba时用来验证的用户及密码。
读写分离配置:
Master Master virtualSlave
defaultPool:配置了默认的数据库节点,一些除了SELECTUPDATEINSERTDELETE的语句都会在defaultPool执行。
writePool :配置了数据库写库,通常配为Master,如这里就配置为之前定义的Master数据库。
readPool :配置了数据库读库,通常配为Slave或者Slave组成的数据库池,如这里就配置之前的virtualSlave数据库池。
5.amoeba启动
# amoeba start //此命令以前台的方式启动,会输出启动时的信息,检查没有错误信息后,中断,并后台运行: # amoeba start & //后台运行
6.测试
在amoeba上登8066端口跟amoeba远程登陆主mysql服务器效果一样。
# /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1 -P8066 # /usr/local/mysql/bin/mysql -uroot -p123456 -h192.168.45.7 -P3306
附录:
1.启动amoeba时出现The stack size specified is too small, Specify at least 160k
#vim /usr/loca/amoeba/bin/amoeba文件,修改 DEFAULT_OPTS=”-server -Xms256m -Xmx256m -Xss128k”
为 DEFAULT_OPTS=”-server -Xms256m -Xmx256m -Xss256k”
保存,再次启动即可
2.amoeba查询数据库时出现:java.util.NoSuchElementException: Could not create a validated object, cause: ValidateObject failed
> select * from user; ERROR 2013 (HY000): Lost connection to MySQL server during query mysql> java.util.NoSuchElementException: Could not create a validated object, cause: ValidateObject failed at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1191) at com.meidusa.amoeba.net.poolable.GenericObjectPool.borrowObject(GenericObjectPool.java:381) at com.meidusa.amoeba.mysql.handler.CommandMessageHandler.startSession(CommandMessageHandler.java:633) at com.meidusa.amoeba.mysql.handler.MySqlCommandDispatcher.handleMessage(MySqlCommandDispatcher.java:123) at com.meidusa.amoeba.mysql.net.MysqlClientConnection$2.run(MysqlClientConnection.java:291) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662)
仔细检查dbServers.xml配置后发现factoryConfig中
# vim /usr/local/amoeba/conf/dbServers.xml,删除${defaultManager} 64 128 3306 test root