第107讲:Mycat实践指南:取模分片下的水平分表详解

文章目录

1.使用取模分片水平分表

平台库下有一张表的数据量非常多,目前已经达到了600w行数据,查询效率很低,数据量越大,索引的结构就越高,性能会有所下降。

基于这种情况,我们决定针对这张业务表进行水平分表,分表后,原表的数据量就会被分到多张表中,缓解单表的压力,将该表的数据拆分到多个数据库实例中存放。

本次我们通过取模分片的方式来对达标进行水平分表。

取模分片指的是根据特定的字段值与分片节点数量进行求模运算,也就是除法运算取余数,根据运算结果中的余数,决定数据写入到哪一个分片中。指定取模分片的字段一定要是数字类型的字段,否则是无法进行运算的。

取模分片例子:

根据id列进行取模分片,写入数据的id为15,分片节点数为2个,运算过程:15/2=7余1,余数为1,取模分片此时就会将这个数据写入到分片2中,因为在Mycat分片中,分片的ID都是从0开始的,余数的值就是要写入对应分片节点的ID号,余数为1就对应分片2这个节点。

2.水平分表取模分片案例

在db_1数据库下有一张table1表,其数据量已经达到500w行,查询效率较低,现需要对这张表进行水平分表,采用取模分片的方法对该表进行水平分表。

2.1.准备测试的表结构

配置水平分表前,需要将要分的表在所有的分片上创建出来。

分片节点数依旧是2个,还是之前垂直分库分表时使用的两套双主双从集群。

sh 复制代码
1.在两个分片上创建数据库
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11 -e "create database db_2;"
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11 -e "create database db_2;"

2.在两个分片上创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11 -e "use db_2; create table table2 (id int,name varchar(10));"
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11 -e "use db_2; create table table2 (id int,name varchar(10));"

2.2.配置Mycat实现范围分片的水平分表

2.2.1.配置Schema配置文件

我们针对table1这张表进行水平分表时,要为其同时指定上两个分片,然后再为其指定分片规则,同时指定两个分片后,Mycat根据分片规则路由到不同的分片上。

xml 复制代码
[root@mysql-1 ~]# vim /data/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/">
         <!--定义逻辑库 库名叫做db_shopping 该逻辑库关联dn1这个数据节点-->
        <schema name="db_2" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
            <!--定义逻辑表 将table2这张大表水平拆分到dn1、dn2这两个分片上 并且分片规则使用mod-long-->
        	<table name="table2" dataNode="dn1,dn2" rule="mod-long"/>

        </schema>  

        <!--定义数据节点 也就是分片 一个分片会关联一个数据主机组 然后对应真实的数据库名称-->
        <dataNode name="dn1" dataHost="mysqlcluster-1" database= "db_2" />          
        <dataNode name="dn2" dataHost="mysqlcluster-2" database= "db_2" />          

        <!--定义数据主机 在这个标签下定义具体的读写操作路由的数据库实例地址 schema、table划分如何指定的是该数据主机关联的数据节点 那么对应的库、表都会被存储在数据主机定义的数据库实例中-->
        <dataHost name="mysqlcluster-1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    
                <heartbeat>select user()</heartbeat>  
                <!--定义写操作路由的数据库实例-->
                <writeHost host="c1-1-master3306" url="192.168.20.11:3306" user="root" password="123456">
                        <!--定义读操作路由的数据库实例-->
                        <readHost host="c1-1-slave3308" url="192.168.20.11:3308" user="root" password="123456" />
                </writeHost> 
                <!--备用的主库 也是提供写操作的数据库,当主库c1-1-master3306故障后 备用库开始提供写操作-->
                <writeHost host="c1-2-master3306" url="192.168.20.12:3306" user="root" password="123456">
                        <!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
                        <readHost host="c1-2-slave3308" url="192.168.20.12:3308" user="root" password="123456" />
                </writeHost> 
        </dataHost>  

        <dataHost name="mysqlcluster-2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    
                <heartbeat>select user()</heartbeat>  
                <writeHost host="c2-1-master3307" url="192.168.20.11:3307" user="root" password="123456">
                        <readHost host="c2-1-slave3309" url="192.168.20.11:3309" user="root" password="123456" />
                </writeHost> 
                <!--备用主库db3 主库db1故障后 开始提供写操作-->
                <writeHost host="c2-2-master3307" url="192.168.20.12:3307" user="root" password="123456">
                        <!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
                        <readHost host="c2-2-slave3309" url="192.168.20.12:3309" user="root" password="123456" />
                </writeHost> 
        </dataHost>  

</mycat:schema>
2.2.2.配置Rule分片规则配置文件

在Rule分片规则配置文件中,我们要配置主要是根据表中的那个字段进行范围分片,如果做取模分片的字段也是id字段,就不需要调整这个配置文件,只需要调整取模分片中传入的参数。

注意:做取模分片的字段必须是数字类型的字段。

xml 复制代码
[root@mysql-1 ~]# vim /data/mycat/conf/rule.xml 
	<!--分片规则的名称-->>
    <tableRule name="mod-long">
        <rule>
            <!--基于表中那个字段进行分片-->
            <columns>id</columns>	
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>

    <!--特定类型所对应的函数名称-->>
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <!-- 分片节点数量 这个值就是取模的分母 id字段会除与这个值 得到的余数就是划分的节点ID -->
        <property name="count">2</property>
    </function>
2.2.3.配置Server配置文件
xml 复制代码
[root@mysql-1 ~]# vim /data/mycat/conf/server.xml
    <user name="root" defaultAccount="true">
        <!--登录用户的密码-->
        <property name="password">123456</property>
        <!--该用户登录后可以显示那些Schema-->
        <property name="schemas">db_2</property>
    </user>
2.2.4.重启Mycat
sh 复制代码
[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...

2.3.写入数据观察水平分表效果

1)插入ID为10和15的两条数据

sql 复制代码
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into table2 (id,name) values (10,'abc');
mysql> insert into table2 (id,name) values (15,'xbz');

ID10除与分片节点数2,余数为0,那么该条数据会分配至分片1的数据库实例中。

ID15除与分片节点数1,余数为1,那么该条数据会分配至分片2的数据库实例中。

3)在Mycat中通过查询table1表就能看到所有的数据

相关推荐
云和数据.ChenGuang42 分钟前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
woshilys1 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi1 小时前
SQL注入的那些面试题总结
数据库·sql
建投数据2 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi3 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀3 小时前
Redis梳理
数据库·redis·缓存
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天4 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺4 小时前
分布式系统架构:服务容错
数据库·架构
拭心5 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android