MySQL-中间件mycat(二)

news2025/1/18 7:36:48

目录

🍁部署主从复制

🍁mycat读写分离

🍂修改配置文件

🍂设置balance与writeType

🍂设置switchType与slaveThreshold

🍂启动程序

🍂验证读写分离

🍁垂直拆分-分库

🍂实现分库

🍂测试分库

🍂总结分库

🍁水平拆分-分表

🍂实现分表

🍂测试分表

🍂连接查询

🍁全局表

🍂修改配置文件

🍂测试全局表

🍂常用分片规则


    🦐博客主页:大虾好吃吗的博客

    🦐MySQL专栏:MySQL专栏地址

        部署目标:本次需要开启五台服务器,主机及ip如下图所示。master1部署1主2从,master2省略从服务器,但理论上讲master2也是主服务器,只是这里省略了从服务器。Mycat的读写分离是建立在Mysql的主从复制的基础上的,所以前提是要配置好主从复制。

部署主从复制

        前提条件,修改my.cof文件,master1、master2开启二进制日志和server_id,从节点开启server_id,最后重启mysqld服务。

[root@master1 ~]# cat /etc/my.cnf 
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
server_id=1
log_bin=mysql-bin

mastr1登录mysql,创建主从复制用户,查看二进制文件

mysql> grant replication slave on *.* to rep@'192.168.8.%' identified by '123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
​
mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000006
         Position: 446
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)

登录slave1,指定主服务器。

mysql> change master to
    -> master_host='192.168.8.20',
    -> master_port=3306,
    -> master_user='rep',
    -> master_password='123',
    -> master_log_file='mysql-bin.000007',
    -> master_log_pos=655;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
​
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
​
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.8.20
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000007
          Read_Master_Log_Pos: 655
               Relay_Log_File: slave-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000007
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

登录slave2,指定主服务器。

mysql> change master to
    -> master_host='192.168.8.20',
    -> master_port=3306,
    -> master_user='rep',
    -> master_password='123',
    -> master_log_file='mysql-bin.000007',
    -> master_log_pos=655;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
​
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
​
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.8.20
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000007
          Read_Master_Log_Pos: 655
               Relay_Log_File: slave2-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000007
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

master2因为省略了两个从节点,所以目前还不需要配置。

mycat读写分离

修改配置文件

重点修改的是baliance=“3”和主机。

[root@mycat ~]# cat /usr/local/mycat/conf/schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
​
        <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="mytest" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="jdbc:mysql://192.168.8.20:3306" user="root"
                                   password="123">
                <readHost host="hostS1" url="jdbc:mysql://192.168.8.30:3306" user="root"
                                   password="123"></readHost>
                <readHost host="hostS2" url="jdbc:mysql://192.168.8.40:3306" user="root"
                                   password="123"></readHost>
                </writeHost>
                
        </dataHost>
</mycat:schema>

        可以看到远程的主机用户都是root,所以需要在所有mysql主机都创建一个远程root用户。注意:master1、master2、slave1、slave2都需要创建。

mysql> grant all on *.* to root@'192.168.8.%' identified by '123';
Query OK, 0 rows affected, 1 warning (0.00 sec)

设置balance与writeType

Balance参数设置:

修改的balance属性,通过此属性配置读写分离的类型,负载均衡类型,目前的取值有4 种:

  1. balance="0",不开启读写分离机制, 所有读操作都发送到当前可用的 writeHost 上。

  2. balance="1",全部的 readHost与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从 模式(M1->S1, M2->S2,并且M1 与 M2 互为主备),正常情况下, M2,S1,S2 都参与 select 语句的负载均衡。

  3. balance="2",所有读操作都随机的在 writeHost、 readhost 上分发。

  4. balance="3",所有读请求随机的分发到 readhost 执行,writerHost 不负担读压力

WriteType参数设置:

  1. writeType=“0”, 所有写操作都发送到可用的writeHost上。

  2. writeType=“1”,所有写操作都随机的发送到readHost。

  3. writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。

        “readHost是从属于writeHost的,即意味着它从那个writeHost获取同步数据,因此,当它所属的writeHost宕机了,则它也不会再参与到读写分离中来,即“不工作了”,这是因为此时,它的数据已经“不可靠”了。基于这个考虑,目前mycat 1.3和1.4版本中,若想支持MySQL一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据,则需要在Mycat里配置为两个writeHost并设置banlance=1。”

