- Mycat 分布式架構(gòu)--水平拆分
7.0 重要概念
1. 分片策略 :幾乎融合經(jīng)典業(yè)務(wù)中大部分的分片策略昆雀。Mycat已經(jīng)開發(fā)了相應(yīng)算法瞄崇,非常方便調(diào)用辜御。
范圍分片
取模
枚舉
日期
HASH
等。
2.分片鍵: 作為分片條件的列珊皿。
7.1 范圍分片(range)
比如說t3表
(1)行數(shù)非常多萨咳,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
創(chuàng)建測試表:
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);"測試:
重啟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
任何正整數(shù)數(shù)字和N(正整數(shù))取模培他,得的值永遠都是 0~N-1
id % 分片數(shù)量取模
N % 5 = 0-4 idx
取余分片方式:分片鍵(一個列)與節(jié)點數(shù)量進行取余鹃两,得到余數(shù)遗座,將數(shù)據(jù)寫入對應(yīng)節(jié)點
1. 修改配置文件
vim schema.xml
<table name="t4" dataNode="sh1,sh2" rule="mod-long" />
2. 查看和定義分片使用
vim rule.xml
<property name="count">2</property>
3. 準(zhǔn)備測試環(huán)境
創(chuàng)建測試表:
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');
分別登錄后端節(jié)點查詢數(shù)據(jù)
mysql -S /data/3308/mysql.sock -e "select * from taobao.t4"
mysql -S /data/3307/mysql.sock -e "select * from taobao.t4"
7.3 枚舉分片 (區(qū)域、zone)
t5 表
id name telnum
1 bj 1212
2 sh 22222
3 bj 3333
4 sh 44444
5 bj 5555
sharding-by-intfile
1. 設(shè)計分片策略
vim schema.xml
<table name="t5" dataNode="sh1,sh2" rule="sharding-by-intfile" />
2. 應(yīng)用分片策略
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. 準(zhǔn)備測試環(huán)境
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. 插入測試數(shù)據(jù):
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
使用場景:
如果你的業(yè)務(wù)中有些數(shù)據(jù)類似于數(shù)據(jù)字典俊扳,比如配置文件的配置途蒋,
常用業(yè)務(wù)的配置或者數(shù)據(jù)量不大很少變動的表,這些表往往不是特別大馋记,
而且大部分的業(yè)務(wù)場景都會用到号坡,那么這種表適合于Mycat全局表,無須對數(shù)據(jù)進行切分抗果,
要在所有的分片上保存一份數(shù)據(jù)即可筋帖,Mycat 在Join操作中奸晴,業(yè)務(wù)表與全局表進行Join聚合會優(yōu)先選擇相同分片內(nèi)的全局表join冤馏,
避免跨庫Join,在進行數(shù)據(jù)插入操作時寄啼,mycat將把數(shù)據(jù)分發(fā)到全局表對應(yīng)的所有分片執(zhí)行逮光,在進行數(shù)據(jù)讀取時候?qū)S機獲取一個節(jié)點讀取數(shù)據(jù)。
1. 設(shè)置全局表策略
vim schema.xml
<table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2" />
2. 后端數(shù)據(jù)準(zhǔn)備
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
例子:
- 修改配置文件
vim schema.xml
<table name="a" dataNode="sh1,sh2" rule="mod-long_oldguo">
<childTable name="b" joinKey="aid" parentKey="id" />
</table>
-
修改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>
創(chuàng)建測試表
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 );"
- 重啟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);
========
后端數(shù)據(jù)節(jié)點數(shù)據(jù)分布:
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"