Mycat2(四)mycat2 分库分表

news2024/11/16 1:36:05

文章目录

  • 一、分库分表原理
    • 垂直切分:分库
    • 水平切分:分表
  • 二、分库分表环境准备
    • 示例:
    • 开始准备环境
  • 三、实现分库分表
    • 3.1 分库分表--广播表(BROADCAST)
    • 3.2 分库分表--分片表(dbpartition、tbpartition)
    • 3.3 分库分表--ER表(自动识别)
  • 四、常用的分片规则
    • 常用分片规则简介
      • MOD_HASH
      • RIGHT_SHIFT
      • YYYYMM
      • MMDD
  • 五、全局序列
    • 1. 建表语句方式关闭全局序列(AUTO_INCREMENT)
    • 2. 设置mycat数据库方式获取全局序列

一、分库分表原理

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图:

垂直切分:分库

系统被拆分为用户、订单、支付多个模块,部署在不同机器上。
分库的原则:由于跨库不能关联查询,所以有紧密关联的表应当放在一个数据库中,相互没有关联的表可以分不到不同的数据库。
在这里插入图片描述
eg:

客户表 customer   rows 20W
订单表 orders   rows 600W
订单详情表 orders_detail   rows 600W
订单状态字典表 dic_order_type   rows 600W
分库方案:将客户表单独分到一个数据库,订单相关联的表放到一个数据库。

水平切分:分表

  1. 分表字段
    以orders表为例,可以根据不同的字段来进行分表。
分表字段效果
ID(主键、创建时间)查询订单注重实效,历史订单查询次数少。带来的问题是会造成一个时间段分片数据多则该节点访问多,另一个访问少。分片不均匀。
customer_id(客户ID)根据客户ID分片,俩个节点平均访问,一个客户的订单都在一个库中,查询历史订单较快

二、分库分表环境准备

示例:

执行注释脚本,创建集群配置

/*! mycat:createCluster{
	"name":"prototype",
	"masters":["rwSepw1"],
	"replicas":["rwSepr1"]
	} */

也可以修改配置文件

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

注意:如果MySQL服务没有启动的话,需要注释掉mycat\conf\datasource下的数据源文件再启动,否则报错会导致mycat启动失败。
mycat2分库分表的优势:可以在终端直接使用注释脚本创建数据源、集群、库存,并在创建时指定分库、分表。

开始准备环境

  1. 添加数据源
    -- 添加数据源dw1-13306、dw2-23306、dr1-33306、dr2-43306
    /*+ mycat:createDataSource{
    "name":"dw1",
    "url":"jdbc:mysql://127.0.0.1:13306/db1?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true",
    "user":"root",
    "password":"admin"
    }*/;
    -- 查看
    /*+ mycat:showDataSources{} */
    
  2. 添加集群配置
    /*! mycat:createCluster{
    	"name":"c1",
    	"masters":["dw1"],
    	"replicas":["dr1"]
    	} */
    -- 查看
    /*! mycat:showClusters{} */
    

三、实现分库分表

3.1 分库分表–广播表(BROADCAST)

关键字:BROADCAST

  1. 执行建表语句
    create table db1. `dic_order_type` (
    	id int not null auto_increment,
    	dcode varchar(100) not null,
    	dname varchar(100) not null,
    	primary key(id)
    )engine=InnoDB default charset=utf8 BROADCAST;
    -- 这里我们加上关键字 BROADCAST,即可将创建的表标识为广播表。
    
  2. 在mycat中执行sql脚本,我们可以看到mycat\conf\schemas\db1.schema.json已经发生了变化。globalTables增加了dic_order_type表配置,其中的broadcast配置了两个targetName。
    {
    	"customTables":{},
    	"globalTables":{
    		"dic_order_type":{
    			"broadcast":[
    				{
    					"targetName":"c1"
    				},
    				{
    					"targetName":"c2"
    				}
    			],
    			"createTableSQL":"/* ApplicationName=DBeaver 22.3.1 - SQLEditor <Script-4.sql> */\nCREATE TABLE db1.`dic_order_type` (\n\tid int NOT NULL AUTO_INCREMENT,\n\tdcode varchar(100) NOT NULL,\n\tdname varchar(100) NOT NULL,\n\tPRIMARY KEY (id)\n) BROADCAST ENGINE = InnoDB CHARSET = utf8",
    			"sequenceType":"NO_SEQUENCE"
    		}
    	},
    	"normalProcedures":{},
    	"normalTables":{},
    	"schemaName":"db1",
    	"shardingTables":{},
    	"views":{}
    }
    
  3. 验证:打开13306-43306可以发现四个表中都已存在数据。原理:mycat2对建表sql进行拦截,并全局转发到所有数据节点上。

