> 技术文档 > MyCAT的五台主从配置与哈希分片

MyCAT的五台主从配置与哈希分片


MyCAT的两主两从配置⭐⭐⭐(五台)

一、分库分表的环境准备

我们可以按第6章的方式,搭建MySQL两组主从复制模型。

1.1 准备四个数据库和一个MyCAT

名称

ip

port

dw0

192.168.221.20

3306

dr0

192.168.221.30

3306

dw1

192.168.221.31

3306

dr1

192.168.221.32

3306

mycat

192.168.221.40

8066

1.2 配置MyCAT数据源

通过上面的配置,我们准备了两组主从,分别为:

1)主服务器dw0从服务器dr0

2)主服务器dw1从服务器dr1

接下来,我们要在MyCAT里面配置这四个数据源。

# 添加dw0数据源
/*+ mycat:createDataSource
{ \"name\":\"dw0\",
  \"password\":\"root123\",

\"url\":\"jdbc:mysql://192.168.221.20:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8\",
  \"user\":\"root\",}
*/;
# 添加dr0数据源
/*+ mycat:createDataSource
{ \"name\":\"dr0\",
  \"password\":\"root123\",

\"url\":\"jdbc:mysql://192.168.221.30:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8\",
  \"user\":\"root\",}
*/;
# 添加dw1数据源
/*+ mycat:createDataSource
{ \"name\":\"dw1\",
  \"password\":\"root123\",

\"url\":\"jdbc:mysql://192.168.221.31:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8\",
  \"user\":\"root\",}
*/;
# 添加dr1数据源
/*+ mycat:createDataSource
{ \"name\":\"dr1\",
  \"password\":\"root123\",

\"url\":\"jdbc:mysql://192.168.221.32:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8\",
  \"user\":\"root\",}
*/;
# 查看数据源
/*+ mycat:showDataSources{} */\\G;

会出现五个row

或者我们在MyCAT服务器里面看到如下数据源的配置文件。

1.3 配置MyCAT集群配置

注意:自动分片默认要求集群名字以c为前缀,数字为后缀:

1)c0就是分片表第一个节点;

2)c1就是第二个节点。

一般情况下我们使用默认的就可以了。

/*! mycat:createCluster{ \"name\":\"c0\", \"masters\":[  \"dw0\" ], \"replicas\":[  \"dr0\" ]} */;
/*! mycat:createCluster{ \"name\":\"c1\", \"masters\":[  \"dw1\" ], \"replicas\":[  \"dr1\" ]} */;
# 查看集群
/*+ mycat:showClusters{} */\\G;

会出现三个row

或者查看MyCAT配置文件里面内容如下:

或者是下面这样的:

{
    \"clusterType\": \"MASTER_SLAVE\",
    \"heartbeat\": {
        \"heartbeatTimeout\": 1000,
        \"maxRetryCount\": 3,
        \"minSwitchTimeInterval\": 300,
        \"showLog\": false,
        \"slaveThreshold\": 0.0
    },
    \"masters\": [
        \"dw0\"
    ],
    \"maxCon\": 2000,
    \"name\": \"c0\",
    \"readBalanceType\": \"BALANCE_ALL\",
    \"replicas\": [
        \"dr0\"
    ],
    \"switchType\": \"SWITCH\"
}

二、全局表(广播表)配置

全局表:所有分片库中都有全量数据的表。分库分表的环境准备好之后,接下来我们在MyCAT里面执行相关的命令,就可以帮我们创建全局表。

2.1 创建数据库

create database db1 default character set utf8mb4 collate utf8mb4_general_ci;

2.2 创建表

use db1;
create table `sys_dict` ( `id` bigint not null auto_increment,
                        `dict_type` int ,
                        `dict_name` varchar(100) default null,
                        `dict_value` int , primary key (`id`)
                        ) engine=innodb  default charset=utf8mb4 broadcast;
# 上面的SQL中有一个BROADCAST 这个就是全局表的标识。

2.3 查看结果

在MyCAT的配置文件中查看:

cat /usr/local/mycat/conf/schemas/db1.schema.json

或者通过Navicat后端数据库中查看发现所有的表全部出现了。

  

2.4 添加数据查看结果