设置switchType与slaveThreshold

switchType 目前有三种选择:

-1:表示不自动切换

1 :默认值,自动切换

2 :基于MySQL主从同步的状态决定是否切换

        “Mycat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType="2" 与slaveThreshold="100",此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制。Mycat心跳机制通过检测 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延。“

启动程序

  1. 控制台启动 : 去mycat/bin 目录下执行 ./mycat console

  2. 后台启动 :去mycat/bin 目录下./mycat start 为了能第一时间看到启动日志,方便定位问题,这里我们选择控制台启动。

[root@mycat ~]# mycat console
Running Mycat-server...
Removed stale pid file: /usr/local/mycat/logs/mycat.pid
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
jvm 1    | 
jvm 1    | Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

验证读写分离

登录master1修改my.cnf文件,添加binlog_format参数。创建mytest库、tb1表。

[root@master1 ~]# vim /etc/my.cnf
#添加下面参数
binlog_format=STATEMENT
[root@master1 ~]# systemctl restart mysql                       #重启后稍等查看slave两个线程yes
[root@master1 ~]# mysql -uroot -p123
#省略部分内容
mysql> create database mytest character set utf8;
Query OK, 1 row affected (0.01 sec)
​
mysql> use mytest;
Database changed
mysql> create table tb1(
    -> id int,
    -> name varchar(20));
Query OK, 0 rows affected (0.02 sec)

1. 在master1主机插入下列数据,就可以测试主从主机数据不一致了。 (@@hostname表示插入的变量为主机名)

mysql> insert into tb1 values(1,@@hostname);
Query OK, 1 row affected, 1 warning (0.02 sec)

2. 登录mycat里查询tb1表,刷新两次可以看到两个name列不同,因为读的是从表,但是主机名不一样。所以可以分析出,读写分离成功。

[root@master2 ~]# mysql -umycat -p123456 -P8066 -h 192.168.8.10
#省略部分内容
mysql> use TESTDB;

mysql> select * from tb1;
+----+-------+
| id | name  |
+----+-------+
|  1 | slave |
+----+-------+
1 row in set (0.01 sec)

mysql> select * from tb1;
+----+--------+
| id | name   |
+----+--------+
|  1 | slave2 |
+----+--------+
1 row in set (0.01 sec)

垂直拆分-分库

        一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类, 分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同的库上面, 如何划分表 分库的原则: 有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到不同的库里。

#客户表 rows:20万
CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);

#订单表 rows:600万
CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);

#订单详细表 rows:600万
CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);

#订单状态字典表 rows:20
CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);

        上面有四个表如何分库?客户表分在一个数据库,另外三张都需要关联查询,分在另外一个数据库。

实现分库

        因为master2没有mytest库,所以提前需要登录master2,创建该库(生产环境中,会直接备份,然后导入)。

[root@master2 ~]# mysql -uroot -p123
#省略部分内容
mysql> create database mytest character set utf8;
Query OK, 1 row affected (0.00 sec)

修改配置文件

        登录mycat,修改schema.xml 配置文件

[root@mycat conf]# cd /usr/local/mycat/conf/
[root@mycat conf]# cat schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2"></table>						#添加
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="mytest" />
        <dataNode name="dn2" dataHost="localhost2" database="mytest" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="jdbc:mysql://192.168.8.20:3306" user="root"
                                   password="123">
                <readHost host="hostS1" url="jdbc:mysql://192.168.8.30:3306" user="root"
                                   password="123"></readHost>
                <readHost host="hostS2" url="jdbc:mysql://192.168.8.40:3306" user="root"
                                   password="123"></readHost>
                </writeHost>
                
        </dataHost>
        <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"				#下面七行添加
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM2" url="jdbc:mysql://192.168.8.50:3306" user="root"
                                   password="123">
                </writeHost>

        </dataHost>
</mycat:schema>
[root@mycat conf]# mycat console
Running Mycat-server...
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
jvm 1    | 
jvm 1    | Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

测试分库

登录mycat登录,创建四个表。

[root@master2 ~]# mysql -umycat -p123456 -P8066 -h 192.168.8.10
#省略登录信息
mysql> use TESTDB;

mysql> CREATE TABLE customer(
    -> id INT AUTO_INCREMENT,
    -> NAME VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.02 sec)
 OK!

