文章目录
- 1.枚举分片的概念
- 2.水平分表枚举分片案例
- 2.1.准备测试的表结构
- 2.2.配置Mycat实现枚举分片的水平分表
- 2.2.1.配置Schema配置文件
- 2.2.2.配置Rule分片规则配置文件
- 2.2.3.配置Server配置文件
- 2.2.4.重启Mycat
- 2.3.写入数据观察水平分表效果
1.枚举分片的概念
枚举分片是根据表中的某个字段,配置可能出现的枚举值,被选中进行枚举分片的字段,该字段的值必须是可以当做分类的字段值,如果该字段的值在表中是不重复的,那么绝对不能作为枚举分片的字段,比如字段值是类型、状态、省份等等可以作为类别使用的字段,这种字段就适合作为枚举分片依据的字段。
枚举分片举例:
表中有个字段是专门存储省份的,我们要按照省份对表中的数据进行拆分,此时就需要使用到Mycat的枚举分片进行水平分表,省份全中国也才32个,我们就可以这样做:bj=0 sh=1,意思就是说如果省份字段的值为bj,那么就划分到第一个分片节点上,如果字段值为sh,就划分到第二个分片节点上。
2.水平分表枚举分片案例
需求:有一张用户信息表,该表的数据量庞大,在表中有字段记录了用户所在的省份,我们希望按照身份对这张表进行拆分,例如北京的用户写入到分片1节点的双主双从集群,上海的用户写入到分片2节点的双主双从集群。
下面我们通过枚举分片来实现这个需求。
2.1.准备测试的表结构
配置水平分表前,需要将要分的表在所有的分片节点中创建出来,
如果我们先配置了Mycat分片,就可以直接通过Mycat进行创建,无需登录到各个分片节点的集群里创建表了,会自动在分片节点中创建,但是目前我们还没有配置Mycat,所以我们直接登录到各个分片节点创建表。
这次我们直接在Mycat中创建这些表。
分片依旧是2个,还是之前垂直分库分表时使用的两套双主双从集群。
#在分片1节点中创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11 -e "use db_2; create table table_mjfp (id int,name varchar(10),province varchar(10));"
#在分片2节点中创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11 -e "use db_2; create table table_mjfp (id int,name varchar(10),province varchar(10));"
2.2.配置Mycat实现枚举分片的水平分表
2.2.1.配置Schema配置文件
[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">
<!--枚举分片-->
<table name="table_mjfp" dataNode="dn1,dn2" rule="sharding-by-intfile-mjfp"/>
</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分片规则配置文件中,默认情况下一种类型分片只有一组分片规则,如果一个库中有多张表都需要枚举分片,势必要声明多个规则,不同的表引用不同的规则,接下来我们自定义一个分片规则。
[root@mysql-1 ~]# vim /data/mycat/conf/rule.xml
<!--定义分片规则-->
<tableRule name="sharding-by-intfile-mjfp">
<rule>
<!--进行枚举分片的字段-->
<columns>province</columns>
<!--进行枚举分片的函数-->>
<algorithm>hash-int-mjfp</algorithm>
</rule>
</tableRule>
<!--枚举分片所对应的函数名称和调用类 这个函数名称要和tableRule中的algorithm字段对应上-->
<function name="hash-int-mjfp"
class="io.mycat.route.function.PartitionByFileMap">
<!--默认分片节点 当枚举字段的值不满足我们声明(值对应的关联分片节点时) 就将该条数据写入到默认的分片节点中 如果没有分片节点 当写入数据的枚举值字段值不满足分片对应关系时 数据将无法写入-->
<property name="defaultNode">0</property>
<!--枚举字段值的类型 0为Integer 1为String 如果我们的枚举字段值的类型是字符串需要声明type为1 如果字段值为数字则声明type为0 否则写入数据时会报错-->
<property name="type">1</property>
<!--将可能出现的枚举字段值与分片节点ID进行绑定 并且这些参数传入到函数中 实现枚举分片-->
<property name="mapFile">partition-hash-int.txt</property>
</function>
枚举分片使用时,需要先定义一个配置文件,在配置文件中声明枚举字段的值对应的分片节点ID,需要实现规划好枚举字段值的所有可能出现的值,避免有漏掉的字段值,没有在配置文件中定义,导致无法写入数据,当然如果在枚举函数中配置了defaultNode参数,可以避免此问题,当这条数据中的枚举字段值没有在配置文件中指定对应的节点ID,这条数据就被写入到默认的分片节点中。
[root@mysql-1 conf]# vim partition-hash-int.txt
bj=0
sh=1
含义:当枚举字段的值为bj时,该数据写入到分片ID为0的的分片节点,当值为sh时,写入到分片ID为1的分片节点。
2.2.3.配置Server配置文件
[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
[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...
2.3.写入数据观察水平分表效果
1)写入人员位于北京的数据
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into table_mjfp (id,name,province) values (1,'xm','bj');
mysql> insert into table_mjfp (id,name,province) values (2,'hah','bj');
mysql> insert into table_mjfp (id,name,province) values (3,'xixi','bj');
人员的地址为北京(province=bj),枚举字段值为bj,此时会被My成他划分到分片1的节点中存储这些数据。
2)写入人员位于上海的数据
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into table_mjfp (id,name,province) values (4,'aaa','sh');
mysql> insert into table_mjfp (id,name,province) values (5,'eee','sh');
人员的地址为北京(province=sh),枚举字段值为sh,此时会被Mycat划分到分片2的节点中存储这些数据。
3)写入人员位于天津的数据
[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into table_mjfp (id,name,province) values (6,'qqqq','tj');
前面写入的几条数据的枚举字段值都在枚举函数的配置文件中声明了,本次我们写入的(province=tj)tj并没有在配置文件中声明,由于我们配置了当枚举字段值都不满足配置文件中定义的,就写入到默认的分片1节点中,此时这条数据将被写入到分片1节点中。