平台:主从均是Window XP
软件:Amoeba 2.0.1-beta
mysql 5.0.22
IP:主:192.168.1.104
从:192.168.1.114
1. amoeba安装
将文件amoeba-mysql-binary-2.0.1-BETA.tar.gz解压到存放的目录中。我以C:\ProgramFiles\下为例。添加环境变量C:\Program Files\amoeba-mysql-binary-2.0.1-BETA\bin和C:\ProgramFiles\amoeba-mysql-binary-2.0.1-BETA。
2. 测试安装
使用命令amoeba可以得出下面输出表示安装成功:
3. 先配置实现amoba的代理能力
修改amoeba.xml文件为如下:
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
<proxy>
<!-- server class must implements com.meidusa.amoeba.service.Service -->
<service name="Amoeba for Mysql" class="com.meidusa.amoeba.net.ServerableConnectionManager">
<!-- port -->
<property name="port">8066</property>
<!-- bind ipAddress -->
<!--
<property name="ipAddress">127.0.0.1</property>
-->
<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>
<property name="password">password</property>
<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">
<!-- 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>
<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">server1</property>
<!--
<property name="writePool">server1</property>
<property name="readPool">server1</property>
-->
<property name="needParse">true</property>
</queryRouter>
</amoeba:configuration>
代码中带有标号的表示做了修改的,说明如下:
Service节点定义了需要启动的服务,在本配置中其class属性为“com.meidusa.amoeba.net.ServerableConnectionManager”,这意味着这是一个Proxy Service(就目前而言)。在这个元素下的connectionFactory元素中定义其class属性为“com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory”,这意味着这是一个MySQL Proxy Service。相应的也会有MongoDB Proxy Service以及Aladdin Proxy Service。 | |
这里定义了之前我们所定义的MySQL Proxy Service的服务端口和主机地址。 Caution 通常Proxy Service服务的主机地址并不需要定义,如果Amoeba所在的服务器在多个网络环境内你可以定义该机器的其中一个IP来指定Amoeba所服务的网络环境。如果设置为127.0.0.1将导致其他机器无法访问Amoeba的服务。 | |
这里配置了MySQL Proxy Service的认证器,user和passwd属性分别定义Amoeba对外服务的用户名和密码。你的程序或者数据库客户端需要使用该用户名和密码来通过Amoeba连接之前定义的dbServer。 | |
runtime元素定义了一些Proxy相关的运行期配置,如客户端及数据库服务器端的线程数以及SQL超时时间设定等等。 | |
connectionManagerList定义了一系列连接管理器,这些连接管理器可以在其他地方被引用,比如clientConnectioneManager在amoeba.xml中被引用作为MySQL Proxy Service的客户端连接管理器;defaultManager在dbServers.xml中被引用作为dbServer的数据库服务器端连接管理器。连接管理器主要配置了用于网络处理的CPU核数,默认其processor属性为Amoeba所在主机的CPU核数。 | |
最后一部分dbServerLoader定义了dbServers.xml的位置。queryRouter定义了规则配置及函数配置等相关文件的位置。 |
4. 测试代理功能
在cmd中先使用命令amoeba start启动amoeba,然后使用命令:
mysql –u root –p hzh –h 192.168.1.104 –P 8066
以amoeba为代理进入mysql,注意上面的命令端口已经改为8066,8066是amoeba的端口。成功的话应该得到如下界面:
观察输出信息可以看出输出信息中有amoeba的版本信息了,表示可以正常的使用amoeba作为mysql的代理了。
5. 配置简单读写分离
这里假设不配置数据切片功能,那在amoeba.xml中做如下的配置:
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd">
<amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">
...
<dbServer name="Master" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.0.1</property>
</factoryConfig>
</dbServer>
<dbServer name="Slave1" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.0.2</property>
</factoryConfig>
</dbServer>
<dbServer name="Slave2" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.0.3</property>
</factoryConfig>
</dbServer>
<dbServer name="virtualSlave" virtual="true">
<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">Slave1,Slave2</property>
</poolConfig>
</dbServer>
...
</amoeba:dbServers>
修改的位置说明如下表:
定义了Master节点,parent为abstractServer,关于abstractServer的定义方式参照第三章。 | |
定义了Slave1和Slave2节点。 | |
定义了virtualSlave的虚拟节点,这是由Slave1和Slave2组成的一个数据库池。 | |
loadbalance元素设置了loadbalance策略的选项,这里选择第一个“ROUNDROBIN”轮询策略,该配置提供负载均衡、failOver、故障恢复功能。 | |
poolNames定义了其中的数据库节点配置(当然也可以是虚拟的节点)。此外对于轮询策略,poolNames还定义了其轮询规则,比如设置成“Slave1,Slave1,Slave2”那么Amoeba将会以两次Slave1,一次Slave2的顺序循环对这些数据库节点转发请求。 |
我的配置结果如下: <?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
<proxy>
<!-- server class must implements com.meidusa.amoeba.service.Service -->
<service name="Amoeba for Mysql" class="com.meidusa.amoeba.net.ServerableConnectionManager">
<!-- port -->
<property name="port">8066</property>
<!-- bind ipAddress -->
<!-- -->
<property name="ipAddress">192.168.1.104</property>
<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>
<property name="password">hzh</property>
<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">192.168.1.104</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">
<!-- 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>
<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">server1</property>
<!---->
<property name="writePool">server1</property>
<property name="readPool">server2</property>
<property name="needParse">true</property>
</queryRouter>
</amoeba:configuration>
6. 测试
上面的配置就实现了在192.168.1.104上写,在192.168.1.104上读的分离了。下面做如下测试,在192.168.1.104上进行一次插入操作,然后通过amoeba读刚刚插入的数据,结果可以读出,而192.168.1.104上面是没有这个数据的,说明实现了读分离。写分离的测试需要先关掉主从复制,不然看不到效果。