Mysql 基于 Amoeba 的 读写分离

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 首先说明一下amoeba 跟 MySQL proxy在读写分离的使用上面的区别: 在MySQL proxy 6.0版本 上面如果想要读写分离并且 读集群、写集群 机器比较多情况下,用mysql proxy 需要相当大的工作量,目前mysql proxy没有现成的 lua脚本。

首先说明一下amoeba 跟 MySQL proxy在读写分离的使用上面的区别:

 

在MySQL proxy 6.0版本 上面如果想要读写分离并且 读集群、写集群 机器比较多情况下,用mysql proxy 需要相当大的工作量,目前mysql proxy没有现成的 lua脚本。mysql proxy根本没有配置文件, lua脚本就是它的全部,当然lua是相当方便的。那么同样这种东西需要编写大量的脚本才能完成一 个复杂的配置。而Amoeba只需要进行相关的配置就可以满足需求。


假设有这样的使用场景,有三个数据库节点分别命名为Master、Slave1、Slave2如下:

 

Amoeba: Amoeba <192.168.14.129>

Master: Master <192.168.14.131> (可读写)

Slaves:Slave1 <192.168.14.132>、Slave2<192.168.14.133> (2个平等的数据库。只读/负载均衡)

 

在 主从数据库 的复制的部分, 任然需要使用数据库自己的复制机制。 Amoeba 不提供复制功能。

1. 起动数据库的主从复制功能。

 

a. 修改配置文件

 

master.cnf

server-id = 1 #主数据库标志  
  
# 增加 日志文件, 用于验证读写分离  
log = /home/mysql/mysql/log/mysql.log  

slave1.cnf

1 server-id = 2  
2   
3 # 增加 日志文件, 用于验证读写分离  
4 log = /home/mysql/mysql/log/mysql.log  

slave2.cnf

1 server-id = 3  
2   
3 # 增加 日志文件, 用于验证读写分离  
4 log = /home/mysql/mysql/log/mysql.log  

b. Master 中 创建两个 只读权限 的用户。 用户名均为:repl_user   密码均为:copy  分别开放给 slave1, slave2

1 mysql> grant replication slave on *.* to repl_user@192.168.14.132 identified by 'copy';  
2   
3 mysql> grant replication slave on *.* to repl_user@192.168.14.133 identified by 'copy';  

c. 查看 Master 信息

1 mysql> show master status;  
2 +------------------+----------+--------------+------------------+  
3 | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
4 +------------------+----------+--------------+------------------+  
5 | mysql-bin.000017 |     2009 |              |                  |  
6 +------------------+----------+--------------+------------------+  
7 1 row in set (0.00 sec)  

d. Slave1 ,Slave2 中 启动 Master - Slave 复制功能。分别执行以下命令:

 1 mysql> slave stop;  
 2 Query OK, 0 rows affected (0.02 sec)  
 3   
 4 mysql> change master to  
 5     -> master_host='192.168.14.131',  
 6     -> master_user='repl_user',  
 7     -> master_password='copy',  
 8     -> master_log_file='mysql-bin.000017',  
 9     -> master_log_pos=2009;  
10 Query OK, 0 rows affected (0.03 sec)  
11   
12 mysql> start slave;  
13 Query OK, 0 rows affected (0.00 sec)  

2. Amoeba 读写分离的配置

 

a. Master , Slave1 ,Slave2 中开放权限给 Amoeba 访问。在 Master , Slave1 , Slave2 中分别执行:

1 mysql> grant all on test.* to test_user@192.168.14.129 indentified by '1234'; 

Amoeba 访问三个数据库的账号密码相同。

b. 修改 Amoeba 的配置文件

dbServer.xml

xml version="1.0" encoding="gbk"?>  
  
DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd">  
<amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">  
  
          
  
       
    <dbServer name="abstractServer" abstractive="true">  
        <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">  
            <property name="manager">${defaultManager}property>  
            <property name="sendBufferSize">64property>  
            <property name="receiveBufferSize">128property>  
                  
              
            <property name="port">3306property>                                          <property name="schema">testproperty>                                          <property name="user">test_userproperty>                                          <property name="password">1234property>                        factoryConfig>            <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">              <property name="maxActive">500property>              <property name="maxIdle">500property>              <property name="minIdle">10property>              <property name="minEvictableIdleTimeMillis">600000property>              <property name="timeBetweenEvictionRunsMillis">600000property>              <property name="testOnBorrow">trueproperty>              <property name="testWhileIdle">trueproperty>          poolConfig>      dbServer>              <dbServer name="master"  parent="abstractServer">          <factoryConfig>                            <property name="ipAddress">192.168.14.131property>          factoryConfig>      dbServer>        <dbServer name="slave1"  parent="abstractServer">          <factoryConfig>                            <property name="ipAddress">192.168.14.132property>          factoryConfig>      dbServer>        <dbServer name="slave2"  parent="abstractServer">          <factoryConfig>                            <property name="ipAddress">192.168.14.133property>          factoryConfig>      dbServer>                    <dbServer name="slaves" virtual="true">          <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">                            <property name="loadbalance">1property>                                          <property name="poolNames">slave1,slave2property>          poolConfig>      dbServer>             amoeba:dbServers>  