mysql> CREATE TABLE orders(
    -> id INT AUTO_INCREMENT,
    -> order_type INT,
    -> customer_id INT,
    -> amount DECIMAL(10,2),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)
 OK!

mysql> CREATE TABLE orders_detail(
    -> id INT AUTO_INCREMENT,
    -> detail VARCHAR(2000),
    -> order_id INT,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)
 OK!

mysql> CREATE TABLE dict_order_type(
    -> id INT AUTO_INCREMENT,
    -> order_type VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.03 sec)
 OK!

分别登录master1、master2,查看表。

master1为:

mysql> show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| dict_order_type  |
| orders           |
| orders_detail    |
| tb1              |
+------------------+
4 rows in set (0.00 sec)

master2为:

mysql> show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| CUSTOMER         |
+------------------+
1 row in set (0.00 sec)

mysql> desc CUSTOMER;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| ID    | int(11)      | NO   | PRI | NULL    | auto_increment |
| NAME  | varchar(200) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

总结分库

        由上可见,分库成功,简单的来讲,由mycat修改配置文件,dn1指向master1,dn2指向master2。登录mycat创建表,customer表已经指定dn2了,而其他表则创建到dn1。

水平拆分-分表

        相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中, 每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就 是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。

实现分表

        选择要拆分的表 MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率, 需要进行水平拆分(分表) 进行优化。 例如:例子中的 orders、 orders_detail 都已经达到600 万行数据,需要进行分表优化。 分表字段 以 orders 表为例,可以根据不同自字段进行分表

编号分表字段效果
1id(主键、 或创建时间)查询订单注重时效,历史订单被查询的次数少,如此分片会造成一个节点访问多,一个访问少,不平均。
2customer_id(客户id)根据客户 id 去分,两个节点访问平均,一个客户的所有订单都在同一个节点

修改配置文件

        登录mycat服务器,修改schema.xml 配置文件,为 orders 表设置数据节点为 dn1、 dn2, 并指定分片规则为 mod_rule(自定义的名字)

[root@mycat conf]# cat schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2"></table>
                <table name="orders" dataNode="dn1,dn2" rule="mod_rule">			#添加
		</table>																	#添加
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="mytest" />
        <dataNode name="dn2" dataHost="localhost2" database="mytest" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="jdbc:mysql://192.168.8.20:3306" user="root"
                                   password="123">
                <readHost host="hostS1" url="jdbc:mysql://192.168.8.30:3306" user="root"
                                   password="123"></readHost>
                <readHost host="hostS2" url="jdbc:mysql://192.168.8.40:3306" user="root"
                                   password="123"></readHost>
                </writeHost>
                
        </dataHost>
        <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM2" url="jdbc:mysql://192.168.8.50:3306" user="root"
                                   password="123">
                </writeHost>

        </dataHost>
</mycat:schema>

登录mycat服务器,修改配置文件 rule.xml,具体修改内容看下图红框中内容。

[root@mycat conf]# vim rule.xml 
#省略部分内容
	<tableRule name="mod_rule">									#修改
                <rule>
                        <columns>id</columns>
                        <algorithm>mod-long</algorithm>
                </rule>
        </tableRule>
#省略部分内容
        <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
                <!-- how many data nodes -->
                <property name="count">2</property>				#修改
        </function>
#省略部分内容

#在 rule 配置文件里新增分片规则 mod_rule,并指定规则适用字段为id。

#还有选择分片算法 mod-long(对字段求模运算) , id 对两个节点求模,根据结果分片。

#配置算法 mod-long 参数 count 为 2,两个节点。

测试分表

1. 在数据节点 dn2 上建 orders 表

[root@master2 ~]# mysql -uroot -p123
#省略部分内容
mysql> use mytest;

mysql> CREATE TABLE orders(
    -> id INT AUTO_INCREMENT,
    -> order_type INT,
    -> customer_id INT,
    -> amount DECIMAL(10,2),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.03 sec)

2. 重启 Mycat,让配置生效

[root@mycat conf]# mycat console

3. 访问 Mycat 实现分片

[root@master2 ~]# mysql -umycat -p123456 -P8066 -h192.168.8.10

4. 在 mycat 里向 orders 表插入下面六行数据, INSERT 字段不能省略

INSERT INTO orders(id,order_type,customer_id,amount) VALUES(1,101,100,100100);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);

5. 分别在mycat、master1、master2中查看orders表数据,分表成功

