码迷,mamicode.com
首页 > 数据库 > 详细

mysql读写分离之amoeba

时间:2016-03-05 14:54:06      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:mysql   集群   amoeba   

一.amoeba介绍

Amoeba(变形虫)项目,该开源框架于2008年 开始发布一款 Amoeba for Mysql软件。这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的 时候充当SQL路由功能,专注于分布式数据库代理层(Database Proxy)开发。座落与 Client、DB Server(s)之间,对客户端透明。具有负载均衡、高可用性、SQL 过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。 通过Amoeba你能够完成多数据源的高可用、负载均衡、数据切片的功能,目前Amoeba已在很多 企业的生产线上面使用。

在MySQL proxy 6.0版本 上面如果想要读写分离并且 读集群、写集群 机器比较多情况下,用mysql proxy 需要相当大的工作量,目前mysql proxy没有现成的 lua脚本。mysql proxy根本没有配置文件, lua脚本就是它的全部,当然lua是相当方便的。那么同样这种东西需要编写大量的脚本才能完成一 个复杂的配置。而Amoeba for Mysql只需要进行相关的配置就可以满足需求。

目前不足:

  1. 目前还不支持事务
    2.暂时不支持存储过程(近期会支持)
    3.不适合从amoeba导数据的场景或者对大数据量查询的query并不合适(比如一次请求返回10w以上甚至更多数据的场合)
    4.暂时不支持分库分表,amoeba目前只做到分数据库实例,每个被切分的节点需要保持库表结构一致。

  2. 原理流程图

技术分享

二 安装amoeba

wget http://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz

mkdir -pv /usr/loca/amoeba/

tar -zxvf amoeba-mysql-binary-2.1.0-RC5.tar.gz -C /usr/loca/amoeba/

然后进入bin目录运行amoeba start或者amoeba start &后台的形式运行,不过下面我们先看配置文件;

三 配置amoeba

1.想象Amoeba作为数据库代理层,它一定会和很多数据库保持通信,因此它必须知道由它代理的数据库如何连接,比如最基础的:主机IP、端口、Amoeba使用的用户名和密码等等。这些信息存储在$AMOEBA_HOME/conf/dbServers.xml中。
2.Amoeba为了完成数据切分提供了完善的切分规则配置,为了了解如何分片数据、如何将数据库返回的数据整合,它必须知道切分规则。与切分规则相关的信息存储在$AMOEBA_HOME/conf/rule.xml中。
3.当我们书写SQL来操作数据库的时候,常常会用到很多不同的数据库函数,比如:UNIX_TIMESTAMP()、SYSDATE()等等。这些函数如何被Amoeba解析呢?$AMOEBA_HOME/conf/functionMap.xml描述了函数名和函数处理的关系。
4.对$AMOEBA_HOME/conf/rule.xml进行配置时,会用到一些我们自己定义的函数,比如我们需要对用户ID求HASH值来切分数据,这些函数在$AMOEBA_HOME/conf/ruleFunctionMap.xml中定义。
5.Amoeba可以制定一些可访问以及拒绝访问的主机IP地址,这部分配置在$AMOEBA_HOME/conf/access_list.conf中
6.Amoeba允许用户配置输出日志级别以及方式,配置方法使用log4j的文件格式,文件是$AMOEBA_HOME/conf/log4j.xml。

ok

配置之前我们说说我们的架构,很简单,三台主机

一台 amoeba 192.168.127.140 来转发请求;

一台 master 192.168.127.141 可以进行读写操作;

一台 slave 192.168.127 只能进行读取操作;

本场景是读取数据量比较大,所以master可以读写,slave只能读取,最终的效果读取比例是master:slave=1:3.

7 .配置amoeba节点

7.1红色字体是主配置文件需要注意和修改的地方