3.2 分库分表–分片表(dbpartition、tbpartition)

关键语法:
dbpartition BY mod_hash(customer_id) tbpartition BY mod_hash(customer_id) tbpartitions 1 dbpartitions 2;

  1. 建表语句
    CREATE TABLE db1.orders( 
      id BIGINT NOT NULL AUTO_INCREMENT,
      order_type INT, 
      customer_id INT,
      amount DECIMAL(10,2), 
      PRIMARY KEY(id),
      KEY id(id)
    )ENGINE=INNODB  DEFAULT CHARSET=utf8 
    dbpartition BY mod_hash(customer_id) tbpartition BY mod_hash(customer_id)
    tbpartitions 1 dbpartitions 2;
    -- dbpartition 设置数据库分片规则;tbpartition 设置表分片规则
    -- tbpartitions 1 dbpartitions 2 配置分片数。表分成一片,数据库分成两片(即两个数据库各分1片)
    

    注意:这里我在执行的时候遇到了一个问题,就是报错说c0集群can not found。是由于我在之前准备环境的时候准备的c1,和c2。这里我们把c2改成c0即可。

  2. 插入数据
    -- 新增数据
    INSERT INTO db1.orders values(1,101,100,2010);
    INSERT INTO db1.orders values(2,101,100,2020);
    INSERT INTO db1.orders values(3,101,101,2030);
    INSERT INTO db1.orders values(4,101,101,2040);
    INSERT INTO db1.orders values(5,102,101,2050);
    INSERT INTO db1.orders values(6,102,100,2060);
    
  3. 查看数据:我们可以看到数据是按照分片键排序的,而不是按照ID排序的。这说明数据是分布在不同是库,然后分别查询拼接起来的。我们打开物理库也可以看到数据分布到了不同的物理表上。
    映射关系:
    				`-->	mysql db1_0.orders_0
    mycat  db1.orders 
    				`-->	mysql db1_1.orders_1
    
    在这里插入图片描述
  4. 查看配置信息mycat\conf\schemas\db1.schema.json,可见shardingTables中新增了配置信息
    {
    	"customTables":{},
    	"globalTables":{},
    	"normalProcedures":{},
    	"normalTables":{},
    	"schemaName":"db1",
    	"shardingTables":{
    		"orders":{
    			"createTableSQL":"/* ApplicationName=DBeaver 22.3.1 - SQLEditor <Script-4.sql> */\nCREATE TABLE db1.orders (\n\tid BIGINT NOT NULL AUTO_INCREMENT,\n\torder_type INT,\n\tcustomer_id INT,\n\tamount DECIMAL(10, 2),\n\tPRIMARY KEY (id),\n\tKEY id (id)\n) ENGINE = INNODB CHARSET = utf8\nDBPARTITION BY mod_hash(customer_id) DBPARTITIONS 2\nTBPARTITION BY mod_hash(customer_id) TBPARTITIONS 1",
    			"function":{
    				"properties":{
    					"dbNum":"2",
    					"mappingFormat":"c${targetIndex}/db1_${dbIndex}/orders_${index}",
    					"tableNum":"1",
    					"tableMethod":"mod_hash(customer_id)",
    					"storeNum":2,
    					"dbMethod":"mod_hash(customer_id)"
    				}
    			},
    			"shardingIndexTables":{}
    		}
    	},
    	"views":{}
    }
    

3.3 分库分表–ER表(自动识别)

  1. 建表语句:创建orders_detail表,与orders表关联。
-- 这里我们并没有写orders_detail与orders的关系,但是mycat会自动的将这张表与orders分到一个库中。
CREATE TABLE orders_detail(
  id BIGINT NOT NULL AUTO_INCREMENT,
  detail VARCHAR(2000),
  order_id INT,
  PRIMARY KEY(id)
)ENGINE=INNODB  DEFAULT CHARSET=utf8 
dbpartition BY mod_hash(order_id) tbpartition BY mod_hash(order_id)
tbpartitions 1 dbpartitions 2;
  1. 插入数据
INSERT INTO orders_detail VALUES(1,'1111',1);
INSERT INTO orders_detail VALUES(2,'2222',2);
INSERT INTO orders_detail VALUES(3,'3333',3);
INSERT INTO orders_detail VALUES(4,'4444',4);
INSERT INTO orders_detail VALUES(5,'5555',5);
INSERT INTO orders_detail VALUES(6,'6666',6);
  1. 验证:查询数据库,并打开物理表可以看到数据分布到了不同的库和表中。
