基于代理的数据库分库分表框架 Mycat实践

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

Profile

文章共 1796字,阅读大约需要 4分钟 !


概 述

在如今海量数据充斥的互联网环境下,分库分表的意义我想在此处就不用赘述了。而分库分表目前流行的方案最起码有两种:

  • 方案一:基于应用层的分片,即应用层代码直接完成分片逻辑
  • 方案二:基于代理层的分片,即在应用代码和底层数据库中间添加一层代理层,而分片的路由规则则由代理层来进行处理

而本文即将要实验的 MyCAT框架就属于第二种方案的代表作品。

注: 本文首发于 My Personal Blog:CodeSheep·程序羊,欢迎光临 小站


环境规划

在本文中,我拿出了三台 Linux主机投入试验,各节点的角色分配如下表所示:

节点 部署组件 角色
192.168.199.75 MySQL 、 MyCAT master
192.168.199.74 MySQL slave
192.168.199.76 MySQL standby master

如果说上面这张表不足以说明实验模型,那接下来再给一张图好了,如下所示:

实验模型

我想这样看来的话,各个节点布了哪些组件,节点间的角色关系应该一目了然了吧

实验环境规划好了以后,接下来进行具体的部署与实验过程,首先当然是 MyCAT代理的部署


MyCAT 部署

关于该部分,网上教程实在太多了,但最好还是参考官方文档来吧,下面也简述一下部署过程

  • 下载 MyCAT并解压安装

这里安装的是 MyCAT 1.5

wget https://raw.githubusercontent.com/MyCATApache/Mycat-download/master/1.5-RELEASE/Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz
tar -zxvf Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz
mv mycat /usr/local/
  • 启动 MyCAT
./mycat start

MyCAT 启动日志

  • MyCAT连接测试
mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB

MyCAT 连接成功


MyCAT 配置

官网上对于这一部分的描述是非常详细的,MyCAT 配置主要涉及三个 XML配置文件:

  • server.xml:MyCAT框架的系统参数/用户参数配置文件
  • schema.xml: MyCAT框架的逻辑库表与分片的配置文件
  • rule.xml :MyCAT框架的逻辑库表分片规则的配置文件

用如下图形可以形象地表示出这三个 XML配置文件的配置内容和相互关系:

三个与 MyCAT相关的 xml配置

下面来进入具体的实验环节 ,这也是围绕 MyCAT提供的几大主要功能展开的,主要涉及三个方面

  • 分库分表
  • 读写分离
  • 主备切换

实验之前,我们先给出公共的 server.xml文件的配置,这部分后续实验过程中并不修改,其也就是定义了系统参数和用户参数:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
    <system>
    <property name="defaultSqlParser">druidparser</property>
      <!--  <property /> 这块诸多的property配置在此就不配置了,参照官网按需配置 -->
    </system>
    <user name="test">
        <property name="password">test</property>
        <property name="schemas">TESTDB</property>
    </user>

    <user name="user">
        <property name="password">user</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">true</property>
    </user>

</mycat:server>

分库分表实验

预期实验效果:通过 MyCAT代理往一张逻辑表中插入的多条数据,在后端自动地分配在不同的物理数据库表上

我们按照本文 第二节【环境规划】中给出的实验模型图来给出如下的 MyCAT逻辑库配置文件 `
schema.xml 和 分库分表规则配置文件 rule.xml`

  • 准备配置文件

schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >

    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
        <table name="travelrecord" dataNode="dn1,dn2" rule="sharding-by-month" />
    </schema>
    
    <dataNode name="dn1" dataHost="testhost" database="db1" />
    <dataNode name="dn2" dataHost="testhost" database="db2" />
    
    <dataHost name="testhost" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native" switchType="-1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="hostM1" url="localhost:3306" user="root" password="xxxxxx">
                <readHost host="hostS1" url="192.168.199.74:3306" user="root" password="xxxxxx" />
        </writeHost>
        <writeHost host="hostM2" url="192.168.199.76:3306" user="root" password="xxxxxx">
        </writeHost>
    </dataHost>

</mycat:schema>

其中定义了实验用到的 hostM1、hostS1 和 hostM2

rule.xml

    <tableRule name="sharding-by-month">
        <rule>
            <columns>create_date</columns>
            <algorithm>partbymonth</algorithm>
        </rule>
    </tableRule>

    <function name="partbymonth"
        class="org.opencloudb.route.function.PartitionByMonth">
        <property name="dateFormat">yyyy-MM-dd</property>
        <property name="sBeginDate">2018-11-01</property>
    </function>