amoeba.xml

  1 xml version="1.0" encoding="gbk"?>  
  2   
  3 DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">  
  4 <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">  
  5   
  6     <proxy>  
  7       
  8           
  9         <service name="Amoeba for Mysql" class="com.meidusa.amoeba.net.ServerableConnectionManager">  
 10               
 11             <property name="port">8066property>  
 12               
 13               
 14               
 17               
 18             <property name="manager">${clientConnectioneManager}property>  
 19               
 20             <property name="connectionFactory">  
 21                 <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">  
 22                     <property name="sendBufferSize">128property>  
 23                     <property name="receiveBufferSize">64property>    24                 bean>    25             property>    26                27             <property name="authenticator">    28                 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">    29                         30                     <property name="user">rootproperty>    31                        32                     <property name="password">rootproperty>    33                        34                     <property name="filter">    35                         <bean class="com.meidusa.amoeba.server.IPAccessController">    36                             <property name="ipFile">${amoeba.home}/conf/access_list.confproperty>    37                         bean>    38                     property>    39                 bean>    40             property>    41                42         service>    43            44             45         <service name="Amoeba Monitor Server" class="com.meidusa.amoeba.monitor.MonitorServer">    46                 47                 50                 51             <property name="ipAddress">127.0.0.1property>    52             <property name="daemon">trueproperty>    53             <property name="manager">${clientConnectioneManager}property>    54             <property name="connectionFactory">    55                 <bean class="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory">bean>    56             property>    57                58         service>    59            60         <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">    61                 62             <property name="readThreadPoolSize">20property>    63                64                 65             <property name="clientSideThreadPoolSize">30property>    66                67                 68             <property name="serverSideThreadPoolSize">30property>    69                70                 71             <property name="statementCacheSize">500property>    72                73                 74             <property name="queryTimeout">60property>    75         runtime>    76            77     proxy>    78        79         83     <connectionManagerList>    84         <connectionManager name="clientConnectioneManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">    85             <property name="subManagerClassName">com.meidusa.amoeba.net.ConnectionManagerproperty>    86                 90         connectionManager>    91         <connectionManager name="defaultManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">    92             <property name="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManagerproperty>    93                94                 98         connectionManager>    99     connectionManagerList>   100       101            102     <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">   103         <property name="configFile">${amoeba.home}/conf/dbServers.xmlproperty>   104     dbServerLoader>   105       106     <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">   107           108         <property name="ruleLoader">   109             <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">   110                 <property name="ruleFile">${amoeba.home}/conf/rule.xmlproperty>   111                 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xmlproperty>   112             bean>   113         property>   114         <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xmlproperty>   115           116         <property name="LRUMapSize">1500property>   117            118         <property name="defaultPool">masterproperty>   119           120            121         <property name="writePool">masterproperty>   122            123         <property name="readPool">slavesproperty>   124           125         <property name="needParse">trueproperty>   126     queryRouter>   127 amoeba:configuration>  

rule.xml

1 xml version="1.0" encoding="gbk"?>  
2 DOCTYPE amoeba:rule SYSTEM "rule.dtd">  
3   
4 <amoeba:rule xmlns:amoeba="http://amoeba.meidusa.com/">  
5     <tableRule name="message" schema="test" defaultPools="server1">  
6     tableRule>  
7 amoeba:rule> 

不需要 数据库分片时,不用配置。 但是不能没有 tableRule 元素, 否则报错。 随便写个空规则就行了。

3. 测试读写分离

a. 在 Master , Slave1 , Slave2  中分别查看 日志文件: mysql.log

tail -f ./log/mysql.log  

b. 启动 Amoeba, 使用 Mysql GUI Tools 连接 Amoeba



执行以上几个命令。 查看日志内容。

 

Master  mysql.log

