水平拆分

  1. Mycat 分布式架构--水平拆分
    7.0 重要概念

1. 分片策略 :几乎融合经典业务中大部分的分片策略。Mycat已经开发了相应算法,非常方便调用。

范围分片 
取模 
枚举
日期
HASH
等。

2.分片键: 作为分片条件的列。

7.1 范围分片(range)
比如说t3表

(1)行数非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2)
(2)访问非常频繁,用户顺序访问较多

1. 修改schema.xml文件,定制分片策略

cp schema.xml schema.xml.1
vim schema.xml
添加:
<table name="t3" dataNode="sh1,sh2" rule="auto-sharding-long" />

2. 定义和使用分片策略

vim rule.xml

<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>

<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>

3. 定义范围

vim autopartition-long.txt
0-10=0
10-20=1

  1. 创建测试表:
    mysql -S /data/3307/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"
    mysql -S /data/3308/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

  2. 测试:
    重启mycat
    mycat restart
    mysql -uroot -p123456 -h 10.0.0.52 -P 8066 --default-auth=mysql_native_password
    insert into t3(id,name) values(1,'a');
    insert into t3(id,name) values(2,'b');
    insert into t3(id,name) values(3,'c');
    insert into t3(id,name) values(4,'d');
    insert into t3(id,name) values(11,'aa');
    insert into t3(id,name) values(12,'bb');
    insert into t3(id,name) values(13,'cc');
    insert into t3(id,name) values(14,'dd');

[root@db01 conf]# mysql -S /data/3308/mysql.sock -e "select * from taobao.t3"
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e "select * from taobao.t3"

7.2 取模分片

1%3 1
2%3 2
3%3 0
4%3 1
5%3 2
任何正整数数字和N(正整数)取模,得的值永远都是 0~N-1

id % 分片数量取模
N % 5 = 0-4 idx

取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点

1. 修改配置文件

vim schema.xml

<table name="t4" dataNode="sh1,sh2" rule="mod-long" />

2. 查看和定义分片使用

vim rule.xml
<property name="count">2</property>

3. 准备测试环境

创建测试表:
mysql -S /data/3307/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3308/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"

重启mycat
mycat restart

4. 测试:

[root@db01 ~]# mysql -uroot -p123456 -h 10.0.0.52 -P8066 --default-auth=mysql_native_password

use TESTDB
insert into t4(id,name) values(1,'a');
insert into t4(id,name) values(2,'b');
insert into t4(id,name) values(3,'c');
insert into t4(id,name) values(4,'d');
insert into t4(id,name) values(6,'x'),(8,'y'),(10,'z');

分别登录后端节点查询数据
mysql -S /data/3308/mysql.sock -e "select * from taobao.t4"
mysql -S /data/3307/mysql.sock -e "select * from taobao.t4"

7.3 枚举分片 (区域、zone)
t5 表
id name telnum
1 bj 1212
2 sh 22222
3 bj 3333
4 sh 44444
5 bj 5555

sharding-by-intfile

1. 设计分片策略

vim schema.xml
<table name="t5" dataNode="sh1,sh2" rule="sharding-by-intfile" />

2. 应用分片策略

vim rule.xml

    <tableRule name="sharding-by-intfile">
            <rule>
                    <columns>name</columns>
                    <algorithm>hash-int</algorithm>
            </rule>
    </tableRule>

<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
</function>

vim partition-hash-int.txt 配置:
bj=0
sh=1
DEFAULT_NODE=1

3. 准备测试环境

mysql -S /data/3307/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3308/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"

重启mycat
mycat restart

4. 插入测试数据:

mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password
use TESTDB
insert into t5(id,name) values(1,'bj');
insert into t5(id,name) values(2,'sh');
insert into t5(id,name) values(3,'bj');
insert into t5(id,name) values(4,'sh');
insert into t5(id,name) values(5,'tj');

mysql -S /data/3308/mysql.sock -e "select * from taobao.t5"
mysql -S /data/3307/mysql.sock -e "select * from taobao.t5"

