一、Amoeba概述
1、amoeba简介
Amoeba是一个类似MySQL Proxy的分布式数据库中间代理层软件,是由陈思儒开发的一个开源的java项目。其主要功能包括读写分离,垂直分库,水平分库等,经过测试,发现其功能和稳定性都非常的不错,如果需要构架分布式数据库环境,采用Amoeba是一个不错的方案。目前Amoeba一共包括For aladdin,For MySQL和For Oracle三个版本,本文主要关注For MySQL版本的一个读写分离实现。
Amoeba处于在应用和数据库之间,扮演一个中介的角色,将应用传递过来的SQL语句经过分析后,将写的语句交给Master库执行,将读的语句路由到Slave库执行(当然也可以到Master读,这个完全看配置)。Amoeba实现了简单的负载均衡(采用轮询算法)和Failover。如果配置了多个读的库,则任何一个读的库出现宕机,不会导致整个系统故障,Amoeba能自动将读请求路由到其他可用的库上,当然,写还是单点的依赖于Master数据库的,这个需要通过数据库的切换,或者水平分割等技术来提升Master库的可用性。
2、amoeba与mysql-proxy的区别
在MySQL proxy 6.0版本上面如果想要读写分离并且读集群、写集群机器比较多情况下,用mysql proxy 需要相当大的工作量,目前mysql proxy没有现成的 lua脚本。mysql proxy根本没有配置文件, lua脚本就是它的全部,当然lua是相当方便的。那么同样这种东西需要编写大量的脚本才能完成一 个复杂的配置。而Amoeba只需要进行相关的配置就可以满足需求。
二、实验环境
服务器角色 | IP地址 | 安装软件 | 功用 | 操作系统 |
主服务器 | 172.16.8.1 | mysql | 可读写 |
centos6.5 |
从服务器 | 172.16.8.2 | mysql | 只可读,与主服务器做读的负载均衡 | centos6.5 |
读写分离服务器 | 172.16.8.3 | amoeba | 实现读写分离,将写操作发往主服务器,将读操作进行负载均衡! | centos6.5 |
三、amoeba的详细配置
1、主从服务器的配置
在主服务器上安装mysql
#yum -y install mysql mysql-server
修改配置文件:
# vim /etc/my.cnf//添加如下:server-id = 1
启动mysql,并 创建授权账户
#service mysqld start#mysqlmysql> grant replication slave,replication client on *.* to "gulong"@'172.16.8.2' identified by '123';mysql> flush privileges;
从服务器上的也安装mysql
#yum -y install mysql mysql-server
修改配置文件:
# vim /etc/my.cnf//添加如下:server-id = 2relay_log = relay_bin
启动mysql,连接主服务器
#service mysqld start#mysqlmysql> change master to master_host='172.16.8.1',master_user='gulong',master_password='123'
查看主从状态:
mysql> start slave;mysql> show slave status\G;
到此,主从服务器配置好了!
2、amoeba的配置
首先下载jdk与amoeba安装包:
安装jdk:
#chmod +x jdk-6u31-linux-x64-rpm.bin #./jdk-6u31-linux-x64-rpm.bin #vim /etc/profile.d/java.sh//添加如下内容:export JAVA_HOME=/usr/java/latestexport PATH=$JAVA_HOME/bin:$PATH#. /etc/profile.d/java.sh
查看java状态:
安装amoeba:
#mkdir /usr/local/amoeba#tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/#cd /usr/local/amoeba/
Amoeba for MySQL的使用是很简单的,主要是通过xml文件来实现的。
1. 配置文件介绍:
(1.) dbServers.xml 想象Amoeba作为数据库代理层,它一定会和很多数据库保持通信,因此它必须知道由它代理的数据库如何连接,比如最基础的:主机IP、端口、Amoeba使用的用户名和密码等等。这些信息存储在$AMOEBA_HOME/conf/dbServers.xml中。
(2.) rule.xml Amoeba为了完成数据切分提供了完善的切分规则配置,为了了解如何分片数据、如何将数据库返回的数据整合,它必须知道切分规则。与切分规则相关的信息存储在$AMOEBA_HOME/conf/rule.xml中。
(3.) functionMap.xml 当我们书写SQL来操作数据库的时候,常常会用到很多不同的数据库函数,比如:UNIX_TIMESTAMP()、SYSDATE()等等。这些函数如何被Amoeba解析呢?$AMOEBA_HOME/conf/functionMap.xml描述了函数名和函数处理的关系。
(4.) ruleFunctionMap.xml 对$AMOEBA_HOME/conf/rule.xml进行配置时,会用到一些我们自己定义的函数,比如我们需要对用户ID求HASH值来切分数据,这些函数在$AMOEBA_HOME/conf/ruleFunctionMap.xml中定义。
(5.) access_list.conf Amoeba可以制定一些可访问以及拒绝访问的主机IP地址,这部分配置在$AMOEBA_HOME/conf/access_list.conf中。
(6.) log4j.xml Amoeba允许用户配置输出日志级别以及方式,配置方法使用log4j的文件格式,文件是$AMOEBA_HOME/conf/log4j.xml。
其中,我们主要用到dbServer.xml 和 amoeba.xml 。
修改ameoba.xml配置文件
[root@node1 ~]# cd /usr/local/amoeba/conf/[root@node1 conf]# vim amoeba.xml
修改dbServers.xml 配置文件
[root@node1 conf]# vim dbServers.xml //修改如下:<?xml version="1.0" encoding="gbk"?><!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd"><amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/"> <!-- Each dbServer needs to be configured into a Pool, If you need to configure multiple dbServer with load balancing that can be simplified by the following configuration: add attribute with name virtual = "true" in dbServer, but the configuration does not allow the element with name factoryConfig such as 'multiPool' dbServer --> <dbServer name="abstractServer" abstractive="true"> <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"> <property name="manager">${defaultManager}</property> <property name="sendBufferSize">64</property> <property name="receiveBufferSize">128</property> <!-- mysql port --> <property name="port">3306</property> <!-- mysql schema --> <property name="schema">test</property> <!-- mysql user --> //设置连接后端数据库的账户密码,需要在主mysql上授权 <property name="user">root</property> <property name="password">admin</property> <!-- mysql password <property name="password">password</property> --> </factoryConfig> <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool"> <property name="maxActive">500</property> <property name="maxIdle">500</property> <property name="minIdle">10</property> <property name="minEvictableIdleTimeMillis">600000</property> <property name="timeBetweenEvictionRunsMillis">600000</property> <property name="testOnBorrow">true</property> <property name="testOnReturn">true</property> <property name="testWhileIdle">true</property> </poolConfig> </dbServer> //将172.16.8.1添加为master主服务器 <dbServer name="master" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <property name="ipAddress">172.16.8.1</property> </factoryConfig> </dbServer> //172.16.8.2添加为从的slave服务器 <dbServer name="slave" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <property name="ipAddress">172.16.8.2</property> </factoryConfig> </dbServer> //将master与slave添加为一个mysql集群,命名为readservers,采用轮询的负载均衡机制 <dbServer name="readservers" virtual="true"> <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> <property name="loadbalance">1</property>//1代表轮询 <!-- Separated by commas,such as: server1,server2,server1 --> <property name="poolNames">master,slave</property> </poolConfig> </dbServer></amoeba:dbServers>
在主mysql服务器上授权远程连接账户:
mysql> grant all on *.* to "root"@'172.16.%.%' identified by 'admin';mysql> flush privileges;
启动amoeba,并测试:
[root@node1 bin]# cd /usr/local/amoeba/[root@node1 bin]# ./amoeba start[root@node1 ~]# mysql -uroot -pmypass -h172.16.8.3
3、测试:
连接amoeba
创建数据库,
MySQL [mysql]> create database wb;//创建数据库MySQL [mysql]> select user,password from mysql.user;//查询数据库MySQL [mysql]> show databases;
可以通过使用tcpdump在master、slave服务器上抓包,创建一个数据库,并多使用几次查询语句,验证写操作是否被调度至master(172.16.8.1),而读操作会以轮叫的方式调度至master和slave,可以分摊mysql的读请求!
[root@localhost ~]# tcpdump -i eth0 -nn -XX ip dst host 172.16.8.1 and tcp dst port 3306[root@localhost ~]# tcpdump -i eth0 -nn -XX ip dst host 172.16.8.2 and tcp dst port 3306
至此,基于amoeba的读写分离已经介绍完毕,不足之处,请多加指点!