[mysql@prx1 mysql]$ tail -f log/mysql.log  
                  370 Query     SET SESSION sql_mode=''  
                  370 Query     SET NAMES utf8  
                  370 Query     SHOW FULL TABLES  
                  370 Query     SHOW COLUMNS FROM `t_message`  
                  370 Query     SHOW COLUMNS FROM `t_user`  
                  370 Query     SHOW PROCEDURE STATUS  
                  370 Query     SHOW FUNCTION STATUS  
110813 15:21:11   370 Query     SHOW VARIABLES LIKE 'character_set_server'  
                  370 Query     SHOW FULL COLUMNS FROM `test`.`t_message`  
110813 15:21:12   370 Query     SHOW CREATE TABLE `test`.`t_message`  
110813 15:22:40   374 Connect   test_user@192.168.14.129 on test  
                  375 Connect   test_user@192.168.14.129 on test  
                  376 Connect   test_user@192.168.14.129 on test  
110813 15:23:40   370 Query     insert into t_message values(1, 'c1')  
110813 15:24:07   377 Connect   test_user@192.168.14.129 on test  
                  378 Connect   test_user@192.168.14.129 on test  
                  379 Connect   test_user@192.168.14.129 on test  
110813 15:24:15   370 Query     insert into t_user values(8, 'n8', 'p8')  
110813 15:24:24   370 Query     SHOW FULL COLUMNS FROM `test`.`t_user`  
                  370 Query     SHOW CREATE TABLE `test`.`t_user`  
110813 15:24:35   370 Query     SHOW FULL COLUMNS FROM `test`.`t_message`  
                  370 Query     SHOW CREATE TABLE `test`.`t_message`  

Slave1  mysql.log

[mysql@prx2 mysql]$ tail -f log/mysql.log  
                  317 Connect   test_user@192.168.14.129 on test  
                  318 Connect   test_user@192.168.14.129 on test  
110813 15:35:30   315 Query     SELECT @@sql_mode  
110813 15:35:32   315 Query     SELECT @@sql_mode  
110813 15:35:44   315 Query     SELECT @@SQL_MODE  
110813 15:35:46   315 Query     SELECT @@SQL_MODE  
110813 15:37:18   319 Connect   test_user@192.168.14.129 on test  
                  320 Connect   test_user@192.168.14.129 on test  
110813 15:37:19   321 Connect   test_user@192.168.14.129 on test  
110813 15:37:26   246 Quit  
110813 15:38:21   315 Query     SELECT @@SQL_MODE  
110813 15:38:22    42 Query     BEGIN  
                   42 Query     insert into t_message values(1, 'c1')  
                   42 Query     COMMIT /* implicit, from Xid_log_event */  
110813 15:38:50   322 Connect   test_user@192.168.14.129 on test  
                  323 Connect   test_user@192.168.14.129 on test  
                  324 Connect   test_user@192.168.14.129 on test  
110813 15:38:58    42 Query     BEGIN  
                   42 Query     insert into t_user values(8, 'n8', 'p8')  
                   42 Query     COMMIT /* implicit, from Xid_log_event */  
110813 15:39:08   315 Query     SELECT @@SQL_MODE  
110813 15:39:19   315 Query     SELECT @@SQL_MODE  
110813 15:44:08   325 Connect   test_user@192.168.14.129 on test  
                  326 Connect   test_user@192.168.14.129 on test  
                  327 Connect   test_user@192.168.14.129 on test  

Slave2  mysql.log

[mysql@prx3 mysql]$ tail -f log/mysql.log  
110813 15:35:08   305 Connect   test_user@192.168.14.129 on test  
                  306 Connect   test_user@192.168.14.129 on test  
                  307 Connect   test_user@192.168.14.129 on test  
110813 15:35:31   304 Query     SELECT @@sql_mode  
                  304 Query     SELECT @@sql_mode  
110813 15:35:44   304 Query     SELECT @@SQL_MODE  
110813 15:35:46   304 Query     SELECT * FROM t_message t  
110813 15:37:18   308 Connect   test_user@192.168.14.129 on test  
                  309 Connect   test_user@192.168.14.129 on test  
                  310 Connect   test_user@192.168.14.129 on test  
110813 15:38:21     8 Query     BEGIN  
                    8 Query     insert into t_message values(1, 'c1')  
                    8 Query     COMMIT /* implicit, from Xid_log_event */  
110813 15:38:50   311 Connect   test_user@192.168.14.129 on test  
                  312 Connect   test_user@192.168.14.129 on test  
                  313 Connect   test_user@192.168.14.129 on test  