select * from orders o;
id|order_type|customer_id|amount |id0|detail|order_id|
--+----------+-----------+-------+---+------+--------+
 1|       101|        100|2010.00|  1|1111  |       1|
 2|       101|        100|2020.00|  2|2222  |       2|
 3|       101|        101|2030.00|  3|3333  |       3|
 4|       101|        101|2040.00|  4|4444  |       4|
 5|       102|        101|2050.00|  5|5555  |       5|
 6|       102|        100|2060.00|  6|6666  |       6|
  1. 查询与关联查询:通过查询我们发现orders表与orders_detail表中order_id相同的并没有分布在同一个数据库。
SELECT * FROM orders o ;
SELECT * FROM orders_detail od;

SELECT * FROM orders o 
LEFT JOIN orders_detail od ON o.id = od.order_id ;

在这里插入图片描述
但俩个表具有相同的分片算法,但是分片字段不同。
mycat2在涉及这种两个表join分片字段等价关系的时候可以完成join的下推。
其无需指定ER表,是自动识别的,具体看分片算法的接口。我们可以用/*+ mycat:showErGroup{} */脚本来查看配置的表是否具有ER关系。
其中groupId表示相同的分组,在该分组的表具有相同的存储分布。

/*+ mycat:showErGroup{} */
groupId|schemaName|tableName    |
-------+----------+-------------+
0      |db1       |orders       |
0      |db1       |orders_detail|

四、常用的分片规则

  1. 分片算法简介
    Mycat2支持常用的(自动)HASH型分片算法也兼容1.6的内置的(cobar)分片算法。
    HASH型分片算法默认要求集群名字以c为前缀,数字为后缀,c0就是分片表第一个节点,c1就是第二个节点,该命名规则允许用户手动改变。
  2. mycat2与1.X版本区别
    mycat2的hash型分片算法多基于MOD_HASH,对应Java的%取余运算。
    mycat2的hash型分片算法对于值的处理,总是把分片值转换到列属性的数据类型再做计算。
    mycat2的hash型分片算法适用于等价条件查询。
  3. 分片规则与适用性
分片算法描述分库分表数值类型
MOD_HASH取模哈希数值,字符串
UNI_HASH取模哈希数值,字符串
RIGHT_SHIFT右移哈希数值
RANGE_HASH两字段其一取模数值,字符串
YYYYMM按年月哈希DATE,DATETIME
YYYYDD按年月哈希DATE,DATETIME
YYYYWEEK按年周哈希DATE,DATETIME
HASH取模哈希数值,字符串,如果不是,则转换成字符串
MM按月哈希DATE,DATETIME
DD按日期哈希DATE,DATETIME
MMDD按月日哈希DATE,DATETIME
WEEK按周哈希DATE,DATETIME
STR_HASH字符串哈希字符串

常用分片规则简介

MOD_HASH

[数据分片]hash形式的分片算法。如果分片键是字符串,会将字符串hash转换为数值类型。

  1. 分库键和分表键相同:
    • 分表下标:分片值%(分库数量*分表数量)
    • 分库下标:分表下表/分库数量
  2. 分库键和分表键相同:
    • 分表下标:分片值%分表数量
    • 分库下标:分片值%分库数量

RIGHT_SHIFT

[数据分片]hash形式的分片算法。仅支持数值类型。
分片值右移两位,按分片数量取余。

YYYYMM

[数值分片]hash形式的分片算法。仅用于分库。
(YYYY*12+MM)%分库数量,MM为1–12。

MMDD

仅用于分表。仅DATE、DATETIME类型。
一年之中第几天%分表数。tbpartitions不能超过366。

五、全局序列

Mycat2默认使用雪花算法作为全局序列。如果不需要mycat默认的全局序列,可以通过配置关闭自动全局序列。

1. 建表语句方式关闭全局序列(AUTO_INCREMENT)

如果不需要自增序列,则修改mycat配置文件中的建表SQL,取消AUTO_INCREMENT关键字即可。需要则配置上即可。
这样mycat则不认为该字段为自增字段,而会交给mysql的自增主键功能补全自增键。
雪花算法:引入了时间戳和ID保持自增的分布式ID生成算法。
在这里插入图片描述

2. 设置mycat数据库方式获取全局序列

  1. 在prototype服务器的db1数据库导入conf\dbseq.sql文件。
    mycat2已经提供了相关sql脚本,需要在对应数据库下运行脚本,但不能通过mycat客户端执行。
  2. 添加全局序列配置文件
    进入mycat\conf\sequences目录,添加配置文件{数据库名}_{表名}.sequence.json
    配置如下内容:
{
	"clazz": "io.mycat.plug.sequence.SequenceMySQLGenerator",
	"name": "db1_tableName",
	"targetName": "prototype",
	"schemaName": "db1"
}