insert into sys_dict(dict_type,dict_name,dict_value) values(1,\"男\",1);
insert into sys_dict(dict_type,dict_name,dict_value) values(1,\"女\",0);
# 上面插入的是所有的库中都能查看的数据

2.5 查询数据查看结果

select * from sys_dict;

会出现

+----+-----------+-----------+------------+

| id | dict_type | dict_name | dict_value |

+----+-----------+-----------+------------+

|  1  |         1   | 男          |          1   |

|  2  |         1   | 女          |          0   |

+----+-----------+-----------+------------+

或者通过Navicat查看表格sys_dict

发现数据并没有重复。

三、分片表配置【重点】

关键字:dbpartition、tbpartitition、tbpartitions、dbpartitions。

以上的运行成功必须是c0、c1的数据源配置没有问题才行。

3.1 创建表

create table orders(id bigint not null auto_increment,
               order_type int,customer_id int,
               amount decimal(10,2),  primary key(id)
               ) engine=innodb  default charset=utf8mb4 dbpartition by mod_hash(customer_id) tbpartition by mod_hash(customer_id) tbpartitions 1 dbpartitions 2;
# dbpartition by mod_hash(customer_id): 指定数据库的分片算法及使用哪一条数据进行分片
# hashtbpartition by mod_hash(customer_id) :指定表的分片算法及使用哪一条数据进行分片
# hashtbpartitions 1  表的分片数量
# dbpartitions 2  数据库的分片数量

3.2 查看MyCAT生成的配置

cat /usr/local/mycat/conf/schemas/db1.schema.json

3.3 添加数据

insert into orders(id,order_type,customer_id,amount) values(1,101,100,100101),(2,101,100,100101),(3,101,100,100101),(4,102,101,101102),(5,102,101,101102),(6,102,101,101102);

3.4 查询后台物理库

从图中我们可以看到数据库生成了。打开数据库后,里面的表也生成了,里面的数据也分开了,并不在一个表里。

3.5 MyCAT中查询(Navicat查看mycat的db1的order内容)

从上图中,我们发现查询的结果也帮我们合并了。

四、ER表配置

说明:在1.6的版本中,我们ER表的配置有关系的数据必须存放在相同的库中,但是在2.0中不用了,MyCAT2自动帮我们优化了。上面我们创建了一张订单表,接下来我们创建一张订单详情表。

4.1 创建表

create table orders_detail( id bigint auto_increment,
                    detail varchar(2000),
                    order_id bigint, primary key(id)
                    ) engine=innodb  default charset=utf8mb4 dbpartition by mod_hash(order_id) tbpartition by mod_hash(order_id) tbpartitions 1 dbpartitions 2;
#dbpartition by mod_hash(order_id):指定数据库的分片算法及使用哪一条数据进行分片hashtbpartition
#by mod_hash(order_id):指定表的分片算法及使用哪一条数据进行分片
#hashtbpartitions 1     表的分片数量
#dbpartitions 2         数据库的分片数量

4.2 查看MyCAT生成的配置

cat /usr/local/mycat/conf/schemas/db1.schema.json

从上图中我们可以出已经放到分片表里面了。

4.3 添加数据

insert into orders_detail values(1,\"详情1\",1);
insert into orders_detail values(2,\"详情2\",2);
insert into orders_detail values(3,\"详情3\",3);
insert into orders_detail values(4,\"详情4\",4);
insert into orders_detail values(5,\"详情5\",5);
insert into orders_detail values(6,\"详情6\",6);

4.4 查询后台物理库

从上图可知,dw0里面只存了三条。

发现dw1里面也存放了三条。

4.5 MyCAT中关联查询

select * from orders o inner join orders_detail od on(o.id=od.order_id);

如果在mysql输入会出现:

+----+------------+-------------+-----------+------+---------+----------+

| ID | ORDER_TYPE | CUSTOMER_ID | AMOUNT    | id0  | detail  | order_id |

+----+------------+-------------+-----------+------+---------+----------+

|  1 |        101 |         100 | 100101.00 |    1 | 详情1   |        1 |

|  2 |        101 |         100 | 100101.00 |    2 | 详情2   |        2 |

|  3 |        101 |         100 | 100101.00 |    3 | 详情3   |        3 |

|  4 |        102 |         101 | 101102.00 |    4 | 详情4   |        4 |

|  5 |        102 |         101 | 101102.00 |    5 | 详情5   |        5 |

|  6 |        102 |         101 | 101102.00 |    6 | 详情6   |        6 |

+----+------------+-------------+-----------+------+---------+----------+

五、分片算法简介

5.1取模哈希分片 MOD_HASH

1)如果分片值是字符串则先对字符串进行Hash转换为数值类型

2)分库键和分表键是同键

3)分表下标=分片值%(分库数量*分表数量)

4)分库下标=分表下标/分表数量

5)分库键和分表键是不同键

6)分表下标= 分片值%分表数量

7)分库下标= 分片值%分库数量

create table travelrecord ( ....) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by MOD_HASH (id) dbpartitions 6 tbpartition by MOD_HASH (id) tbpartitions 6;

5.2 范围哈希分片 RANGE_HASH

1)RANGE_HASH(字段1, 字段2, 截取开始下标)

2)仅支持数值类型,字符串类型

3)当时字符串类型时候,第三个参数生效

4)计算时候优先选择第一个字段,找不到选择第二个字段

5)如果是字符串则根据下标截取其后部分字符串,然后该字符串hash成数值

6)根据数值按分片数取余

7)要求截取下标不能少于实际值的长度

8)两个字段的数值类型要求一致

create table travelrecord(...)ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by RANGE_HASH(id,user_id,3) dbpartitions 3 tbpartition by RANGE_HASH(id,user_id,3) tbpartitions 3;

5.3字符串哈希分片 UNI_HASH

1)如果分片值是字符串则先对字符串进行hash转换为数值类型

2)分库键和分表键是同键

3)分库下标=分片值%分库数量

4)分表下标=(分片值%分库数量)*分表数量+(分片值/分库数量)%分表数量

5)分库键和分表键是不同键

6)分表下标= 分片值%分表数量

7)分库下标=分片值%分库数量

create table travelrecord ( ....) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by UNI_HASH (id) dbpartitions 6tbpartition by UNI_HASH (id) tbpartitions 6;

5.4日期哈希分片 YYYYDD

1)仅用于分库

2)DD是一年之中的天数

3)(YYYY*366+DD)%分库数

create table travelrecord ( ....) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by YYYYDD(xxx) dbpartitions 8tbpartition by xxx(xxx) tbpartitions 12;