首页 > 代码库 > 实现mysql 数据集群的读写分离之 amoeba
实现mysql 数据集群的读写分离之 amoeba
服务器配置:
amoeba :192.168.240.130
master写服务器:192.168.240.129
slave读服务器 :192.168.240.128
mysql主从配置............略,可参照:http://752030200.blog.51cto.com/8936921/1853460
Amoeba数据库代理
前提条件应该把所有数据库节点的密码进行统一,并允许将要配置的amoeba的IP进行连接。
以下说明和配置文件信息引用自https://my.oschina.net/u/1169079/blog/390726 并自己在dbServer.xml和amoeba.xml部分做注释,用蓝色字体标识
mysql> GRANT ALLPRIVILEGES ON *.* TO ‘root‘@‘192.168.240.130‘ IDENTIFIED BY ‘root‘ WITH GRANTOPTION;
mysql> FLUSHPRIVILEGES;
Amoeba作为数据库代理,以中间件的形式存在,拓扑图如下所示:
图片来源于Amoeba官网。
目前Amoeba for Mysql最新版本为amoeba-mysql-3.0.5-RC-distribution.zip。
安装过程很简单,只需要将zip压缩包解压至/usr/local/即可。若没有安装zip和unzip,可以通过centOS yum安装。
[root@chenllcentos ~]# yum -y install zip unzip
接下来,解压Amoeba压缩包。
[root@chenllcentos ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip
[root@chenllcentos ~]# cp -rf amoeba-mysql-3.0.5-RC /usr/local
用 Amoeba 实现 mysql 读写分离,只需要分别对dbServers.xml和amoeba.xml两个配置文件进行配置即可,这有利于系统扩展和维护。
首先是配置dbServers.xml,主要是配置真实Mysql数据库连接信息。
<?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节点abstractive="true",包含Mysql的公共配置信息,其他dbServer节点都继承该节点 -->
<!-- 设置节点配置的继承结构,可以避免重复配置相同信息,减少配置文件冗余 -->
<dbServer name="abstractServer" abstractive="true">
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="connectionManager">${defaultManager}</property>
<property name="sendBufferSize">64</property>
<property name="receiveBufferSize">128</property>
<!-- mysql port -->
<!-- Mysql默认端口 -->
<property name="port">3306</property>
<!-- mysql schema -->
<!-- 默认连接的数据库,若不存在需要事先创建,否则Amoeba启动报错 -->
<property name="schema">test</property>
<!-- mysql user mysql用户名-->
<property name="user">root</property>
<!-- mysql password mysql密码-->
<property name="password">root</property>
</factoryConfig>
<poolConfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">
<property name="maxActive">500</property>
<property name="maxIdle">500</property>
<property name="minIdle">1</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>
<!--以上是mysql节点公共信息设置-->
<!--下是真实MYSQL服务器master和slave相关信息-->
<!-- master节点继承abstractServer -->
<dbServer name="master" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<!-- master数据库主机地址 -->
<property name="ipAddress">192.168.240.129</property>
</factoryConfig>
</dbServer>
<!-- slave 节点继承abstractServer -->
<dbServer name="slave" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<!-- slave数据库主机地址 -->
<property name="ipAddress">192.168.240.128</property>
</factoryConfig>
</dbServer>
<!--配置 读取数据库节点池 -->
<dbServer name="readPool" 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">slave</property>
</poolConfig>
</dbServer>
</amoeba:dbServers>
可以看出,对dbServers.xml文件的配置,主要就是对dbServer节点的配置。其中,readPool节点需要特别注意,因为Amoeba实现读写分离就是根据它来实现。
接下来是 amoeba.xml,主要是配置代理数据库连接信息。
<?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.mysql.server.MySQLService">
<!-- port -->
<property name="port">8066</property>
<!-- bind ipAddress amoeba 服务IP 单网卡可以不配置,双网卡必须配置-->
<property name="ipAddress">192.168.240.130</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="authenticateProvider">
<bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
<!—-登录amoeba的用户名 -->
<property name="user">root</property>
<!—-登录amoeba的密码 -->
<property name="password">root</property>
<!—-设置amoeba过滤信息(安全控制) -->
<property name="filter">
<bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">
<property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
<!--允许登录amoeba的列表文件 -->
</bean>
</property>
</bean>
</property>
</service>
<runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">
<!-- proxy server client process thread size 设置客户端及数据库服务器端的线程数-->
<property name="executeThreadSize">128</property>
<!-- per connection cache prepared statement size -->
<property name="statementCacheSize">500</property>
<!-- default charset 设置amoeba默认字符集-->
<property name="serverCharset">utf8</property>
<!-- query timeout( default: 60 second , TimeUnit:second) 设置登录amoeba超时时间,单位秒-->
<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="defaultManager" class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper">
<property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManager</property>
</connectionManager>
</connectionManagerList>
<!-- default using file loader -->
<dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">
<property name="configFile">${amoeba.home}/conf/dbServers.xml</property>
<!—-调用dbServers.xml配置文件 -->
</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>
<!—- sql解析功能调用-->
<property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
<property name="LRUMapSize">1500</property>
<!—- 设置默认数据库节点,当然是写的节点-->
<property name="defaultPool">master</property>
<!—- 设置写数据库节点-->
<property name="writePool">master</property>
<!—-设置只读数据库节点 -->
<property name="readPool">readPool</property>
<!—-设置是否需要解析sql语句,当然是要的(true),要不怎么实现读写分离呢,是吧 -->
<property name="needParse">true</property>
</queryRouter>
</amoeba:configuration>
在amoeba.xml中,主要完成连接信息和SQL路由配置。在queryRouter节点中,通过配置writePool和readPool可以实现读写分离。
配置完成后,重启Amoeba。
[root@chenllcentos ~]# /usr/local/amoeba-mysql-3.0.5-RC/bin/shutdown
[root@chenllcentos ~]# /usr/local/amoeba-mysql-3.0.5-RC/bin/launcher
至此,Mysql主从复制和使用Amoeba实现数据库读写分离全部配置完成。
启动amoeba:
[root@chenllcentos ~]# chmod +x /usr/local/amoeba-mysql-3.0.5-RC/bin/launcher
[root@chenllcentos ~]# /usr/local/amoeba-mysql-3.0.5-RC/bin/launcher&
启动amoeba需要将amoeba进程丢到后台,要不会一直停留在前台,做不了其他事。这时可以用CTRL+Z 暂停amoeba进程,再输入bg命令进行后台继续运行。
读写分离验证
思 路:在不进行主从备份的情况下,登录amoeba进行新建一个数据库,这时应该只要master写服务器存在新建的数据库,从是没有的。然后登录slave服务器在上面新建一个数据库AA,然后在amoeba上进程use AA 是可以切换数据库的,但是是不能操作的。
登录amoeba :
[root@chenllcentos ~]mysql -u root -p root -h192.168.240.130 -P8066
登录master
登录slave,可以看到slave 上并没有刚才新建master数据库。
现在登录slave节点,并新建一个slave数据库
登录amoeba查看,是否有slave这个数据库,再试试是否可以切换到slave这个数据库:
从上面可以看到,虽然show不出slave数据库 ,但是可以切换到slave数据库。虽然看起来有点矛盾,因为show也算是查询的一种操作,却没有从slave节点上显示slave数据库,这点应该是dbServer.xml里将master写服务器设置,而不是将slave读服务器设为默认造成的。
至此目的算是达到了。
附两个实验中遇到的错误信息及解决方法:
1.启动时提示:
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
从错误文字上看,应该是由于stack size太小,导致JVM启动失败
其实Amoeba已经考虑到这个问题,并将JVM参数配置写在属性文件里。现在,让我们通过该属性文件修改JVM参数。
修改jvm.properties文件JVM_OPTIONS参数。
[root@chenllcentos ~]# vi /usr/local/amoeba-mysql-3.0.5-RC/jvm.properties
将内容:
JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m"
替换为:
JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k -XX:PermSize=16m -XX:MaxPermSize=96m"
2.可以登录amoeba却不可能做任何操作,哪怕只是show databases; 也会提示出错信息:
ERROR 1044 (42000): poolName=multiPool, no valid pools 或其他
查看amoeba安装目录下的日志文件root.log,发现在大量的error:Access denied for user
‘root‘@‘192.168.240.130‘ (using password: YES),hashCode=1496580638,由此可以推断是amoeba连接上mysql服务节点没有权限而造成拒绝访问。
解决办法是更新各mysql节点中amoeba.xml文件里的对应的用户和密码信息。
mysql> update user set password=password("root") where user="root";
这里是因为amoeba的登录信息和mysql的节点是一致的,所以就更新root的信息了,其实还是有必要让amoeba的帐号区别于mysql的帐号的,这样也方便管理。
完
本文出自 “烂笔头博客” 博客,转载请与作者联系!
实现mysql 数据集群的读写分离之 amoeba