MyCat09——分片技术之水平拆分

2023-11-26 23:09:21 浏览数 (1)

垂直拆分,解决了单库容量过大的问题,但是对于单表记录过大的问题,并没有解决。

1 水平拆分

按照数据表中某个字段的某种规则,将记录分散到多个库中,每个库该表中存储一部分记录,所有库中该表的记录并集,为该表所有记录的数据全集。

可以将其理解为按照数据的行进行拆分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。

2 实现分表

2.1 选择要拆分的表

MySQL单表存储数据条数,是存在瓶颈的。当单表数据达到1000万条时就会到达性能瓶颈,对查询效率有明显影响。此时,需要对该表做水平拆分的优化。

2.2 分析用来做分表的字段

以前边创建的 orders 表为例,可以根据不同的字段进行分表。

分表字段

效果

id

对于整个系统来说,所有订单都会被平衡地拆分到不同数据库中,但是结合使用场景,这个查询系统中所有订单的操作,没有实际价值,因为该项操作仅支持系统管理员操作

customer_id

将用户的订单平衡地拆分到不同数据库中。用户在下完订单后,对订单进行查询,该项操作的查询会非常频繁,如果根据该字段进行拆分,将极大提高查询效率,提升用户体验

2.3 修改配置文件 schema.xml

为数据表 orders 设置数据节点 dn1、dn2,并定义分片规则的名称为 customer_id_rule。

增加一个 table 节点:

  • name 为哪个数据表设置该分片规则,这里是 orders 表;
  • dataNode 将该表存储的位置,这里是同时存储于 dn1、dn2 节点;
  • rule 对表中数据水平拆分的规则,这里是规则名称,对应于 rule.xml 中的配置。

2.4 修改配置文件 rule.xml

在rule.xml配置文件中,增加名称为 customer_id_rule 的规则信息。

2.4.1 增加tableRule节点

添加用于水平拆分的规则名称:

  • columns 根据哪个字段来进行水平拆分;
  • algorithm 计算拆分的具体算法,该数据对应 rule.xml 配置文件中的一个 function 节点。
代码语言:html复制
<tableRule name="customer_id_rule">
                <rule>
                        <columns>customer_id</columns>
                        <algorithm>mod-long</algorithm>
                </rule>
</tableRule>

2.4.2 修改function节点

该节点是用于设置对数据存储分片的计算规则。

可以选择添加新的function节点,或者在确保对其他设置没有影响时,修改已有的function节点。

  • name 规则计算的名称,应与上一部分 algorithm 节点值一致;
  • class 调用规则计算的java类,这里使用的是取模运算 PartitionByMod;
  • property name="count" 要分片的节点数量。

通过这种设置后,即我们有两台数据库节点,在存储数据时,先做 x % 2 运算,当值为0时存储 dn1,值为1时存储到 dn2。

代码语言:html复制
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
     <!-- how many data nodes -->
     <property name="count">2</property>
</function>

2.5 为dn2节点创建数据表

因之前做分库时,仅将 orders 表保存到了 dn1 节点,这里需要在 dn2 节点中也创建 orders 表。

进入到 dn2 容器

docker exec -it db2 /bin/bash

进入到数据库命令行

mysql -uroot -p123456

创建 orders 表

create table orders(id int auto_increment primary key, order_type int, customer_id int, amount decimal(10,2));

2.6 重新启动mycat

mycat restart2.7 向orders表中批量插入数据

2.7.1 进入到mycat数据端口

mysql -uroot -p123456 -h192.168.137.3 -P8066

批量插入数据

insert into orders(id, order_type, customer_id, amount) values(1, 101, 100, 258.12);

insert into orders(id, order_type, customer_id, amount) values(2, 101, 101, 1543.0);

insert into orders(id, order_type, customer_id, amount) values(3, 101, 101, 57.03);

insert into orders(id, order_type, customer_id, amount) values(4, 101, 100, 5000);

insert into orders(id, order_type, customer_id, amount) values(5, 101, 100, 923);

insert into orders(id, order_type, customer_id, amount) values(6, 101, 102, 7583);

2.7.2 在mycat查询数据

2.7.3 在dn1节点查询数据

2.7.4 在dn2节点查询数据

所有插入的数据,根据 customer_id 在 dn1 和 dn2 节点进行了水平拆分。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