首页 > 其他分享 >深入理解MyCAT分库分表机制:架构师的秘密武器

深入理解MyCAT分库分表机制:架构师的秘密武器

时间:2024-08-01 23:24:28浏览次数:21  
标签:分库 数据库 db MyCAT 分表 架构师 orders

在这里插入图片描述

一、MyCAT分库和分表的概念

1. 分库(Database Sharding)

分库是将一个大数据库拆分成多个小数据库,以减小单个数据库的压力并提高系统的扩展性。每个子数据库可以分布在不同的服务器上,从而分散负载并提高性能。

示例:

假设我们有一个用户信息数据库users_db,其中包含了大量的用户数据。分库的思想是将这个数据库拆分为多个子库,例如users_db_1users_db_2等。每个子库存储特定用户的信息(如按用户ID或地区划分)。

2. 分表(Table Sharding)

分表是将一个大表拆分成多个小表,以提高查询性能和写入性能。分表可以在同一个数据库实例中实现,也可以在多个数据库实例中实现。

示例:

假设我们有一个订单表orders,包含了所有订单信息。通过分表,我们可以将这张大表拆分成多个小表,如orders_2024orders_2023等,每个小表分别存储不同年份的订单数据。

二、MyCAT中的分库、分表配置

MyCAT通过配置文件schema.xml来定义数据库分库和分表的规则。以下是详细的配置步骤及实例。

1. 配置分库

分库在MyCAT中主要通过定义dataNodedataHost来实现。

示例:

假设我们有一个user表,计划根据用户ID将其分库到两个数据库实例中:user_db_1user_db_2

schema.xml 配置示例

<schema name="mycatDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1,dn2">
    <!-- 定义user表的分片规则 -->
    <table name="user" primaryKey="id" dataNode="dn1,dn2" rule="userShard" />
</schema>

<dataNode name="dn1" dataHost="localhost1" database="user_db_1" />
<dataNode name="dn2" dataHost="localhost2" database="user_db_2" />

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostM1" url="192.168.1.100:3306" user="root" password="password" />
</dataHost>

<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostM2" url="192.168.1.101:3306" user="root" password="password" />
</dataHost>

在上述配置中:

  • dataNode:定义了两个数据节点dn1dn2,分别指向不同的数据库实例user_db_1user_db_2
  • dataHost:定义了不同的数据主机localhost1localhost2,它们对应不同的数据库服务器。

2. 配置分表

分表在MyCAT中通过定义table元素中的分片规则(rule)来实现。

示例:

假设我们有一个订单表orders,根据订单ID进行分表,将其分为两个子表:orders_0orders_1

schema.xml 配置示例

<schema name="mycatDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1,dn2">
    <!-- 定义orders表的分片规则 -->
    <table name="orders" primaryKey="order_id" dataNode="dn1,dn2" rule="orderShard" />
</schema>

<dataNode name="dn1" dataHost="localhost1" database="orders_db" />
<dataNode name="dn2" dataHost="localhost1" database="orders_db" />

<function name="orderShard" class="io.mycat.route.function.PartitionByMod">
    <!-- 分片数量 -->
    <property name="count">2</property>
</function>

在上述配置中:

  • table元素中的rule定义了orderShard,这是一种分片函数,用于根据订单ID对表进行分片。
  • PartitionByMod函数表示按取模分片,将数据分为两片。

3. 自定义分片规则

除了默认的分片规则,MyCAT允许用户自定义分片规则以满足具体业务需求。

示例:

假设我们要根据用户注册时间对用户表进行分片。

schema.xml 自定义规则示例

<schema name="mycatDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1,dn2,dn3">
    <!-- 自定义分片规则 -->
    <table name="user" primaryKey="id" dataNode="dn1,dn2,dn3" rule="timeShard" />
</schema>

<dataNode name="dn1" dataHost="localhost1" database="user_db_1" />
<dataNode name="dn2" dataHost="localhost1" database="user_db_2" />
<dataNode name="dn3" dataHost="localhost1" database="user_db_3" />

<function name="timeShard" class="io.mycat.route.function.PartitionByDate">
    <!-- 按注册时间进行分片 -->
    <property name="dateColumn">register_time</property>
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="partitionCount">3</property>
</function>

在这个例子中:

  • timeShard是一个自定义的分片函数,用于根据用户注册时间将用户数据分为三片。
  • PartitionByDate函数通过日期进行分片,可以灵活地将数据分布到不同的节点上。

三、完整实例

示例1:基于用户ID的分库分表

假设我们有一个用户表users和订单表orders,分别需要进行分库和分表。

环境准备

  1. 数据库服务器

    • MySQL服务器1:192.168.1.100,数据库名:users_db_1orders_db
    • MySQL服务器2:192.168.1.101,数据库名:users_db_2
  2. 用户表

    CREATE TABLE users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(255),
        email VARCHAR(255),
        register_time DATETIME
    );
    
  3. 订单表

    CREATE TABLE orders (
        order_id INT AUTO_INCREMENT PRIMARY KEY,
        user_id INT,
        product_id INT,
        quantity INT,
        order_time DATETIME
    );
    