#mycat
mysql> select * from orders;
+------+------------+-------------+-----------+
| id   | order_type | customer_id | amount    |
+------+------------+-------------+-----------+
|    2 |        101 |         100 | 100300.00 |
|    4 |        101 |         101 | 103000.00 |
|    6 |        102 |         100 | 100020.00 |
|    1 |        101 |         100 | 100100.00 |
|    3 |        101 |         101 | 120000.00 |
|    5 |        102 |         101 | 100400.00 |
+------+------------+-------------+-----------+
6 rows in set (0.01 sec)
#master1
mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  2 |        101 |         100 | 100300.00 |
|  4 |        101 |         101 | 103000.00 |
|  6 |        102 |         100 | 100020.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)
#master2
mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  1 |        101 |         100 | 100100.00 |
|  3 |        101 |         101 | 120000.00 |
|  5 |        102 |         101 | 100400.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

连接查询

1. 登录mycat服务器,修改配置文件,添加下列内容,表示可以外键连接。

[root@mycat conf]# cat schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2"></table>
                <table name="orders" dataNode="dn1,dn2" rule="mod_rule">
                        <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />		#添加
		</table>
#省略部分内容

2. 登录master2上创建 orders_detail表。

[root@master2 ~]# mysql -uroot -p123

mysql> use mytest;