这里配置了 sharding-by-month的分库分表规则,即按照表中的 create_date字段进行分割,从 2018-11-01日期开始,月份不同的数据落到不同的物理数据库表中

  • 在三个物理节点数据库上分别创建两个库 db1和 db2
create database db1;
create database db2;
  • 连接 MyCAT
mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB
  • 通过 MyCAT来创建数据库 travelrecord
create table travelrecord (id bigint not null primary key,city varchar(100),create_date DATE);
  • 通过 MyCAT来往travelrecord表中插入两条数据
insert into travelrecord(id,city,create_date)  values(1,'NanJing','2018-11-3');
insert into travelrecord(id,city,create_date)  values(2,'BeiJing','2018-12-3');

通过 MyCAT往逻辑库中插入数据

由于插入的这两条记录的 create_date分别是 2018-11-32018-12-3,而我们配的分库分表的规则即是根据 2018-11-01这个日期为起始来进行递增的,按照前面我们配的分片规则,理论上这两条记录按照 create_date日期字段的不同,应该分别插入到 hostM1的 db1和 db2两个不同的数据库中。

  • 验证一下数据分片的效果

数据分片的效果

由于 hostM1hostS1组成了 主-从库 关系,因此刚插入的两条数据也应该相应自动同步到 hostS1db1db2两个数据库中,不妨也来验证一下:

主从数据库同步也是OK的


读写分离实验

预期实验效果:开启了 MyCAT的读写分离机制后,读写数据操作各行其道,互不干扰

此节实验用到的配置文件 schema.xmlrule.xml基本和上面的【分库分表】实验没什么不同,只是我们需要关注一下 schema.xml配置文件中 <dataHost />标签里的 balance字段,它是与读写分离息息相关的配置:

因此我们就需要弄清楚 标签中 balance参数的含义:

  • balance="0":不开启读写分离机制,即读请求仅分发到 writeHost上
  • balance="1":读请求随机分发到当前 writeHost对应的 readHost和 standby writeHost上
  • balance="2":读请求随机分发到当前 dataHost内所有的 writeHost / readHost上
  • balance="3":读请求随机分发到当前 writeHost对应的 readHost上

我们验证一下 balance="1"的情况,即开启读写分离机制,且读请求随机分发到当前 writeHost对应的 readHost和 standby writeHost上,而对于本文来讲,也即:hostS1 和 hostM2 上

我们来做两次数据表的 SELECT读操作:

mysql> select * from travelrecord limit 6;
+----+----------+-------------+
| id | city     | create_date |
+----+----------+-------------+
|  3 | TianJing | 2018-11-04  |
|  5 | ShenYang | 2018-11-05  |
|  4 | Wuhan    | 2018-12-04  |
|  6 | Harbin   | 2018-12-05  |
+----+----------+-------------+
4 rows in set (0.08 sec)

mysql> select * from travelrecord limit 6;
+----+---------+-------------+
| id | city    | create_date |
+----+---------+-------------+
|  2 | BeiJing | 2018-12-03  |
|  8 | WuXi    | 2018-12-06  |
|  1 | NanJing | 2018-11-03  |
|  7 | SuZhou  | 2018-11-06  |
+----+---------+-------------+
4 rows in set (0.01 sec)

然后我们取出 mycat.log日志查看一下具体详情,我们发现第一次 select读操作分发到了 hostM2上:

第一次 select读操作分发到了 hostM2上

而第二次 select读操作分发到了 hostS1上:

第二次 select读操作分发到了 hostS1上


主备切换实验

预期实验效果:开启 MyCAT的主备机制后,当主库宕机时,自动切换到备用机进行操作

关于主备切换,则需要弄清楚 <dataHost /> 标签中 switchType参数的含义:

  • switchType="-1":不自动切换主备数据库
  • switchType="1":自动切换主备数据库
  • switchType="2":基于MySQL主从复制的状态来决定是否切换,需修改heartbeat语句:show slave status
  • switchType="3":基于Galera(集群多节点复制)的切换机制,需修改heartbeat语句:show status like 'wsrep%'

此处验证一下 Mycat的主备自动切换效果。为此首先我们将 switchType="-1" 设置为 switchType="1",并重启 MyCat服务:

<dataHost name="testhost" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

在本实验环境中,在 hostM1hostM2均正常时,默认写数据时是写到 hostM1

  • 接下来手动停止 hostM1 上的 MySQL数据库来模拟 hostM1 宕机:
systemctl stop mysqld.service

接下来再通过 MyCat插入如下两条数据:

insert into travelrecord(id,city,create_date)  values(3,'TianJing','2018-11-4');
insert into travelrecord(id,city,create_date)  values(4,'Wuhan','2018-12-4');

效果如下:

hostM1宕机后,备用hostM2升级为主写节点

  • 此时,我们恢复 hostM1,但接下来的数据写入依然进入 hostM2
insert into travelrecord(id,city,create_date)  values(5,'ShenYang','2018-11-5');
insert into travelrecord(id,city,create_date)  values(6,'Harbin','2018-12-5');

虽然hostM1恢复,但依然不是主写节点

  • 接下来手动让 hostM2宕机,看 hostM1 是否能升级为主写节点

再插入两条数据:

insert into travelrecord(id,city,create_date)  values(7,'SuZhou','2018-11-6');
insert into travelrecord(id,city,create_date)  values(8,'WuXi','2018-12-6');

hostM2宕机后,hostM1再次升级为主写节点

很明显,答案是肯定的


后 记

由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
搜索推荐 前端开发 算法
基于用户画像及协同过滤算法的音乐推荐系统,采用Django框架、bootstrap前端,MySQL数据库
本文介绍了一个基于用户画像和协同过滤算法的音乐推荐系统,使用Django框架、Bootstrap前端和MySQL数据库构建,旨在为用户提供个性化的音乐推荐服务,提高推荐准确性和用户满意度。
基于用户画像及协同过滤算法的音乐推荐系统,采用Django框架、bootstrap前端,MySQL数据库
|
15天前
|
存储 缓存 运维
优化数据库查询性能的关键技巧与实践
在当今软件开发中,高效的数据库查询是保证系统性能的重要因素之一。本文将探讨如何通过优化查询语句、索引设计以及服务器配置等多方面手段,提升数据库查询效率,从而实现更快速和可靠的数据检索和处理。
|
16天前
|
存储 负载均衡 中间件
构建可扩展的分布式数据库:技术策略与实践
【8月更文挑战第3天】构建可扩展的分布式数据库是一个复杂而具有挑战性的任务。通过采用数据分片、复制与一致性模型、分布式事务管理和负载均衡与自动扩展等关键技术策略,并合理设计节点、架构模式和网络拓扑等关键组件,可以构建出高可用性、高性能和可扩展的分布式数据库系统。然而,在实际应用中还需要注意解决数据一致性、故障恢复与容错性以及分布式事务的复杂性等挑战。随着技术的不断发展和创新,相信分布式数据库系统将在未来发挥更加重要的作用。
|
19天前
|
开发框架 缓存 NoSQL
基于SqlSugar的数据库访问处理的封装,在.net6框架的Web API上开发应用
基于SqlSugar的数据库访问处理的封装,在.net6框架的Web API上开发应用
|
19天前
|
开发框架 Oracle 关系型数据库
ABP框架使用Oracle数据库,并实现从SQLServer中进行数据迁移的处理
ABP框架使用Oracle数据库,并实现从SQLServer中进行数据迁移的处理
|
20天前
|
存储 关系型数据库 MySQL
深度评测:PolarDB-X 开源分布式数据库的优势与实践
本文对阿里云开源分布式数据库 PolarDB-X 进行了详细评测。PolarDB-X 以其高性能、强可用性和出色的扩展能力在云原生数据库市场中脱颖而出。文章首先介绍了 PolarDB-X 的核心产品优势,包括金融级高可靠性、海量数据处理能力和高效的混合负载处理能力。随后,分析了其分布式架构设计,包括计算节点、存储节点、元数据服务和日志节点的功能分工。评测还涵盖了在 Windows 平台通过 WSL 环境部署 PolarDB-X 的过程,强调了环境准备和工具安装的关键步骤。使用体验方面,PolarDB-X 在处理分布式事务和实时分析时表现稳定,但在网络问题和性能瓶颈上仍需优化。最后,提出了改进建
6585 2
|
22天前
|
SQL 存储 安全
SQL数据库:核心原理、应用实践与未来展望
在电子商务领域,SQL数据库用于存储商品信息、用户信息、订单信息等。通过SQL数据库,电商平台可以实现商品的快速检索、用户行为的跟踪分析、订单状态的实时更新等功能,提升用户体验和运营效率。
|
24天前
|
关系型数据库 分布式数据库 数据库
PolarDB产品使用问题之是否支持分库分表创建数据库
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
27天前
|
缓存 监控 NoSQL
深入解析数据库性能优化:策略与实践
【7月更文挑战第23天】数据库性能优化是一个复杂而持续的过程,涉及硬件、软件、架构、管理等多个方面。通过本文的介绍,希望能够为读者提供一个全面的性能优化框架,帮助大家在实际工作中更有效地提升数据库性能。记住,优化不是一蹴而就的,需要持续的观察、分析和调整。
|
4天前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
15 0