schema.xml 配置

<schema name="mycatDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="user_dn1,user_dn2,order_dn1,order_dn2">
    <!-- 定义users表的分库规则 -->
    <table name="users" primaryKey="id" dataNode="user_dn1,user_dn2" rule="userShard" />

    <!-- 定义orders表的分表规则 -->
    <table name="orders" primaryKey="order_id" dataNode="order_dn1,order_dn2" rule="orderShard" />
</schema>

<dataNode name="user_dn1" dataHost="userHost1" database="users_db_1" />
<dataNode name="user_dn2" dataHost="userHost2" database="users_db_2" />

<dataNode name="order_dn1" dataHost="orderHost1" database="orders_db" />
<dataNode name="order_dn2" dataHost="orderHost1" database="orders_db" />

<dataHost name="userHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostM1" url="192.168.1.100:3306" user="root" password="password" />
</dataHost>

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

>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostM2" url="192.168.1.101:3306" user="root" password="password" />
</dataHost>

<dataHost name="orderHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostO1" url="192.168.1.100:3306" user="root" password="password" />
</dataHost>

<function name="userShard" class="io.mycat.route.function.PartitionByMod">
    <!-- 用户表按ID取模分库 -->
    <property name="count">2</property>
</function>

<function name="orderShard" class="io.mycat.route.function.PartitionByMod">
    <!-- 订单表按订单ID取模分表 -->
    <property name="count">2</property>
</function>

启动MyCAT并验证

  1. 启动MyCAT

    ./bin/mycat start
    
  2. 连接MyCAT并验证

    mysql -h 127.0.0.1 -P 8066 -u root -p
    

    执行以下SQL语句进行验证:

    -- 插入数据
    INSERT INTO users (name, email, register_time) VALUES ('Alice', '[email protected]', NOW());
    INSERT INTO orders (user_id, product_id, quantity, order_time) VALUES (1, 101, 2, NOW());
    
    -- 查询数据
    SELECT * FROM users;
    SELECT * FROM orders;
    

    如果能够成功插入和查询数据,则说明分库分表配置成功。

示例2:基于城市的分库和基于月份的分表

假设我们有一个城市数据表cities和月度销售表sales

环境准备

  1. 数据库服务器

    • MySQL服务器1:192.168.1.200,数据库名:cities_dbsales_db
    • MySQL服务器2:192.168.1.201,数据库名:sales_db
  2. 城市表

    CREATE TABLE cities (
        city_id INT AUTO_INCREMENT PRIMARY KEY,
        city_name VARCHAR(255),
        population INT
    );
    
  3. 销售表

    CREATE TABLE sales (
        sale_id INT AUTO_INCREMENT PRIMARY KEY,
        city_id INT,
        amount DECIMAL(10, 2),
        sale_date DATE
    );
    
schema.xml 配置
<schema name="mycatDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="city_dn1,sales_dn1,sales_dn2">
    <!-- 定义cities表的分库规则 -->
    <table name="cities" primaryKey="city_id" dataNode="city_dn1" rule="cityShard" />

    <!-- 定义sales表的分表规则 -->
    <table name="sales" primaryKey="sale_id" dataNode="sales_dn1,sales_dn2" rule="monthShard" />
</schema>

<dataNode name="city_dn1" dataHost="cityHost1" database="cities_db" />

<dataNode name="sales_dn1" dataHost="salesHost1" database="sales_db" />
<dataNode name="sales_dn2" dataHost="salesHost2" database="sales_db" />

<dataHost name="cityHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostC1" url="192.168.1.200:3306" user="root" password="password" />
</dataHost>

<dataHost name="salesHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostS1" url="192.168.1.200:3306" user="root" password="password" />
</dataHost>

<dataHost name="salesHost2" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>show status like 'threads_connected'</heartbeat>
    <writeHost host="hostS2" url="192.168.1.201:3306" user="root" password="password" />
</dataHost>

<function name="cityShard" class="io.mycat.route.function.PartitionByMod">
    <!-- 城市表按城市ID取模分库 -->
    <property name="count">1</property>
</function>

<function name="monthShard" class="io.mycat.route.function.PartitionByMonth">
    <!-- 销售表按月份分表 -->
    <property name="dateColumn">sale_date</property>
    <property name="dateFormat">yyyy-MM</property>
    <property name="partitionCount">2</property>
</function>

启动MyCAT并验证

  1. 启动MyCAT

    ./bin/mycat start
    
  2. 连接MyCAT并验证

    mysql -h 127.0.0.1 -P 8066 -u root -p
    

    执行以下SQL语句进行验证:

    -- 插入城市数据
    INSERT INTO cities (city_name, population) VALUES ('New York', 8419600);
    INSERT INTO cities (city_name, population) VALUES ('Los Angeles', 3980400);
    
    -- 插入销售数据
    INSERT INTO sales (city_id, amount, sale_date) VALUES (1, 1000.00, '2024-07-01');
    INSERT INTO sales (city_id, amount, sale_date) VALUES (2, 1500.00, '2024-08-01');
    
    -- 查询数据
    SELECT * FROM cities;
    SELECT * FROM sales;
    

    如果能够成功插入和查询数据,则说明分库分表配置成功。