<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
<proxy>
 
 <!-- service class must implements com.meidusa.amoeba.service.Service -->
 <service name="Amoeba for Mysql" class="com.meidusa.amoeba.net.ServerableConnectionManager">#1.定义这是一个MySQL Proxy Service。相应的也会有MongoDB Proxy Service以及Aladdin Proxy Service。
 <!-- port -->
 <property name="port">8066</property> #2.数据库客户端用来登陆amoeba的端口;
 
 <!-- bind ipAddress -->
 <!-- 
 <property name="ipAddress">192.168.127.140</property> #3.数据库客户端用来登陆amoeba的IP,通常Proxy Service服务的主机地址并不需要定义,如果Amoeba所在的服务器在多个网络环境内你可以定义该机器的其中一个IP来指定Amoeba所服务的网络环境。如果设置为127.0.0.1将导致其他机器无法访问Amoeba的服务。
 -->
 
 <property name="manager">${clientConnectioneManager}</property>
 
 <property name="connectionFactory">
 <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">
 <property name="sendBufferSize">128</property>
 <property name="receiveBufferSize">64</property>
 </bean>
 </property>
 
 <property name="authenticator">
 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
 
 <property name="user">root</property> #6.数据库客户端用来登陆amoeba的用户名;
 
 <property name="password">password</property>#7.数据库客户端用来登陆amoeba的密码;
 
 <property name="filter">
 <bean class="com.meidusa.amoeba.server.IPAccessController"> 
 <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
 </bean>
 </property>
 </bean>
 </property>
 
 </service>
 
 <!-- server class must implements com.meidusa.amoeba.service.Service -->
 <service name="Amoeba Monitor Server" class="com.meidusa.amoeba.monitor.MonitorServer">
 <!-- port -->
 <!-- default value: random number
 <property name="port">9066</property>
 -->
 <!-- bind ipAddress -->
 <property name="ipAddress">127.0.0.1</property>
 <property name="daemon">true</property>
 <property name="manager">${clientConnectioneManager}</property>
 <property name="connectionFactory">
 <bean class="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory"></bean>
 </property>
 
 </service>
 
 <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">#8.runtime元素定义了一些Proxy相关的运行期配置,如客户端及数据库服务器端的线程数以及SQL超时时间设定等等。
 <!-- 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>
 
 <!-- per connection cache prepared statement size -->
 <property name="statementCacheSize">500</property>
 
 <!-- query timeout( default: 60 second , TimeUnit:second) -->
 <property name="queryTimeout">60</property>
 </runtime>
 
 </proxy>
 
 <!-- 
 Each ConnectionManager will start as thread
 manager responsible for the Connection IO read , Death Detection
 -->
 <connectionManagerList> #9.connectionManagerList定义了一系列连接管理器,这些连接管理器可以在其他地方被引用,比如clientConnectioneManager在amoeba.xml中被引用作为MySQL Proxy Service的客户端连接管理器;defaultManager在dbServers.xml中被引用作为dbServer的数据库服务器端连接管理器。连接管理器主要配置了用于网络处理的CPU核数,默认其processor属性为Amoeba所在主机的CPU核数。
 <connectionManager name="clientConnectioneManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
 <property name="subManagerClassName">com.meidusa.amoeba.net.ConnectionManager</property>
 <!-- 
 default value is avaliable Processors 
 <property name="processors">5</property>
 -->
 </connectionManager>
 <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>
 
 <!-- default using file loader -->
 <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">
 <property name="configFile">${amoeba.home}/conf/dbServers.xml</property>
 </dbServerLoader>
 
 <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
 <property name="ruleLoader">
 <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
 <property name="ruleFile">${amoeba.home}/conf/rule.xml</property>
 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
 </bean>
 </property>
 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
 <property name="LRUMapSize">1500</property>
 <property name="defaultPool">master</property>#10.表示默认配置读写都会到数据池的master这个角色,在dbServer.xml中定义;
 
 <property name="writePool">master</property>#11.表示只写的数据池指定master这个名称的角色;
 <property name="readPool">virtualSlave</property>#12.表示只读的数据池指定virtualSlave这个名称的角色;
 <property name="needParse">true</property>
 </queryRouter>
</amoeba:configuration>

ok