110813 15:38:58   304 Query     SELECT @@SQL_MODE  
                    8 Query     BEGIN  
                    8 Query     insert into t_user values(8, 'n8', 'p8')  
                    8 Query     COMMIT /* implicit, from Xid_log_event */  
110813 15:39:08   304 Query     select * from t_user  
110813 15:39:19   304 Query     select * from t_message  
110813 15:44:08   314 Connect   test_user@192.168.14.129 on test  
                  315 Connect   test_user@192.168.14.129 on test  
                  316 Connect   test_user@192.168.14.129 on test  

从日志中可以看出。

在 Master  mysql.log 中,只执行了 insert into 命令。

在 Slave1 中,只是复制了 insert into 命令, 是主从复制的结果

在 Slave2 中, 复制了 insert into 命令,同时还执行了 select 命令。

 

说明,主从分离已经成功。

转自:http://www.iteye.com/topic/1113437

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8月前
|
存储 关系型数据库 MySQL
MySQL 读写分离原理
MySQL 读写分离原理
114 0
MySQL 读写分离原理
|
8月前
|
关系型数据库 MySQL Java
MySQL的主从复制 && SpringBoot整合Sharding-JDBC解决读写分离
MySQL的主从复制 && SpringBoot整合Sharding-JDBC解决读写分离
160 0
|
8月前
|
SQL 关系型数据库 MySQL
Mycat【Mycat部署安装(核心配置及目录结构、安装以及管理命令详解)Mycat高级特性(读写分离概述、搭建读写分离、MySQL双主双从原理)】(三)-全面详解(学习总结---从入门到深化)
Mycat【Mycat部署安装(核心配置及目录结构、安装以及管理命令详解)Mycat高级特性(读写分离概述、搭建读写分离、MySQL双主双从原理)】(三)-全面详解(学习总结---从入门到深化)
700 0
|
3月前
|
负载均衡 监控 关系型数据库
MySQL 官宣:支持读写分离了!!
【10月更文挑战第8天】MySQL的读写分离功能显著提升了数据库性能、可用性和可靠性。通过将读写操作分配至不同服务器,有效减轻单个服务器负载,提高响应速度与吞吐量,并增强系统稳定性。此外,它还支持便捷的扩展方式,可通过增加只读服务器提升读操作性能。实现读写分离的方法包括软件层面(如使用数据库中间件)和硬件层面(使用独立服务器)。使用时需注意数据一致性、负载均衡及监控管理等问题。
197 0
|
8月前
|
SQL 关系型数据库 MySQL
mysql 主从复制与读写分离
mysql 主从复制与读写分离
|
4月前
|
关系型数据库 MySQL Java
MySQL主从复制实现读写分离
MySQL主从复制(二进制日志)、 Sharding-JDBC实现读写分离
MySQL主从复制实现读写分离
|
5月前
|
SQL 关系型数据库 MySQL
(二十五)MySQL主从实践篇:超详细版读写分离、双主热备架构搭建教学
在上篇《主从原理篇》中,基本上把主从复制原理、主从架构模式、数据同步方式、复制技术优化.....等各类细枝末节讲清楚了,本章则准备真正对聊到的几种主从模式落地实践,但实践的内容通常比较枯燥乏味,因为就是调整各种配置、设置各种参数等步骤。
670 3
|
5月前
|
关系型数据库 MySQL PHP
开发者必看:MySQL主从复制与Laravel读写分离的完美搭配
开发者必看:MySQL主从复制与Laravel读写分离的完美搭配
97 2
|
5月前
|
SQL 关系型数据库 MySQL
mysql读写分离,主从同步
本文介绍了如何在Laravel项目中配置数据库读写分离,并实现MySQL主从同步。主要步骤包括:在`config/database.php`中设置读写分离配置;为主机授予从机访问权限;配置各MySQL服务器的`/etc/my.cnf`文件以确保唯一的`server-id`;以及通过SQL命令设置主从关系并启动从服务。文章还针对一些常见错误提供了排查方法。最后通过验证确认主从同步是否成功。[原文链接](https://juejin.cn/post/6901581801458958344)。版权所有者为作者佤邦帮主,转载请遵循相关规定。
|
5月前
|
cobar 关系型数据库 MySQL
使用MyCat实现MySQL主从读写分离(一)概述
【8月更文挑战第11天】MySQL读写分离通过主从复制分散负载,主库负责写操作,从库承担读查询,以复制技术确保数据一致性。此策略有效缓解锁竞争,提升查询效能并增强系统可用性。实现方式包括应用层处理,简便快捷但灵活性受限;或采用中间件如MyCAT、Vitess等,支持复杂场景但需专业团队维护。
153 0