Mysql+amoeba实现数据库读写分离

Posted BLotus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql+amoeba实现数据库读写分离相关的知识,希望对你有一定的参考价值。



一、Amoeba 是什么

Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发。座落与ClientDB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。

主要解决:

• 降低 数据切分带来的复杂多数据库结构

• 提供切分规则并降低 数据切分规则 给应用带来的影响

• 降低db 与客户端的连接数

• 读写分离

 

二、为什么要用Amoeba

目前要实现mysql的主从读写分离,主要有以下几种方案:

1  通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。

2  通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。

3  自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。

4  利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。

 

三、Amoeba的安装

先介绍下部署环境:

amoeba:192.168.18.231

masterDB192.168.18.232

slaveDB192.168.18.230

以上系统全为centos7 

 

部署前先部署mysql主从服务

mysql主从部署略

 

Amoeba框架是居于JDK1.5开发的,采用了JDK1.5的特性,所以还需要安装java环境,建议使用javaSE1.5以上的JDK版本

安装java环境

先去官网下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

 

一、  安装jdk

1)      查看当前版本命令:

java -version

2)      创建java安装目录

#sudo mkdir /usr/java

#cd /home/install

3)      拷贝到安装目录

#sudo cp jdk-7u80-linux-x64.tar.gz/usr/java/

#cd /usr/java

#sudo tar -zxvf jdk-7u80-linux-x64.tar.gz

#ln -s /amoeba/jdk1.7.0_80/ /amoeba/jdk

4)      修改配置文件

更改 /etc/profile 文件:

sudo vim /etc/profile 

export JAVA_HOME=/amoeba/jdk1.7.0_80

export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH

export PATH=$JAVA_HOME/bin:$PATH

Mysql+amoeba实现数据库读写分离

 

5)      将信息导入

#source /etc/profile然后设置java环境变量

测试是否安装成功

 #java -version

 

二、    安装配置Amoeba

1.     安装amoeba

可以从https://sourceforge.net/projects/amoeba/下载最新版本的Amoeba,我这里下载的是amoeba-mysql-3.0.5-RC-distribution.zipAmoeba安装非常简单,直接解压即可使用,这里将Amoeba解压到/usr/local/amoeba目录下,这样就安装完成了

#unzip amoeba-mysql-3.0.5-RC-distribution.zip -d /usr/local/

#cd /usr/local

#mv amoeba-mysql-3.0.5-RC-distribution amoeba

#cd amoeba

 

2.     配置dbServers.xml

Amoeba的配置文件在本环境下位于/usr/local/amoeba/conf目录下。配置文件比较多,但是仅仅使用读写分离功能,只需配置两个文件即可,分别是dbServers.xmlamoeba.xml,如果需要配置ip访问控制,还需要修改access_list.conf文件,下面首先介绍dbServers.xml

 

[root@blotus amoeba]# cat conf/dbServers.xml

<?xml version="1.0" encoding="gbk"?>

 

<!DOCTYPEamoeba:dbServers SYSTEM "dbserver.dtd">

<amoeba:dbServersxmlns:amoeba="http://amoeba.meidusa.com/">

 

        <!--

            Each dbServer needs to beconfigured into a Pool,

            If you need to configure multipledbServer with load balancing that can be simplified by the followingconfiguration:

             add attribute with name virtual = "true"in dbServer, but the configuration does notallow the element with name factoryConfig

             such as 'multiPool'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 -->

          <property name="port">3306</property>  

#设置Amoeba要连接的mysql数据库的端口,默认是3306

           

           <!--mysql schema -->

         <property name="schema">testdb</property>  

#设置缺省的数据库,当连接amoeba时,操作表必须显式的指定数据库名,即采用dbname.tablename的方式,不支持 use dbname指定缺省库,因为操作会调度到各个后端dbserver

            

           <!--mysql user -->

         <property name="user">zhangsan</property>  

#设置amoeba连接后端数据库服务器的账号和密码,因此需要在所有后端数据库上创建该用户,并授权amoeba服务器可连接

           

         <property name="password">123456</property>

        </factoryConfig>

 

        <poolConfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">

           <property name="maxActive">500</property>  

#最大连接数,默认500

           <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>

 

<dbServer name="master"  parent="abstractServer">  

#设置一个后端可写的dbServer,这里定义为master,这个名字可以任意命名,后面还会用到

        <factoryConfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.18.232</property>

#设置后端可写dbserver

        </factoryConfig>

    </dbServer>

   

<dbServer name="slave" parent="abstractServer">  

#设置后端可读dbserver

        <factoryConfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.18.230</property>

        </factoryConfig>

    </dbServer>

   

<dbServer name="readserver" virtual="true">  

