基于Amoeba的MySQL读取分离

上一篇刚记录下MySQL的主从复制配置,这就要搞读取分离了,正好也记录下配置及遇到的小问题。

一、Amoeba 是什么

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

  • 降低 数据切分带来的复杂多数据库结构
  • 提供切分规则并降低 数据切分规则 给应用带来的影响
  • 降低db 与客户端的连接数
  • 读写分离

二、为什么要用Amoeba

目前要实现mysql的主从读写分离,主要有以下几种方案:
1、 通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。
2、 通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。
3、 自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。
4、 利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。

三、快速架设amoeba,实现mysql主从读写分离

amoeba的前提条件:

  • Java SE 1.5 或以上 Amoeba 框架是基于JDK1.5开发的,采用了JDK1.5的特性。
  • 支持Mysql 协议版本10(mysql 4.1以后的版本)。
  • 网络环境至少运行有一个mysql 4.1以上的服务(本文中使用的是MySQL5.5)

1、首先介绍下本文的实验环境。

  • System: Windows
  • Master mysql:192.168.1.194
  • Slave mysql:192.168.1.223
  • Amoeba server: 192.168.1.194

架构如如下所示:

本文只用了一个主、一个从服务器

2、安装配置mysql主从环境及用户,上一篇已介绍不再赘述,有需要烦请自行查找。

3、安装JDK环境
下载jdk1.5或者更新版本,地址 http://java.sun.com/javase/downloads/index.jsp
本文的是之前项目需要装的:jdk-8u151-windows-x64.exe
下载安装后,配置环境变量

4、下载解压Amoeba及配置代理读写分离
因为只有两台服务器,所以Amoeba安装在192.168.1.194上(即MySQL主服务器上)
本文使用2.0版本 请下载2.0

下载https://sourceforge.net/projects/amoeba/files/

直接下载3x https://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/3.x/amoeba-mysql-3.0.5-RC-distribution.zip/download

直接下载2x https://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz/download

修改配置文件:
1)、打开conf/ amoeba.xml配置文件,修改以下位置
这个service是提供给访问数据库的程序使用的.也就是别人连接数据库需要配置的东西
分别为,端口,默认为8066
用户名:可以随便写
密码:可以随便写

<!-- service 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.194</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">123456</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>

最下边把注释打开,配置writePool,readPool,这里边对应的是dbServers.xml 配置文件里边的两个数据库dbServer的name

<!-- conf/rule.xml中的tableRule优先于此处的queryRouter,只有rule.xml中tableRule未匹配到数据库或表才次级匹配当前queryRouter -->
    <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>

        <!--这里配置了默认的数据库节点,一些除了SELECT\UPDATE\INSERT\DELETE的语句都会在defaultPool执行 -->
        <property name="defaultPool">writePool</property>       

        <!--这里配置了数据库写库,通常配为Master,如这里就配置为之前定义的Master数据库 -->
        <property name="writePool">writePool</property>

        <!--这里配置了数据库读库,通常配为Slave或者Slave组成的数据库池,如这里就配置conf/dbServer.xml的virtualSlave数据库池-->
        <property name="readPool">virtualslave</property>

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

打开dbServers.xml,配置 端口,用户名,密码

<!--配置数据库端口、用户名、密码,如两个服务器端口、用户名、密码不一致,需再增加一个以便于读写配置继承;本次两个服务器数据库均一致,所以只配置了一个-->
<dbServer name="abstractServer" abstractive="true">
        <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
            <property name="manager">${defaultManager}</property>
            <property name="sendBufferSize">64</property>
            <property name="receiveBufferSize">128</property>

            <!-- mysql port -->
            <property name="port">3306</property>

            <!-- mysql schema -->
            <property name="schema">test</property>

            <!-- mysql user -->
            <property name="user">root</property>

            <!-- mysql password -->
            <property name="password">123456</property>

        </factoryConfig>

        <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
            <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对应上一个配置文件(amoeba.xml)里边的server 读写的配置; 192.168.1.194是写入数据库,192.168.1.223是读取数据库,因为两个库的用户名密码都一样的,所以直接继承上面的server配置的信息就可以了.如果不一样需要单独配置.最下边是连接池配置.

<!-- 写入服务器-->
    <dbServer name="writePool"  parent="abstractServer" virtual="true">
        <factoryConfig>
            <!-- mysql ip -->
            <property name="ipAddress">192.168.1.194</property>
        </factoryConfig>
    </dbServer>
    <!-- 读取服务器 -->
    <dbServer name="readPool"  parent="abstractServer" virtual="true">
        <factoryConfig>
            <!-- mysql ip -->
            <property name="ipAddress">192.168.1.223</property>
        </factoryConfig>
    </dbServer>

    <!-- 交替读写 -->
    <dbServer name="virtualslave" virtual="true">
        <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
            <!-- Loadbalancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
            <property name="loadbalance">1</property>

            <!--Separated by commas,such as: server1,server2,server1 -->
            <property name="poolNames">writePool,readPool,readPool,readPool</property>
        </poolConfig>
    </dbServer>

然后保存,启动
打开cmd 切换到Amoeba目录下的bin目录,执行如下命令启动:

amoeba start

如果配置环境变量了,可以直接启动.否则需要切换到程序目录下.
这里写图片描述

5、 测试
测试之前先要保证amoeba-server有访问两个主从服务器test库的权限,在主从mysql上都执行:

grant all on test.* to 'root'@'192.168.1.%' identified by '123456';

测试的时候和平时使用一样,amoeba-mysql对应用透明,就是个mysql的代理!
登录mysql使用如下命令(用户名密码和上面配置(amoeba.xml中authenticator下的user和password)的要一致):

mysql -uroot -p123456 -h192.168.1.194 -P8066

登录上去后,为了测试读和写必须,先把mysql的主从复制停掉,才能更清楚地看出读写的服务器是哪台,在从服务器上使用

stop slave;

登录到amoeba-mysql上,使用命令

mysql -uroot -ppassword -h192.168.1.159 -P8066

然后执行写和读操作,查看写的是哪台服务器,读的是哪台服务器,
实验结果显示:写只在主上进行,读在主和从都进行,比率是1:1

1)、测试步骤:
还没有停掉从同步之前,创建一个表:

create table zhang (id int(10) ,name varchar(10),address varchar(20));

在从服务器上执行

stop slave;

然后在主从服务器数据库上各插入一条不同数据(供测试读的时候用),
在主上插入:

insert into zhang values('1','zhang','this_is_master');

在从上插入:

insert into zhang values('2','zhang','this_is_slave');

接下来通过登录amoeba-mysql上来测试读写:
这里写图片描述


—-至此,基于Amoeba的MySQL读取分离基本配置完成,以后遇到问题会再次补充。
—-另外,关于Amoeba的数据切分规则配置认知还不完全,了解后有机会也会进行补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值