欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Amoeba+Mysql实现数据库读写分离(代码教程)

程序员文章站 2022-07-04 09:27:55
一、amoeba是什么 amoeba(变形虫)项目,专注分布式proxy开发。座落与client、db server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关...

一、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}641283306  #设置amoeba要连接的mysql数据库的端口,默认是3306
            
            
            testdb  #设置缺省的数据库,当连接amoeba时,操作表必须显式的指定数据库名,即采用dbname.tablename的方式,不支持 use dbname指定缺省库,因为操作会调度到各个后端dbserver
            
            
            test1  #设置amoeba连接后端数据库服务器的账号和密码,因此需要在所有后端数据库上创建该用户,并授权amoeba服务器可连接
            
            111111500  #最大连接数,默认500
            500    #最大空闲连接数
            1    #最新空闲连接数
            600000600000truetruetrue
    

      #设置一个后端可写的dbserver,这里定义为writedb,这个名字可以任意命名,后面还会用到
        
            
            192.168.2.204 #设置后端可写dbserver
        
    
    
      #设置后端可读dbserver
        
            
            192.168.2.205
        
    
    
      #设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为myslave
        1  #选择调度算法,1表示复制均衡,2表示权重,3表示ha, 这里选择1
            
            
            slave  #myslave组成员
        

另一个配置文件amoeba.xml

[root@bogon amoeba]# cat conf/amoeba.xml 





    8066    #设置amoeba监听的端口,默认是8066
            
                #下面配置监听的接口,如果不设置,默认监听所以的ip
            
            
            12864
# 提供客户端连接amoeba时需要使用这里设定的账号 (这里的账号密码和amoeba连接后端数据库服务器的密码无关)
                    root    

                    
                    123456${amoeba.home}/conf/access_list.conf128500utf860com.meidusa.toolkit.net.authingableconnectionmanager${amoeba.home}/conf/dbservers.xml${amoeba.home}/conf/rule.xml${amoeba.home}/conf/rulefunctionmap.xml${amoeba.home}/conf/functionmap.xml1500writedb  #设置amoeba默认的池,这里设置为writedb
        
        
        writedb  #这两个选项默认是注销掉的,需要取消注释,这里用来指定前面定义好的俩个读写池
        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输出日志的级别和方式。