可选参数targetName更改序列号服务器,targetName是执行自增序列的节点,也是dbseq.sql导入的节点。其导入的当前库的苦命与逻辑表的逻辑库名一致。
导入后可以检查库下是否有mycat_sequence表。在有多个mycat做集群的时候需要修改increment值,不能严格的让其自增。Name列的值是对应的库名_表名,需要自己设置,即插入一条数据,用于记录序列号。
在这里插入图片描述

  1. 切换为数据库方式全局序列号
    在MySQL中执行dbseq.sql,然后执行脚本:
/*+ mycat:setSequence {
	"name": "db1_tableName",
	"clazz": "io.mycat.plug.sequence.SequenceMySQLGenerator",
	"targetName": "prototype",
	"schemeName": "db1"
}*/
  1. 切换为雪花算法方式的全局序列号
/*+ mycat:setSequence {
	"name": "db1_tableName",
	"time": true
}*/

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

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

相关文章

电脑录屏怎么录ppt?三个ppt录制视频的方法

PPT演示文稿是人们在日常生活和学习中常用的工具&#xff0c;它也被广泛地运用于各个方面。最近有不少朋友问小编ppt录制视频的方法&#xff0c;其实ppt录制视频的方法有很多。如果只需要录制PPT内容&#xff0c;可以用PPT自带的“屏幕录制”来录制视频就可以了&#xff0c;如果…

Day848.Copy-on-Write模式 -Java 性能调优实战

Copy-on-Write模式 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于Copy-on-Write模式的内容。 Java 里 String 这个类在实现 replace() 方法的时候&#xff0c;并没有更改原字符串里面 value[]数组的内容&#xff0c;而是创建了一个新字符串&#xff0c;这种方法在…

C++GUI之wxWidgets(10)-编写应用涉及的类和方法(5)-事件处理(4)

目录自定义事件AddPendingEvent()QueueEvent()PushEventHandler()ProcessEvent()wxCommandEvent与新的事件类型一起使用自定义事件 AddPendingEvent() virtual void wxEvtHandler::AddPendingEvent ( const wxEvent & event ) 发布要稍后处理的事件。 此函数类似于Qu…

逆向-还原代码之eth (Interl 64)

// 源程序 #include <stdio.h> #define HIETH_SYSREG_BASE (0x101e0000) #define REG_RESET 0x01C // 外设控制寄存器(IP软复位控制) #define RESET_SHIFT 12 static void hieth_set_regbit(unsigned long addr, int bit, int shift) { unsigned long …

nginx学习笔记1(小d课堂)

我们进入到官网可以看到有很多个版本的nginx。 我们点击documentation&#xff0c;可以看到官方文档&#xff0c;但是这里的文档暂时还没有中文的&#xff1a; 我们这里后期会在linux上进行安装部署nginx。 而我们的nginx就是我们的反向代理服务器。 我们可以这样来配置。 我们…

栈和队列(内附模拟实现代码)

一&#xff0c;栈1.1 栈的概念栈是一种线性表&#xff08;是一种特殊的线性表&#xff09;&#xff0c;栈只允许在固定一端进行插入和删除元素。插入元素的一端称为栈顶&#xff0c;另一端称为栈底。所以栈中的数据元素满足先进后出&#xff08;First In Last Out&#xff09;的…

【数据篇】31 # 如何对海量数据进行优化性能?

说明 【跟月影学可视化】学习笔记。 渲染动态的地理位置 用随机的小圆点模拟地图的小圆点&#xff0c;实现呼吸灯效果 最简单的做法&#xff1a;先创建圆的几何顶点数据&#xff0c;然后对每个圆设置不同的参数来分别一个一个圆绘制上去。 <!DOCTYPE html> <html …

如何使用python删除一个文件?别说,还挺好用....

嗨害大家好鸭&#xff01;我是小熊猫~ 若想利用python删除windows里的文件&#xff0c;这里需要使用os模块&#xff01;那接下来就看看利用os模块是如何删除文件的&#xff01; 具体实现方法如下&#xff01; 更多学习资料:点击此处跳转文末名片获取 os.remove(path) 删除文…

Java位运算符:Java移位运算符、复合位赋值运算符及位逻辑运算符

