基于Ameoba实现mysql读写分离

一、Amoeba介绍

Amoeba:基于Java研发,配置文件xml文档。对事务支持功能很差,不支持分布式读,尤其不支持分布式事务。默认监听在8066端口上。2.2.x开始支持单库事务,没有缓存功能,所有请求直接向后转发。对内存占用少,而对CPU占用大。

二、架构简介

Amoeba服:192.168.1.253 监听端口80663306,作为后端mysql服务器代理,监控后端mysql服务器健康的端口9066

主服:station20:192.168.1.20,前端代理往主服写操作会自动复制到从服。

从服:station21:192.168.1.21

如果是多从,在前端代理里设置一个负载均衡从服组(虚拟服务器),组内按调度算法调度,三种算法:轮询rr,加权轮询wrr,高可用ha.

地址:http://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/

wKiom1OB8qaCMgKbAAEYFXPU8AE320.jpg

三、操作步骤

主服新建远程用户,从服自动复制次条目
mysql>grant all on *.* to 'root'@'%' identified by 'amoebapass';
mysql>flush privileges;
------------------------------------------------------------------
从服
mysql>show grants for root@'%';
| Grantsfor root@%                                                                                           
| GRANTALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD'*84BB5DF4823DA319BBF86C99624479A198E6EEE9' |

 

Amoba

1.安装Amoeba
[root@station253~]# cp /mnt/hgfs/Share64/jdk/jdk-6u31-linux-x64-rpm.bin /tmp
[root@station253tmp]# chmod +x jdk-6u31-linux-x64-rpm.bin
[root@station253tmp]# ./jdk-6u31-linux-x64-rpm.bin
[root@station253tmp]# vim /etc/profile.d/java.sh
exportJAVA_HOME=/usr/java/latest
exportPATH=$JAVA_HOME/bin:$PATH
[root@station253tmp]# . /etc/profile.d/java.sh
[root@station253tmp]# java -version
javaversion "1.6.0_31"
Java(TM)SE Runtime Environment (build 1.6.0_31-b04)
JavaHotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)  混合模式,支持编译
 
[root@station253tmp]# cp /mnt/hgfs/Share64/amoeba/amoeba-mysql-binary-2.2.0.tar.gz .
ameoba不会自行创建目录,手工创建
[root@station253tmp]# mkdir -pv /usr/local/amoeba-2.2.0  #保留版本信息便于后期识别
[root@station253tmp]# tar -zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba-2.2.0
[root@station253tmp]# cd /usr/local/
[root@station253local]#  ln -sv amoeba-2.2.0/ amoeba
"amoeba"-> "amoeba-2.2.0/"
2.添加环境变量
[root@station253local]# vim /etc/profile.d/amoeba.sh
exportAMOEBA_HOME=/usr/local/amoeba
exportPATH=$AMOEBA_HOME/bin:$PATH
[root@station253local]# . /etc/profile.d/amoeba.sh
[root@station253conf]# amoeba
amoeba start|stop
3.配置amoeba服务
[root@station253local]# cd amoeba
[root@station253amoeba]# cp -r conf/ backup
[root@station253amoeba]# ls
backup  benchmark bin  changelogs.txt  conf lib  LICENSE.txt  README.html
[root@station253amoeba]# cd conf
定义数据库读写分离及节点管理信息
[root@station253conf]# vim amoeba.xml
<?xml version="1.0"encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM"amoeba.dtd">
<amoeba:configurationxmlns:amoeba="http://amoeba.meidusa.com/">
<proxy>             #定义代理
<!-- service class must implementscom.meidusa.amoeba.service.Service -->
<service name="Amoeba for Mysql"class="com.meidusa.amoeba.net.ServerableConnectionManager">       #定义服务,由类实现
<!-- port -->     #定义连接池
<!-- <propertyname="port">8066</property> -->  加外括号注释
<property name="port">3306</property>      #定义监听端口,将默认改动为3306
  <!-- bindipAddress -->   #定义代理服务器对外连接的监听IP
 <!--
<propertyname="ipAddress">127.0.0.1</property>
 -->
 <propertyname="ipAddress">0.0.0.0</property>  #定义监听IP地址,这里定义为监听所有IP
<propertyname="manager">${clientConnectioneManager}</property>
 <propertyname="connectionFactory">  #连接池
<beanclass="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">
<propertyname="sendBufferSize">128</property>          #定义发送缓冲大小(可根据主机内存可调整)
 <propertyname="receiveBufferSize">64</property>        #定义接受缓冲的大小(可根据主机内存可调整)
 </bean>
 </property>
 <propertyname="authenticator">           #认证器
  <beanclass="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
 <propertyname="user">root</property>      #客户端连接后端时的用户名
<property name="password">amoebapass</property>      #客户端连接后端时的密码
 <propertyname="filter">