7.4 Mycat全局表
a b c d .....
join

t

a
id name age

1 zs 18 sh1
id addr aid
1001 bj 1
1002 sh 2

2 ls 19 sh2
id addr aid
1001 bj 1
1002 sh 2

t
id addr aid
1001 bj 1
1002 sh 2

使用场景:
如果你的业务中有些数据类似于数据字典,比如配置文件的配置,
常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,
而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分,
要在所有的分片上保存一份数据即可,Mycat 在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join,
避免跨库Join,在进行数据插入操作时,mycat将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。

1. 设置全局表策略

vim schema.xml
<table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2" />

2. 后端数据准备

mysql -S /data/3307/mysql.sock -e "use taobao;create table t_area (id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3308/mysql.sock -e "use taobao;create table t_area (id int not null primary key auto_increment,name varchar(20) not null);"

重启mycat
mycat restart

3. 测试:

mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password

use TESTDB
insert into t_area(id,name) values(1,'a');
insert into t_area(id,name) values(2,'b');
insert into t_area(id,name) values(3,'c');
insert into t_area(id,name) values(4,'d');

mysql -S /data/3308/mysql.sock -e "select * from taobao.t_area"
mysql -S /data/3307/mysql.sock -e "select * from taobao.t_area"

7.5 E-R分片
a
join
b
on a.xx =b.yy

a
id name


1 a sh1
3 c


2 b sh2
4 d

b
id addr aid
1001 bj 1 sh1
1002 sh 2

1003 tj 3 sh2
1004 wh 4

为了防止跨分片join,可以使用E-R模式

<table name="a" dataNode="sh1,sh2" rule="mod-long">
<childTable name="b" joinKey="aid" parentKey="id" />
</table>

select * from a join b on a.id = b.aid

例子:

  1. 修改配置文件
    vim schema.xml
    <table name="a" dataNode="sh1,sh2" rule="mod-long_oldguo">
    <childTable name="b" joinKey="aid" parentKey="id" />
    </table>
  1. 修改rule.xml mod-log分片策略:
    vim rule.xml
    <tableRule name="mod-long_oldguo">
    <rule>
    <columns>id</columns>
    <algorithm>mod-long_oldguo</algorithm>
    </rule>
    </tableRule>

     <function name="mod-long_oldguo" class="io.mycat.route.function.PartitionByMod">
             <!-- how many data nodes -->
             <property name="count">2</property>
     </function>
    
  2. 创建测试表
    mysql -S /data/3307/mysql.sock -e "use taobao;create table a (id int not null primary key auto_increment,name varchar(20) not null);"
    mysql -S /data/3307/mysql.sock -e "use taobao;create table b (id int not null primary key auto_increment,addr varchar(20) not null ,aid int );"

mysql -S /data/3308/mysql.sock -e "use taobao;create table a (id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3308/mysql.sock -e "use taobao;create table b (id int not null primary key auto_increment,addr varchar(20) not null ,aid int );"

  1. 重启mycat 测试
    mycat restart
    mysql -uroot -p123456 -h10.0.0.52 -P8066 --default-auth=mysql_native_password
    use TESTDB
    insert into a(id,name) values(1,'a');
    insert into a(id,name) values(2,'b');
    insert into a(id,name) values(3,'c');
    insert into a(id,name) values(4,'d');
    insert into a(id,name) values(5,'e');

insert into b(id,addr,aid) values(1001,'bj',1);
insert into b(id,addr,aid) values(1002,'sj',3);
insert into b(id,addr,aid) values(1003,'sd',4);
insert into b(id,addr,aid) values(1004,'we',2);
insert into b(id,addr,aid) values(1005,'er',5);
========
后端数据节点数据分布:
mysql -S /data/3307/mysql.sock -e "select * from taobao.a"
mysql -S /data/3307/mysql.sock -e "select * from taobao.b"

mysql -S /data/3308/mysql.sock -e "select * from taobao.a"
mysql -S /data/3308/mysql.sock -e "select * from taobao.b"

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容