Java 定义的位运算&#xff08;bitwise operators&#xff09;直接对整数类型的位进行操作&#xff0c;这些整数类型包括 long&#xff0c;int&#xff0c;short&#xff0c;char 和 byte。位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位&#xff08…

GitLab安装使用(SSH+Docker两种方式)

GitLab安装使用1、在ssh下安装gitlab1.1 安装依赖1.2 配置镜像1.3 开始安装1.4 gitlab常用命令2、在docker下安装gitlab2.1 安装docker2.1.1 更新yum源2.1.2 安装依赖2.1.3 添加镜像2.1.4 查看源中可用版本2.1.5 安装指定版本2.1.6 配置开机启动项2.2 使用容器安装gitlab2.2.1 …

车载以太网 - DoIP头部信息检测逻辑 - 03

通过前面的文章我们已经了解了DoIP所具备的Payload类型,基础的信息都已经具备了,今天我们就要进一步的去了解DoIP的处理逻辑了;按照正常的逻辑来看,处理无论是我们人眼去看书,还是计算机处理一段数据,都是从前到后依次进行处理;而DoIP的信息处理也不例外,也是从头开始进…

2023跨境出海指南:印度网红营销白皮书

前不久&#xff0c;联合国预测印度人口将在4个月后超过中国&#xff0c;成为全球第一人口大国。印度这个国家虽然有些奇葩&#xff0c;但他们的经济实力确实不能小觑&#xff0c;这也是众多国际公司大力发展印度的原因。出海印度容易&#xff0c;但攻克印度市场太难&#xff0c…

Python Tutorial——类

与其它编程语言相比&#xff0c;Python的类机制添加了最小的新语法和语义。它是C和Modula-3中的类机制的混合。Python的类提供了面向对象编程的所有的标准特性&#xff0c;类继承机制允许有多个基类&#xff0c;一个子类可以重写基类中的任何方法&#xff0c;一个方法可以调用基…

编程思想图书推荐,新手入门应该看些啥

编程思想图书推荐&#xff0c;新手入门应该看些啥 导入 元旦的时候&#xff0c;学校社团的指导老师&#xff0c;咨询我有没有什么可以推荐的编程思想的学习书籍&#xff0c;可以值得推荐精读。 说实话&#xff0c;我个人是买过很多书的&#xff0c;但是很少读书&#xff0c;如果…

搭建redis主从复制+哨兵高可用

从服务器连接主服务器&#xff0c;发送SYNC命令&#xff1b;主服务器接收到SYNC命名后&#xff0c;开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令&#xff1b;主服务器BGSAVE执行完后&#xff0c;向所有从服务器发送快照文件&#xff0c;并在发送期间继续…

Window下安装oracle12C

1.Window下安装oracle12C 官网下载地址&#xff1a; Database Software Downloads | Oracle 页面顶部选择 “接受许可协议” 后&#xff0c;我想选择下载 12c 版的企业版&#xff0c;文件1和文件2都需要下载。&#xff08;如果提示登录 Oracle&#xff0c;则需要先登录才能下…

java家装网装修网站装修系统源码

简介 本平台主要是家装网站。管理员发布装修案例&#xff0c;看工地&#xff0c;装修设计师&#xff0c;装修攻略&#xff0c;装修知识文章等&#xff0c;嵌入3d全景图。普通用户注册&#xff0c;填写装修房型报价等。 演示视频&#xff1a; https://www.bilibili.com/video/…

Kotlin基础入门 - 静态变量、常量 And 静态函数、方法

2022一晃而过&#xff0c;2023悄然而至&#xff0c;有天晚上看第一行代码&#xff08;第三版&#xff09;的时候&#xff0c;又看到了Kotlin中静态方法的几种使用方式&#xff0c;蹭着过年还有一些时间&#xff0c;写了个Demo简单测试记录一下 在 Kotlin 中使用静态的方式不止一…

JavaScript基础系列之原型链

1. 前言 今天的重点复习的是JavaScript原型链。所谓是"基础不牢&#xff0c;地动山摇"&#xff0c;原型链作为继承等相关知识的基础&#xff0c;就显得尤为重要了。接下来以手绘原型链为基础&#xff0c;详解讲解下原型链以及相关的属性 2. 原型 以及原型链 2.1 pro…

vs 生成前事件 生成后事件命令

为了提高编译生成后的事件效率&#xff0c;不需要手动的拷贝到固定目录。可以在项目->属性中设备生成后事件。输入相应的命令行&#xff0c;即可。 Visual Studio中&#xff0c;可以在项目-》属性-》生成事件-》生成后事件命令行 xcopy 复制文件&#xff1b; /y/e 如果只复…