<beanclass="com.meidusa.amoeba.server.IPAccessController">
<propertyname="ipFile">${amoeba.home}/conf/access_list.conf</property>     #只允许哪些客户端访问,基于文件实现访问控制
</bean>
</property>
 </bean>
 </property>
 </service>
<!-- server class must implementscom.meidusa.amoeba.service.Service -->
 <servicename="Amoeba Monitor Server"class="com.meidusa.amoeba.monitor.MonitorServer">  #amoeba的监控服务器,监测每一个后端的工作状态
<!-- port -->
<property name="port">3306</property>   #监控服务器监听的端口,默认注释表示使用随机端口
<!-- bind ipAddress -->
<propertyname="ipAddress">127.0.0.1</property>  #定义监控服务器监听的地址
<propertyname="daemon">true</property>
<propertyname="manager">${clientConnectioneManager}</property>
 <propertyname="connectionFactory">
<beanclass="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory"></bean>
</property>
 </service>
<runtimeclass="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">
<!-- proxy server net IO Read thread size -->
 <propertyname="readThreadPoolSize">20</property>
 <!-- proxyserver client process thread size -->
<property name="clientSideThreadPoolSize">30</property>
 <!-- mysqlserver data packet process thread size -->
<propertyname="serverSideThreadPoolSize">30</property>
 <!-- perconnection cache prepared statement size -->
<propertyname="statementCacheSize">500</property>
 <!-- querytimeout( default: 60 second , TimeUnit:second) -->
<propertyname="queryTimeout">60</property>
 </runtime>
</proxy>
<!--
 EachConnectionManager will start as thread
 managerresponsible for the Connection IO read , Death Detection
-->
<connectionManagerList>   #定义连接池的列表
<connectionManagername="clientConnectioneManager"class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
<propertyname="subManagerClassName">com.meidusa.amoeba.net.ConnectionManager</property>
<!--
default value is avaliable Processors
 <propertyname="processors">5</property>
 -->
 </connectionManager>
<connectionManager name="defaultManager"class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
 <propertyname="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property>
 <!--
  default valueis avaliable Processors
<propertyname="processors">5</property>
  -->
 </connectionManager>
 </connectionManagerList>     #连接池的列表
  <!-- defaultusing file loader -->
<dbServerLoaderclass="com.meidusa.amoeba.context.DBServerConfigFileLoader">
 <propertyname="configFile">${amoeba.home}/conf/dbServers.xml</property>
 </dbServerLoader>
 <queryRouterclass="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">    #定义查询路由
<property name="ruleLoader">
 <beanclass="com.meidusa.amoeba.route.TableRuleFileLoader">
 <propertyname="ruleFile">${amoeba.home}/conf/rule.xml</property>
 <propertyname="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
</bean>
</property>
<propertyname="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
<propertyname="LRUMapSize">1500</property>                            
 <propertyname="defaultPool">station20</property>                   #定义读写服务器,这里默认定义到主服务器上
<propertyname="writePool">station20</property>                     #定义写服务器,若有多个用逗号隔开,这些服务器名来自于dbservers.xml
<propertyname="readPool">station21</property>                      #定义读服务器
 <propertyname="needParse">true</property>
</queryRouter>
</amoeba:configuration>
###############定义连接后端Mysql服务器信息############
[root@node conf]# vim dbServers.xml
<?xml version="1.0"encoding="gbk"?>
<!DOCTYPE amoeba:dbServers SYSTEM"dbserver.dtd">
<amoeba:dbServersxmlns:amoeba="http://amoeba.meidusa.com/">
  <!--
   Each dbServerneeds to be configured into a Pool,
If you need to configure multiple dbServer with loadbalancing that can be simplified by the following configuration:add attributewith name virtual = "true" in dbServer, but the configuration doesnot allow the element with name factoryConfig
 such as'multiPool' dbServer
 -->
 <dbServername="abstractServer" abstractive="true">                 #定义服务器,名字叫抽象服务器,支持抽象功能:公共属性的定义
<factoryConfigclass="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<propertyname="manager">${defaultManager}</property>
 <propertyname="sendBufferSize">64</property>                 #定义发送缓冲大小
<propertyname="receiveBufferSize">128</property>             #接受缓冲的大小
<!-- mysql port -->
 <propertyname="port">3306</property>                         #监听的端口
 <!-- mysqlschema -->
<property name="schema">test</property>                       #默认连接的数据库服务器
<!-- mysql user -->
<property name="user">root</property>                         #用户名
 <!--  mysql password   -->                                   -->上移与<!- 配对,取消下行注释
 <propertyname="password">amoebapass</property>                 #后端服务器的密码,授权用户密码
 </factoryConfig>