mysql> CREATE TABLE orders_detail(
    -> id INT AUTO_INCREMENT,
    -> detail VARCHAR(2000),
    -> order_id INT,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

3. 重启 Mycat 访问,并登录Mycat 向 orders_detail 表插入数据

[root@mycat conf]# mycat console

重启后登录mycat

[root@master2 ~]# mysql -umycat -p123456 -P8066 -h192.168.8.10
#省略部分内容
mysql> use TESTDB;

mysql> insert into orders_detail(id,detail,order_id) values (1,'detail',1);
Query OK, 1 row affected (0.25 sec)
 OK!

mysql>  insert into orders_detail(id,detail,order_id) values (2,'detail',2);
Query OK, 1 row affected (0.02 sec)
 OK!

mysql> insert into orders_detail(id,detail,order_id) values (3,'detail',3);
Query OK, 1 row affected (0.01 sec)
 OK!

mysql>  insert into orders_detail(id,detail,order_id) values (4,'detail',4);
Query OK, 1 row affected (0.01 sec)
 OK!

mysql> insert into orders_detail(id,detail,order_id) values (5,'detail',5);
Query OK, 1 row affected (0.01 sec)
 OK!

mysql> insert into orders_detail(id,detail,order_id) values (6,'detail',6);
Query OK, 1 row affected (0.01 sec)
 OK!

mysql> select o.*,od.detail from orders as o inner join orders_detail as od on o.id=od.order_id;
+------+------------+-------------+-----------+--------+
| id   | order_type | customer_id | amount    | detail |
+------+------------+-------------+-----------+--------+
|    2 |        101 |         100 | 100300.00 | detail |
|    4 |        101 |         101 | 103000.00 | detail |
|    6 |        102 |         100 | 100020.00 | detail |
|    1 |        101 |         100 | 100100.00 | detail |
|    3 |        101 |         101 | 120000.00 | detail |
|    5 |        102 |         101 | 100400.00 | detail |
+------+------------+-------------+-----------+--------+
6 rows in set (0.07 sec)

全局表

        在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联, 就成了比较 棘手的问题,考虑到字典表具有以下几个特性:

1、 变动不频繁

2、 数据量总体变化不大

3、数据规模不大,很少有超过数十万条记录 鉴于此, Mycat 定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:

  1. 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性

  2. 全局表的查询操作,只从一个节点获取

  3. 全局表可以跟任何一个表进行 JOIN 操作 将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据 JOIN 的难题。 通过全局表+基于 E-R 关系的分片策略, Mycat 可以满足 80%以上的企业应用开发

修改配置文件

登录mycat修改 schema.xml 配置文件

[root@mycat conf]# cat schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2"></table>
                <table name="orders" dataNode="dn1,dn2" rule="mod_rule">
                        <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
		</table>
		<table name="dict_order_type" dataNode="dn1,dn2" type="global">
	</table>
        </schema>
#省略部分内容

测试全局表

1. 在master2创建 dict_order_type 表

[root@master2 ~]# mysql -uroot -p123
#省略部分内容
mysql> use mytest

mysql> CREATE TABLE dict_order_type(
    -> id INT AUTO_INCREMENT,
    -> order_type VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

2. 重启 Mycat

[root@mycat conf]# mycat console

3. 访问 Mycat 向 dict_order_type 表插入数据

[root@master2 ~]# mysql -umycat -p123456 -P8066 -h192.168.8.10
#省略部分内容
mysql> use TESTDB

mysql> insert into dict_order_type (id,order_type) values (101,'type1');
Query OK, 1 row affected (0.22 sec)
 OK!

mysql> insert into dict_order_type (id,order_type) values (102,'type2');
Query OK, 1 row affected (0.03 sec)
 OK!

4. 分别登录mycat、master1、master2,查看表,最终都可以看到id为101,102的数据内容。

mysql> select * from dict_order_type;
+-----+------------+
| id  | order_type |
+-----+------------+
| 101 | type1      |
| 102 | type2      |
+-----+------------+
2 rows in set (0.00 sec)

常用分片规则

1、 取模 此规则为对分片字段求摸运算。 也是水平分表最常用规则。 5.1 配置分表中, orders 表采用了此规则。

2、 分片枚举 通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务 需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422829.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【从零开始学Skynet】基础篇(九):调试控制台服务

Skynet自带了一个调试控制台服务debug_console&#xff0c;启动它之后&#xff0c;可以查看节点的内部状态。 1、启用调试控制台 &#xff08;1&#xff09;在skynet/examples目录下新建main_console.lua文件&#xff0c;代码如下所示&#xff1a; local skynet require &quo…

【Python_Scrapy学习笔记(二)】创建Scrapy爬虫项目

创建Scrapy爬虫项目 前言 本文主要介绍如何创建并运行 Scrapy 爬虫项目。 正文 1、创建 Scrapy 框架 Scrapy 框架提供了 scrapy 命令用来建立 Scrapy 工程&#xff0c;在终端 terminal 中输入以下命令&#xff1a; scrapy startproject 自定义的项目名称创建好爬虫项目文件…

2023年超实用的27个VSCode插件推荐

Visual Studio Code&#xff0c;或者称作VS Code&#xff0c;是一个广为人知且评价很高的代码编辑器&#xff0c;它有许多特性和扩展功能&#xff0c;以增强开发体验。使用VS Code的主要好处之一是它的灵活性&#xff0c;允许开发人员根据自己的特定需求进行自定义。此外&#…

02-app漏洞发现

漏洞发现-APP应用之漏洞探针类型利用修复 一、思维导图&#xff1a; 思路说明&#xff1a; apk反编译提取URL或抓包获取url&#xff0c;进行web应用测试&#xff0c;如不存在或走其他协议的情况下&#xff0c;需采用网络接口抓包进行数据获取&#xff0c;转至其他协议安全测试…

【jvm系列-05】精通运行时数据区共享区域---方法区

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

Redis 6.0的多线程是如何工作的

来了解下 6.0 版本中新出的多线程特性。 1、多线程处理网络IO&#xff0c;单线程执行命令 Redis 一直被大家熟知的就是它的单线程架构&#xff0c;虽然有些命令操作可以用后台线程或子进程执行&#xff08;比如数据删除、快照生成、AOF 重写&#xff09;&#xff0c;但是&…

freeswitch带媒体压力测试方案

概述 原本的计划是使用sipp完成带媒体压力测试&#xff0c;但是实际测试过程中发现sipp的媒体处理功能有问题&#xff08;也有可能是我使用的姿势不对&#xff09;。 sipp在带媒体的情况下&#xff08;600路并发开始&#xff09;&#xff0c;出现大量的不响应和响应延迟&…

请求响应-响应

前面已经说了我们重点关注的就是XXXcontroller类 进行请求接收 和响应 接收参数那些我们在请求部分讲过了 现在我们来处理响应部分 响应 设置响应数据 可以发现其实我们之前都是设置过的 比如那个Hello World 浏览器都接收到了且在浏览器上进行了输出 这里的是返回值作为这个…

Direct3D 12——纹理——纹理

纹理不同于缓冲区资源&#xff0c;因为缓冲区资源仅存储数据数组&#xff0c;而纹理却可以具有多个mipmap层级(后 文有介绍)&#xff0c;GPU会基于这个层级进行相应的特殊操作&#xff0c;例如运用过滤器以及多重采样。支持这些特殊 的操作纹理资源都被限定为一些特定的数据格式…

7 个最好的 Word 转 PDF 转换器

如果您使用 Word 文件&#xff0c;您可能在某个时候遇到过将 Word 文件转换为 PDF 的紧迫问题。PDF 文件有很多优点。它们通常更紧凑&#xff0c;无论您在哪里打开它们看起来都一样。PDF 还允许您共享文档&#xff0c;而不必冒有人更改内容的风险。那么如何将 Word 文档转换为 …

小白学网络安全要学些什么?

一.网络安全学些什么呢&#xff1f; 虽然网上已经有非常多的学习路线了&#xff0c;但是仍然有很多零基础的小白还是不懂网络安全到底应该要怎么去学习&#xff0c;我也经常会在后台收到这样的问题“我想学网络安全&#xff0c;需要先学编程语言吗&#xff1f;”、“学渗透就业…

【python零碎】

1. 拼接字符中&#xff0c;插入变量 >>> shepherd "Mary" >>> age 32 >>> stuff_in_string "Shepherd {} is {} years old.".format(shepherd, age) >>> print(stuff_in_string) Shepherd Mary is 32 years old. &…

HIT-CSAPP 第五章 面向程序的优化方法(1)

考纲: 1.面向程序性能的优化 面向编译器的程序优化方法:减少过程调用、减少内存引用、指令并行等方法等方法。面向流水线、超标量、向量CPU的程序优化方法。 2.存储器的层次结构 优化编译器的能力和局限性 内存别名使用妨碍函数优化 void twiddle1(long *xp, long *yp){ //…

ERTEC200P-2 PROFINET设备完全开发手册(4-1)

ERTEC200P-2作为应用处理器&#xff0c;既可以单独使用&#xff0c;通过GPIO扩展实现基本的IO功能。也可以配合外部主机&#xff08;例如单片机&#xff09;实现更复杂的应用。ERTEC200P-2与外部主机接口的示意图如下。常用的接口包括UART&#xff0c;SPI&#xff0c;XHIF接口。…

MSI: 基于多元同步索引的SSVEP频率识别算法

MSI: 基于多元同步索引的SSVEP频率识别算法1.算法背景2.算法原理3.Python代码实现1.算法背景 脑机接口&#xff08;Brain-Computer Interface, BCI&#xff09;因其在神经工程与神经科学中的广泛应用价值而备受研究者们的关注。BCI系统可以在人类或动物被试与外部设备之间提供…

“深元AI”赋能传统加油站智能化转型,全力打造新一代智慧加油站

历届的全国两会和党代会上&#xff0c;“安全生产”始终是核心议题。党的二十大报告提出&#xff1a;推动公共安全治理模式向事前预防转型&#xff0c;并强调要加强重点行业、重点领域安全监管&#xff0c;提高防灾减灾救灾和重大突发公共事件处置保障能力。同时&#xff0c;国…

Linux_vim编辑器

Vi编辑器是所有Unix及Linux系统下标准的编辑器&#xff0c;类似于windows系统下的notepad&#xff08;记事本&#xff09;编辑器&#xff0c;由于在Unix及Linux系统的任何版本&#xff0c;Vi编辑器是完全相同的&#xff0c;因此可以在其他任何介绍vi的地方都能进一步了解它&…

Java的CPU 飙升700%优化的真实案例

最近负责的一个项目上线&#xff0c;运行一段时间后发现对应的进程竟然占用了700%的CPU&#xff0c;导致公司的物理服务器都不堪重负&#xff0c;频繁宕机。 那么,针对这类java进程CPU飙升的问题&#xff0c;我们一般要怎么去定位解决呢&#xff1f; 采用top命令定位进程 登…

spring初始项目创建

首先进入http://spring.p2hp.com/projects/spring-framework.html&#xff0c;点击git按钮 点击Access to Binaries中的链接 找到里程碑版本&#xff0c;要引入仓库地址 这里的spring-context依赖只是基础的spring框架的依赖 在resources目录下创建spring的xml文件&#xff0c…

中国31个主要城市绿地数据(空间分辨率为1m)

近年来&#xff0c;为了满足生态文明和可持续发展的理念&#xff0c;科学的城市绿地规划和管理在中国越来越受到重视。因此&#xff0c;提高UGS分类体系和布局布局的合理性&#xff0c;建设绿色宜居城市&#xff0c;是近年来政府和学者关注的重点。为此&#xff0c;本文选取中国…