#设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为readserver

        <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">

            <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

            <property name="loadbalance">1</property>  #选择调度算法,1表示复制均衡,2表示权重,3表示HA, 这里选择1

           

            <!-- Separated by commas,such as:server1,server2,server1 -->

            <property name="poolNames">slave,master</property>  #readserver组成员

        </poolConfig>

    </dbServer>

       

</amoeba:dbServers>

 

3.     另一个配置文件amoeba.xml

[root@blotus amoeba]# cat conf/amoeba.xml

<?xml version="1.0" encoding="gbk"?>

 

<!DOCTYPEamoeba: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.mysql.server.MySQLService">

            <!-- port -->

            <property name="port">8066</property>  

#设置amoeba监听的端口,默认是8066

           

            <!--bind ipAddress -->    

#下面配置监听的接口,如果不设置,默认监听所以的IP

            <!--

           <property name="ipAddress">192.168.18.231</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时需要使用这里设定的账号 (这里的账号密码和amoeba连接后端数据库服务器的密码无关)

                    <property name="user">root</property>    

                    

                    <property name="password">123456</property>

                   

                    <property name="filter">

                        <bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">

                            <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>

                        </bean>

                    </property>

                </bean>

            </property>

           

        </service>

       

        <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">

           

            <!-- proxy server client processthread size -->

            <property name="executeThreadSize">128</property>

           

            <!-- per connection cache preparedstatement size  -->

            <property name="statementCacheSize">500</property>

           

            <!-- default charset -->

            <property name="serverCharset">utf8</property>

           

            <!-- query timeout( default: 60 second , TimeUnit:second) -->

            <property name="queryTimeout">60</property>

        </runtime>

       

    </proxy>

   

    <!--

        Each ConnectionManager will start asthread

        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>

    </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>  

#设置amoeba默认的池,这里设置为master

       

       

       <property name="writePool">master</property>  

#这两个选项默认是注销掉的,需要取消注释,这里用来指定前面定义好的俩个读写池

       <property name="readPool">readserver</property>   

       

        <property name="needParse">true</property>

    </queryRouter>

</amoeba:configuration>

 

4.     修改# cat /usr/local/amoeba/jvm.properties

JVM_OPTIONS="-server-Xms256m -Xmx1024m -Xss300k -XX:PermSize=16m -XX:MaxPermSize=96m"

 

 

5.     分别在masterdb和slavedb上为amoedb授权 

mysql> GRANTALL ON *.* TO 'zhangsan'@'%' IDENTIFIED BY '123456';

Query OK, 0 rows affected (0.05 sec)

 

mysql> flushprivileges;

Query OK, 0 rows affected (0.02 sec)

 

 

6.     启动amoeba

[root@blotusamoeba]# nohup/usr/local/amoeba/bin/launcher &

Error: JAVA_HOMEenvironment variable is not set.

[root@blotusamoeba]# vim /etc/profile

[root@blotusamoeba]# source /etc/profile

[root@blotus amoeba]# nohup /usr/local/amoeba/bin/launcher &

 

 

7.     查看端口

[root@blotus ~]# netstat -tulnp | grep java


由此可知Amoeba启动正常

 

8.     测试

[root@blotus ~]# mysql -h192.168.18.231 -uroot -p -P8066

 

 

9.     结果

经测试读库读表写库写表写数据都是连接的主服务器,

只有读数据库数据是在从服务器。

 

10.附:

数据库服务器配置文件($AMOEBA_HOME/conf/dbServers.xml),用来存储和配置Amoeba所代理的数据库服务器的信息,如:主机IP、端口、用户名、密码等。

切分规则配置文件($AMOEBA_HOME/conf/rule.xml),用来配置切分规则。

数据库函数配置文件($AMOEBA_HOME/conf/functionMap.xml),用来配置数据库函数的处理方法,Amoeba将使用该配置文件中的方法解析数据库函数。

切分规则函数配置文件($AMOEBA_HOME/conf/ruleFunctionMap.xml),用来配置切分规则中使用的用户自定义函数的处理方法。

访问规则配置文件($AMOEBA_HOME/conf/access_list.conf),用来授权或禁止某些服务器IP访问Amoeba

日志规格配置文件($AMOEBA_HOME/conf/log4j.xml),用来配置Amoeba输出日志的级别和方式。


amoeba使用指南

http://docs.hexnova.com/amoeba/index.html

 


以上是关于Mysql+amoeba实现数据库读写分离的主要内容,如果未能解决你的问题,请参考以下文章

Amoeba+Mysql 实现读写分离

Amoeba 实现MySQL读写分离

Amoeba来实现mysql读写分离

Amoeba实现mysql读写分离

MySQL基于Amoeba实现读写分离

利用amoeba(变形虫)实现mysql数据库读写分离