非常感谢您读到这里!如果您觉得这篇文章对您有帮助,可以关注一下博主。关注后,您将第一时间获得最新的AI、云计算、运维(Linux、数据库,容器等)技术,以及更多实用的技能干货。

全网第一个AI+PPT提效小册希望能对大家有帮助订阅之后有专属学习交流群
以及AI考试资料分享

标签:分库,数据库,db,MyCAT,分表,架构师,orders
From: https://blog.csdn.net/zgt_certificate/article/details/140859594

相关文章

  • MyCAT数据库中间件:让你的数据库无缝扩展!
    什么是MyCATMyCAT是一个开源的数据库中间件系统,设计用于支持分布式数据库环境。它被广泛用于大数据和高并发的场景中,作为传统关系数据库(如MySQL)的扩展,以提高性能和扩展能力。MyCAT提供了数据库分片、读写分离、负载均衡、以及跨库的事务支持等功能。MyCAT的详细解释及其......
  • 架构师手写代码:分享数据库原子性与一致性实现方案(不再背概念)
    数据库事务的原子性和一致性是数据库管理系统(DBMS)中确保数据完整性和可靠性的两个关键属性。下面是这两个属性的基本概念和实现逻辑:肖哥弹架构跟大家“弹弹”数据库设计技巧,需要代码关注欢迎点赞,点赞,点赞。关注公号Solomon肖哥弹架构获取更多精彩内容历史热点文章......
  • 面试官:聊聊你对分库分表的理解?
    在MySQL集群架构中有两种主流的集群实现,一种是读写分离,而另外一种则是数据分片。所谓的数据分片其实就是今天要聊的分库分表技术。分库分表技术不但是日常工作中用于解决数据库中的数据量会急剧增长,解决单库单表性能瓶颈的一种方案,更是面试中的高频知识点。在阿里巴巴的《Java......
  • [Mysql]分库分表
    分库分表读写分离主要应对的是数据库读并发,没有解决数据库存储问题。试想一下:如果MySQL一张表的数据量过大怎么办?换言之,我们该如何解决MySQL的存储压力呢?答案之一就是分库分表。什么是分库?分库就是将数据库中的数据分散到不同的数据库上,可以垂直分库,也可以水平分库。......
  • 架构师的新武器:Codigger之软件项目体检Software Project HealthCheck
    在软件架构这一充满挑战与创新的领域中,架构师宛如精心雕琢宏伟建筑的艺术大师,他们的每一个决策都决定着软件系统的稳固性、可扩展性和性能表现。而Codigger软件项目体检,无疑是架构师手中一件崭新且威力强大的神兵利器,为打造卓越的软件架构提供了有力支撑。项目体检在架构合理性......
  • 【SQL】常用的分库策略有哪些
    分库是数据库设计中的一种常见策略,用于解决大规模数据处理和高并发访问的问题。通过将数据分布到多个数据库实例上,可以提高系统的可扩展性、性能和可用性。常用的分库策略主要包括垂直分库、水平分库和混合分库。以下是这些策略的详细介绍:1.垂直分库(VerticalSharding)垂......
  • 【SQL】分库分表带来的问题以及解决方案
    分库分表是解决大规模数据和高并发访问的有效方法,但它也会带来一些问题和挑战。以下是分库分表可能带来的主要问题:1.跨分片查询复杂性在分库分表的架构中,数据分布在多个数据库实例或表中,这导致跨分片的查询变得复杂。问题:需要跨多个数据库实例或表进行数据聚合。查询性......
  • 【架构师专栏】togaf9.2基础题库
    1、根据T0GAF架构,下列哪一项是被普遍接受的一个整个企业架构的子集划分?A.应用,业务,数据,技术B.能力,组件,战略C.下文,定义,治理,改造D.义,实现,过渡,愿景正确答案:A2、关于TOGAF9文档结构的叙述中,哪一个是正确的?A.第一部分介绍了企业架构的T0GAF方法B.第二部分介......
  • 基于mycat实现数据库的读写分离
    一、mycat分布式存储服务部署1.安装java运行环境(db01)[root@db01~]#yuminstall-yjava2.下载、解压mycat包#上传解压mycat程序包[root@db01~]#tarxfMycat-server-1.6.7.4-release-20200105164103-linux_.tar.gz -C/usr/local/[root@db01~]#ll/usr/local/......
  • 深度解析:分库分表策略在数据库性能优化中的核心作用
        目录分库分表的核心原理分库(Sharding)分表(Partitioning)综合运用与挑战在探讨分库分表的深度理解之前,先回顾一下为什么数据库系统会面临性能瓶颈。随着互联网业务的飞速发展,数据量呈指数级增长,同时高并发的访问需求对数据库的读写性能提出了更高要求。传统的......