7.2配置dbServer.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"> #1.这份dbServers配置文件中,我们定义了三个dbServer元素,这是第一个dbServer元素的定义。这个名为abstractServer的dbServer,其abstractive属性为true,这意味着这是一个抽象的dbServer定义,可以由其他dbServer定义拓展。
 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
 <property name="manager">${defaultManager}</property> #2.manager定义了该dbServer选择的连接管理器(ConnectionManager),这里引用了amoeba.xml的配置
 <property name="sendBufferSize">64</property>
 <property name="receiveBufferSize">128</property>
 <!-- mysql port -->
 <property name="port">3306</property>#3.数据库端口
 <!-- mysql schema -->
 <property name="schema">dongdong</property>#4.目标数据库
 <!-- mysql user -->
 <property name="user">haha</property>#5.用于连接后端数据库的用户,注意需要给他赋予操作上面数据库的权限;
 <!-- mysql password -->
 <property name="password">haha123</property>#6.haha用户登陆的密码
 </factoryConfig>
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">#7.dbServer下有poolConfig的元素,这个元素的属性主要配置了与数据库的连接池,与此相关的具体配置会在后面详细介绍。
 <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="testWhileIdle">true</property>
 </poolConfig>
 </dbServer><dbServer name="master" parent="abstractServer">#8.这个master是abstractServer的拓展,parent属性配置了拓展的抽象dbServer,它拓展了abstractServer的ipAddress属性来指名数据库的IP地址,而在端口、用户名密码、连接池配置等属性沿用了abstractServer的配置。
 <factoryConfig>
 <!-- mysql ip -->
 <property name="ipAddress">192.168.127.141</property>#9.master的地址;
 </factoryConfig>
 </dbServer>
 <dbServer name="slave" parent="abstractServer">
 <factoryConfig>
 <!-- mysql ip -->
 <property name="ipAddress">192.168.127.142</property>#9.slave的地址;
 </factoryConfig>
 </dbServer>
 <dbServer name="virtualSlave" virtual="true">#10. 这一段其实并不需要配置,并不会影响到基本使用。以下大致介绍下此配置的含义:multiPool是一个虚拟的数据库节点,可以将这个节点配置成好几台数据库组成的数据库池。比如上面这个配置中仅配置了一台server1,负载均衡策略为ROUNDROBIN(轮询)。与虚拟数据库节点相关的详细教程会在后面的章节中介绍。
 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
 <property name="loadbalance">1</property>
 <!-- Separated by commas,such as: server1,server2,server1 -->
 <property name="poolNames">master,slave,slave,slave</property>#11.此处master和slave配置出现的此处就是给它们分配请求的比例,此处是1:3
 </poolConfig>
 </dbServer>
</amoeba:dbServers>

补充 定义abstractServer的原因:当我们有一个数据库集群需要管理,这个数据库集群中节点的大部分信息可能是相同的,比如:端口号、用户名、密码等等。因此通过归纳这些共性定义出的abstractServer极大地简化了dbServers配置文件。

四.运行amoeba以及测试

1./usr/loca/amoeba/bin/amoeba start &

日志显示

open socket channel to server[192.168.127.141:3306] success!
open socket channel to server[192.168.127.142:3306] success!

如果没有显示就证明没有连接到后端数据库,笔者之前有一个连接不到,结果原因是配置文件里面的注释未去掉,o(╯□╰)o

2.因为实际环境需要master与slave同步,不是本文重点,可看其他文章;

这里前提是关闭slave的同步,在slave上  stop slave,但是如果大量测试数据,那么你可以让slave把master的数据库同步过来在关闭也ok;

分别在master和slave上创建数据库

grant all privileges on hehe.* to hehe@‘%‘ indefied by ‘hehe123‘;
 flush privileges;
create database hehe;
 use hehe;
create tables heheta(id int(10),name varchar(20));
insert into heheta (id,name,address)value(‘9,‘master‘,‘100‘); 给master插入数据
insert into heheta (id,name,address)value(‘10‘,‘slave‘,‘101‘);给slave插入数据
然后在amoeba主机上进行登陆以及测试
mysql -uroot -ppassword -h192.168.127.140 -P8066
use heheta;
mysql> select * from heheta;
+------+-------+---------+
| id | name | address |
+------+-------+---------+
| 10 | slave | 101 |
+------+-------+---------+
1 row in set (0.01 sec)
mysql> select * from heheta;
+------+-------+---------+
| id | name | address |
+------+-------+---------+
| 10 | slave | 101 |
+------+-------+---------+
1 row in set (0.00 sec)
mysql> select * from heheta;
+------+-------+---------+
| id | name | address |
+------+-------+---------+
| 10 | slave | 101 |
+------+-------+---------+
1 row in set (0.01 sec)
mysql> select * from heheta;
+------+--------+---------+
| id | name | address |
+------+--------+---------+
| 9 | master | 100 |
+------+--------+---------+
1 row in set (0.01 sec)

读取比例master:slave=1:3

插入数据测试
insert into heheta(id,name,address)value(‘11‘,‘adddata‘,‘102‘);
查询只能在负责写入数据的master上才会有数据
mysql> select * from heheta;
+------+-------+---------+
| id | name | address |
+------+-------+---------+
| 10 | slave | 101 |
+------+-------+---------+
1 row in set (0.01 sec)
mysql> select * from heheta;
+------+---------+---------+
| id | name | address |
+------+---------+---------+
| 9 | master | 100 |
| 11 | adddata | 102 |
+------+---------+---------+
2 rows in set (0.02 se

更多欢迎到查阅


本文出自 “技术成就梦想” 博客,请务必保留此出处http://2367685.blog.51cto.com/2357685/1747796

mysql读写分离之amoeba

标签:mysql   集群   amoeba   

原文地址:http://2367685.blog.51cto.com/2357685/1747796

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!