<poolConfigclass="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
 <propertyname="maxActive">500</property>                      #定义最大活动连接数
 <propertyname="maxIdle">500</property>                        #空闲连接数
 <propertyname="minIdle">10</property>                         #最少空闲连接数
 <propertyname="minEvictableIdleTimeMillis">600000</property>
 <propertyname="timeBetweenEvictionRunsMillis">600000</property>
   <propertyname="testOnBorrow">true</property>
  <propertyname="testOnReturn">true</property>
<propertyname="testWhileIdle">true</property>
 </poolConfig>
</dbServer>
 <dbServername="station20"  parent="abstractServer">           #定义服务器,其父服务器就是上面的"abstractServer"继承其属性,若不想请添加属性实现定义
 <factoryConfig>
 <!-- mysql ip-->
  <propertyname="ipAddress">192.168.1.20</property>           #server1的IP地址
</factoryConfig>
 </dbServer>
<dbServer name="station21"  parent="abstractServer">          #server1的IP地址
<factoryConfig>
  <!-- mysqlip -->
 <propertyname="ipAddress">192.168.18.21</property>
 </factoryConfig>
</dbServer>
<dbServer name="multiPool"virtual="true">                          #定义虚拟服务器组
<poolConfigclass="com.meidusa.amoeba.server.MultipleServerPool">
 <!-- Loadbalancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->      #算法:1表示轮询,2:基于权重做轮询,3:高可用效果
 <propertyname="loadbalance">1</property>          #还可以实现负载均衡,算法为1
 <!--Separated by commas,such as: server1,server2,server1 -->
 <propertyname="poolNames">station20,station21</property>             #此处一定是定义的dbname
 </poolConfig>
       </dbServer>
</amoeba:dbServers>
4.启动Amoeba
[root@station253conf]# amoeba start
log4j:WARNlog4j config load completed from file:/usr/local/amoeba/conf/log4j.xml
2014-05-2505:05:40,143 INFO context.MysqlRuntimeContext - Amoeba for Mysql currentversoin=5.1.45-mysql-amoeba-proxy-2.2.0  #检测后端mysql服务器兼容版本
log4j:WARNip access config load completed fromfile:/usr/local/amoeba/conf/access_list.conf
2014-05-2505:05:40,415 INFO  net.ServerableConnectionManager- Amoeba for Mysql listening on /0.0.0.0:3306. #监听地址及端口
2014-05-2505:05:40,427 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on/127.0.0.1:23679.  #管理地址及端口(随机)
##########停止amoeba###########
Ctrl+C
#########使用后端启动##########
[root@station253conf]# amoeba start &
#########后端启动服务时停止####
[root@station253conf]# amoeba stop
amoebaserver shutting down with port=11422
###########查看监听端口########
[root@station253conf]# ss -natlp | grep 3306
LISTEN     0     128      :::3306         :::*     users:(("java",2467,50))

5.测试连接

[root@station253conf]# mysql -uroot -pamoebapass -h192.168.1.253
YourMySQL connection id is 432598870  前端连接的是代理服务器amoeba
Serverversion: 5.1.45-mysql-amoeba-proxy-2.2.0 MySQLCommunity Server (GPL)
mysql>select version();  显示后端数据库版本
+------------+
|version()  |
+------------+
|5.6.13-log |
+------------+
测试读写分离是否到各自服务器
前端 读库
mysql>select user,host from mysql.user;   在读写分离后,select必须用库名+表名,因为默认路由是到test库
+------+-----------------------+
| user |host                  |
+------+-----------------------+
| root |%                     |
| root |127.0.0.1             |
| root |::1                   |
|      | localhost             |
| root |localhost             |
|      | station21.example.com |
| root |station21.example.com |
+------+-----------------------+
后端2服务器提前启用tcpdump抓包
[root@station21~]# tcpdump -i eth0 -A -nn -s0 tcp dst port 3306 and ip dst host 192.168.1.21
tcpdump:verbose output suppressed, use -v or -vv for full protocol decode
listeningon eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
07:20:03.771162IP 192.168.1.253.39815 > 192.168.1.21.3306: Flags [P.], select user,host from mysql.user
前端 写库
mysql>create database school;  
[root@station20~]# tcpdump -i eth0 -A -nn -s0 tcp dst port 3306 and ip dst host 192.168.1.20
tcpdump:verbose output suppressed, use -v or -vv for full protocol decode
listeningon eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
07:21:30.426165IP 192.168.1.253.33837 > 192.168.1.20.3306: Flags [P.], create database school
mysql>drop database school;  drop会先drop写库后select读库确认删除
07:33:40.080159IP 192.168.1.253.33849 > 192.168.1.20.3306: Flags [P.], drop database school
07:33:40.410321IP 192.168.1.253.39825 > 192.168.1.21.3306: Flags [P.], SELECT DATABASE()





你可能感兴趣的:(读写,amoeba,分离)