实现mysql 数据集群的读写分离之 amoeba

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:




服务器配置:

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 ALL PRIVILEGES ON *.* TO 'amoeba'@'192.168.240.130' IDENTIFIED BY 'amoeba' WITH  GRANT OPTION;

mysql> FLUSH  PRIVILEGES;

Amoeba作为数据库代理,以中间件的形式存在,拓扑图如下所示:


wKiom1fyVxPDej7tAAEqMnQoOWY154.png


图片来源于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">amoeba</property>

                          <!—-登录amoeba的密码 -->

                    <property name="password">amoeba</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

wKiom1fycTvy7RWqAAA78gAiM3k690.png-wh_50

登录master

wKiom1fycQbxGnqoAAAptO_WP-g391.png-wh_50


登录slave,可以看到slave 上并没有刚才新建master数据库。

wKioL1fycYfi-wrnAAAmGK9H4XI594.png-wh_50


现在登录slave节点,并新建一个slave数据库

wKiom1fycouiDHShAAA1hRUQB0s784.png-wh_50


登录amoeba查看,是否有slave这个数据库,再试试是否可以切换到slave这个数据库:

wKiom1fyfEPTTs2AAABjAobs7qI668.png

从上面可以看到,虽然show不出slave数据库 ,但是可以切换到slave数据库。虽然看起来有点矛盾,因为show也算是查询的一种操作,却没有从slave节点上显示slave数据库,这点应该是dbServer.xml里将master写服务器设置,而不是将slave读服务器设为默认造成的。


至此目的算是达到了。


附两个实验中遇到的错误信息及解决方法:


1.提示:ERROR:JAVA_HOME environment variable is not set

[root@chenllcentos ~]dir /usr/java/    看看是什么版本号,我的是jdk1.8.0_91,没有就去下载安装吧。要1.5以上http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html


[root@chenllcentos ~]vim /etc/profile       在文件最末添加以下三行。

JAVA_HOME=/usr/java/jdk1.8.0_91/
PATH=$PATH:JAVA_HOME/bin 
export JAVA_HOME PATH 


2.启动时提示:

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的帐号的,这样也方便管理。






      本文转自笔下生辉  51CTO博客,原文链接:http://blog.51cto.com/752030200/1858652,如需转载请自行联系原作者




相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6天前
|
SQL 前端开发 关系型数据库
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
17 0
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
|
11天前
|
关系型数据库 MySQL 数据库
mysql 里创建表并插入数据
【10月更文挑战第5天】
79 1
|
13天前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
38 3
|
13天前
|
消息中间件 分布式计算 关系型数据库
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
32 0
|
6天前
|
存储 关系型数据库 MySQL
面试官:MySQL一次到底插入多少条数据合适啊?
本文探讨了数据库插入操作的基础知识、批量插入的优势与挑战,以及如何确定合适的插入数据量。通过面试对话的形式,详细解析了单条插入与批量插入的区别,磁盘I/O、内存使用、事务大小和锁策略等关键因素。最后,结合MyBatis框架,提供了实际应用中的批量插入策略和优化建议。希望读者不仅能掌握技术细节,还能理解背后的原理,从而更好地优化数据库性能。
|
14天前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
54 0
|
14天前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
27 0
|
9天前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
43 6
|
7天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
39 3
Mysql(4)—数据库索引
|
9天前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
27 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用