Amoeba+Mysql实现数据库读写分离(代码教程)
一、amoeba是什么
amoeba(变形虫)项目,专注分布式proxy开发。座落与client、db server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。
主要解决:
降低数据切分带来的复杂多数据库结构
提供切分规则并降低数据切分规则给应用带来的影响
降低db与客户端的连接数
读写分离
二、为什么要用amoeba
目前要实现mysql的主从读写分离,主要有以下几种方案:
1、通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。
2、通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。
3、自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。
4、利用阿里巴巴的开源项目amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。国产的开源软件,应该支持,目前正在使用,不发表太多结论,一切等测试完再发表结论吧,哈哈!
三、amoeba的安装
先介绍下部署环境:
amoeba:192.168.2.203
masterdb:192.168.2.204
slavedb:192.168.2.205
以上全为centos6.8
amoeba框架是居于jdk1.5开发的,采用了jdk1.5的特性,所以还需要安装java环境,建议使用javase1.5以上的jdk版本
1、安装java环境
先去官网下载
安装
[root@bogon src]# rpm -ivh jdk-8u111-linux-x64.rpm preparing... ########################################### [100%] 1:jdk1.8.0_111 ########################################### [100%] unpacking jar files... tools.jar... plugin.jar... javaws.jar... deploy.jar... rt.jar... jsse.jar... charsets.jar... localedata.jar...
然后设置java环境变量
[root@bogon src]# vim /etc/profile #set java environment java_home=/usr/java/jdk1.8.0_111 jre_home=/usr/java/jdk1.8.0_111/jre class_path=.:$java_home/lib/dt.jar:$java_home/lib/tools.jar:$jre_home/lib path=$path:$java_home/bin:$jre_home/bin export java_home jre_home class_path path [root@bogon amoeba]# source /etc/profile
测试是否安装成功
[root@bogon src]# java -version java version "1.8.0_111" java(tm) se runtime environment (build 1.8.0_111-b14) java hotspot(tm) 64-bit server vm (build 25.111-b14, mixed mode)
2、安装amoeba
可以从https://sourceforge.net/projects/amoeba/下载最新版本的amoeba,我这里下载的是amoeba-mysql-3.0.5-rc-distribution.zip。amoeba安装非常简单,直接解压即可使用,这里将amoeba解压到/usr/local/amoeba目录下,这样就安装完成了
[root@bogon amoeba]# pwd /usr/local/amoeba
[root@bogon amoeba]# ll
总用量 20
drwxrwxrwx. 2 root root 4096 7月 5 2013 benchmark
drwxrwxrwx. 2 root root 4096 7月 5 2013 bin
drwxrwxrwx. 2 root root 4096 7月 5 2013 conf
-rwxrwxrwx. 1 root root 728 7月 5 2013 jvm.properties
drwxrwxrwx. 2 root root 4096 7月 5 2013 lib
3、配置amoeba
amoeba的配置文件在本环境下位于/usr/local/amoeba/conf目录下。配置文件比较多,但是仅仅使用读写分离功能,只需配置两个文件即可,分别是dbservers.xml和amoeba.xml,如果需要配置ip访问控制,还需要修改access_list.conf文件,下面首先介绍dbservers.xml
[root@bogon amoeba]# cat conf/dbservers.xml${defaultmanager} 64 128 3306 #设置amoeba要连接的mysql数据库的端口,默认是3306testdb #设置缺省的数据库,当连接amoeba时,操作表必须显式的指定数据库名,即采用dbname.tablename的方式,不支持 use dbname指定缺省库,因为操作会调度到各个后端dbservertest1 #设置amoeba连接后端数据库服务器的账号和密码,因此需要在所有后端数据库上创建该用户,并授权amoeba服务器可连接111111 #设置一个后端可写的dbserver,这里定义为writedb,这个名字可以任意命名,后面还会用到 500 #最大连接数,默认500500 #最大空闲连接数1 #最新空闲连接数600000 600000 true true true 192.168.2.204 #设置后端可写dbserver #设置后端可读dbserver192.168.2.205 #设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为myslave1 #选择调度算法,1表示复制均衡,2表示权重,3表示ha, 这里选择1slave #myslave组成员
另一个配置文件amoeba.xml
[root@bogon amoeba]# cat conf/amoeba.xml# 提供客户端连接amoeba时需要使用这里设定的账号 (这里的账号密码和amoeba连接后端数据库服务器的密码无关)8066 #设置amoeba监听的端口,默认是8066 #下面配置监听的接口,如果不设置,默认监听所以的ip128 64
root 123456 ${amoeba.home}/conf/access_list.conf 128 500 utf8 60 com.meidusa.toolkit.net.authingableconnectionmanager ${amoeba.home}/conf/dbservers.xml ${amoeba.home}/conf/rule.xml ${amoeba.home}/conf/rulefunctionmap.xml ${amoeba.home}/conf/functionmap.xml 1500 writedb #设置amoeba默认的池,这里设置为writedbwritedb #这两个选项默认是注销掉的,需要取消注释,这里用来指定前面定义好的俩个读写池myslave #true
4、在masterdb上创建数据库testdb
mysql> create database testdb; query ok, 1 row affected (0.08 sec) mysql> show databases; +--------------------+ | database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | | testdb | +--------------------+ 6 rows in set (0.00 sec)
查看slavedb是否复制成功
mysql> show databases; +--------------------+ | database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | | testdb | +--------------------+ 6 rows in set (0.00 sec)
分别在masterdb和slavedb上为amoedb授权
mysql> grant all on testdb.* to 'test1'@'192.168.2.203' identified by '111111'; query ok, 0 rows affected (0.05 sec) mysql> flush privileges; query ok, 0 rows affected (0.02 sec)
启动amoeba
[root@bogon amoeba]# /usr/local/amoeba/bin/launcher error: java_home environment variable is not set. [root@bogon amoeba]# vim /etc/profile^c [root@bogon amoeba]# source /etc/profile [root@bogon amoeba]# /usr/local/amoeba/bin/launcher java hotspot(tm) 64-bit server vm warning: ignoring option permsize=16m; support was removed in 8.0 java hotspot(tm) 64-bit server vm warning: ignoring option maxpermsize=96m; support was removed in 8.0 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.
报错:
error: could not create the java virtual machine. error: a fatal exception has occurred. program will exit.
从错误文字上看,应该是由于stack size太小,导致jvm启动失败,要如何修改呢?
其实amoeba已经考虑到这个问题,并将jvm参数配置写在属性文件里。现在,让我们通过该属性文件修改jvm参数。
修改jvm.properties文件jvm_options参数。
[root@bogon amoeba]# vim /usr/local/amoeba/jvm.properties 改成:jvm_options="-server -xms1024m -xmx1024m -xss256k -xx:permsize=16m -xx:maxpermsize=96m" 原为:jvm_options="-server -xms256m -xmx1024m -xss196k -xx:permsize=16m -xx:maxpermsize=96m"
再次启动
[root@bogon ~]# /usr/local/amoeba/bin/launcher at org.codehaus.plexus.classworlds.launcher.launcher.launchstandard(launcher.java:329) at org.codehaus.plexus.classworlds.launcher.launcher.launch(launcher.java:239) at org.codehaus.plexus.classworlds.launcher.launcher.mainwithexitcode(launcher.java:409) at org.codehaus.classworlds.launcher.mainwithexitcode(launcher.java:127) at org.codehaus.classworlds.launcher.main(launcher.java:110) caused by: com.meidusa.toolkit.common.bean.util.initialisationexception: default pool required!,defaultpool=writedb invalid at com.meidusa.amoeba.route.abstractqueryrouter.init(abstractqueryrouter.java:469) at com.meidusa.amoeba.context.proxyruntimecontext.initallinitialisablebeans(proxyruntimecontext.java:337) ... 11 more 2016-10-24 18:46:37 [info] project name=amoeba-mysql, pid=1577 , system shutdown .... java hotspot(tm) 64-bit server vm warning: ignoring option permsize=16m; support was removed in 8.0 java hotspot(tm) 64-bit server vm warning: ignoring option maxpermsize=96m; support was removed in 8.0 2016-10-24 18:50:19 [info] project name=amoeba-mysql, pid=1602 , starting... log4j:warn log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml 2016-10-24 18:50:21,668 info context.mysqlruntimecontext - amoeba for mysql current versoin=5.1.45-mysql-amoeba-proxy-3.0.4-beta log4j:warn ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf 2016-10-24 18:50:22,852 info net.serverableconnectionmanager - server listening on 0.0.0.0/0.0.0.0:8066.
查看端口
[root@bogon ~]# netstat -unlpt | grep java tcp 0 0 :::8066 :::* listen 1602/java
由此可知amoeba启动正常
5、测试
远程登陆mysql客户端通过指定amoeba配置文件中指定的用户名、密码、和端口以及amoeba服务器ip地址链接mysql数据库
[root@lys2 ~]# mysql -h192.168.2.203 -uroot -p -p8066 enter password: welcome to the mysql monitor. commands end with ; or \g. your mysql connection id is 1364055863 server version: 5.1.45-mysql-amoeba-proxy-3.0.4-beta source distribution 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>
在testdb中创建表test并插入数据
mysql> use testdb; database changed mysql> create table test_table(id int,password varchar(40) not null); query ok, 0 rows affected (0.19 sec) mysql> show tables; +------------------+ | tables_in_testdb | +------------------+ | test_table | +------------------+ 1 row in set (0.02 sec) mysql> insert into test_table(id,password) values('1','test1'); query ok, 1 row affected (0.04 sec) mysql> select * from test_table; +------+----------+ | id | password | +------+----------+ | 1 | test1 | +------+----------+ 1 row in set (0.02 sec)
分别登陆masterdb和slavedb查看数据
masterdb:
mysql> use testdb; database changed mysql> show tables; +------------------+ | tables_in_testdb | +------------------+ | test_table | +------------------+ 1 row in set (0.00 sec) mysql> select * from test_table; +------+----------+ | id | password | +------+----------+ | 1 | test1 | +------+----------+ 1 row in set (0.03 sec)
slavedb:
mysql> use testdb; database changed mysql> show tables; +------------------+ | tables_in_testdb | +------------------+ | test_table | +------------------+ 1 row in set (0.00 sec) mysql> select * from test_table; +------+----------+ | id | password | +------+----------+ | 1 | test1 | +------+----------+ 1 row in set (0.00 sec)
停掉masterdb,然后在客户端分别执行插入和查询功能
masterdb:
[root@bogon ~]# service mysqld stop
shutting down mysql. success!
客户端:
mysql> insert into test_table(id,password) values('2','test2'); error 1044 (42000): amoeba could not connect to mysql server[192.168.2.204:3306],拒绝连接 mysql> select * from test_table; +------+----------+ | id | password | +------+----------+ | 1 | test1 | +------+----------+ 1 row in set (0.01 sec)
可以看到,关掉masterdb和写入报错,读正常
开启masterdb上的msyql 关闭slave上的mysql
masterdb:
[root@bogon ~]# service mysqld start starting mysql.. success!
slavedb:
[root@localhost ~]# service mysqld stop shutting down mysql. success!
客户端再次尝试
mysql> insert into test_table(id,password) values('2','test2'); query ok, 1 row affected (0.19 sec) mysql> select * from test_table; error 1044 (42000): poolname=myslave, no valid pools
可以看到插入成功,读取失败
开启slavedb上的mysql,查看数据是否自动同步
slavedb:
[root@localhost ~]# service mysqld start starting mysql... success!
客户端:
mysql> select * from test_table; +------+----------+ | id | password | +------+----------+ | 1 | test1 | | 2 | test2 | +------+----------+ 2 rows in set (0.01 sec)
接着客户端:
mysql> insert into test_table(id,password) values('3','test3'); query ok, 1 row affected (0.03 sec) mysql> select * from test_table; +------+----------+ | id | password | +------+----------+ | 1 | test1 | | 2 | test2 | | 3 | test3 | +------+----------+ 3 rows in set (0.02 sec)
ok 一切正常,到此全部结束
注:关于mysql主从同步自行查看博主之前的主从同步笔记!
amoeba主配置文件($amoeba_home/conf/amoeba.xml),用来配置amoeba服务的基本参数,如amoeba主机地址、端口、认证方式、用于连接的用户名、密码、线程数、超时时间、其他配置文件的位置等。
数据库服务器配置文件($amoeba_home/conf/dbservers.xml),用来存储和配置amoeba所代理的数据库服务器的信息,如:主机ip、端口、用户名、密码等。
切分规则配置文件($amoeba_home/conf/rule.xml),用来配置切分规则。
数据库函数配置文件($amoeba_home/conf/functionmap.xml),用来配置数据库函数的处理方法,amoeba将使用该配置文件中的方法解析数据库函数。
切分规则函数配置文件($amoeba_home/conf/rulefunctionmap.xml),用来配置切分规则中使用的用户自定义函数的处理方法。
访问规则配置文件($amoeba_home/conf/access_list.conf),用来授权或禁止某些服务器ip访问amoeba。
日志规格配置文件($amoeba_home/conf/log4j.xml),用来配置amoeba输出日志的级别和方式。