Mycat2【java提高】4

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Mycat2【java提高】4

3、读写分离配置扩展

通过对集群配置的修改,可以根据需求实现更多种情况的读写分离配置,总结如下

(1)读写分离(一主一从,无备)(m是主,s是从)

{
  "clusterType":"MASTER_SLAVE",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "m"
  ],
  "maxCon":200,
  "name":"prototype",
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "s"
  ],
  "switchType":"SWITCH"
}

(2)读写分离(一主一从,一备)(m是主,s是从备)

{
  "clusterType":"MASTER_SLAVE",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "m","s"
  ],
  "maxCon":200,
  "name":"prototype",
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "s"
  ],
  "switchType":"SWITCH"
}

(2)读写分离(一主一从,一备)(m是主,s是从,b是备)

{
  "clusterType":"MASTER_SLAVE",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "m","b"
  ],
  "maxCon":200,
  "name":"prototype",
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "s"
  ],
  "switchType":"SWITCH"
}

(4)MHA(一主一从,一备)(m是主,s是从,b是备,READ_ONLY判断主)

{
  "clusterType":"MHA",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "m","b"
  ],
  "maxCon":200,
  "name":"prototype",
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "s"
  ],
  "switchType":"SWITCH"
}

(5)MGA(一主一从,一备)(m是主,s是从,b是备,READ_ONLY判断主)

{
  "clusterType":"MGA",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "m","b"
  ],
  "maxCon":200,
  "name":"prototype",
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "s"
  ],
  "switchType":"SWITCH"
}

(6)GARELA_CLUSTER(一主一从,一备)(m是主,s是从,b多主)

{
  "clusterType":"GARELA_CLUSTER",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "m","b"
  ],
  "maxCon":200,
  "name":"prototype",
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "s"
  ],
  "switchType":"SWITCH"
}

第四章 垂直拆分——分库

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

系统被切分成了,用户,订单交易,支付几个模块。

5.1 如何分库

一个问题:在两台主机上的两个数据库中的表,能否关联查询?

答案:不可以关联查询

分库的原则: 有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到不同的库里。

#客户表 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)
);

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

5.2 如何分表

1、选择要拆分的表

MySQL单表存储数据条数是有瓶颈的,单表达到1000万条数据就达到了瓶颈,会影响查询效率,需要进行水平拆分(分表)进行优化。

例如:例子中的orders、orders…detail都已经达到600万行数据,需要进行分表优化。
2、 分表字段

以 orders 表为例,可以根据不同自字段进行分表

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

5.3 实现分库分表

首先,不需要双主双从了

删掉数据源


Mycat2 一大优势就是可以在终端直接创建数据源、集群、库表,并在创建时指定分库、分表。与1.6版本比大大简化了分库分表的操作

1、添加数据库、存储数据源

/*+mycat:.createDataSource{
"name" :" dw0" , -
"url" :" jdbc:mysql://192.168.253.139:3306",
"user":"root", 
"password":"123456"
}*/ ;
/*+mycat:createDataSource{
"name" :"dr0" , 
"url" :"jdbc:mysql://192.168.253.139:3306",
"user":"root", 
"password" :"123456"
}*/ ;
/*+mycat:.createDataSource{
"name" :" dw1" , -
"url" :" jdbc:mysql://192.168.253.140:3306",
"user":"root", 
"password":"123456"
}*/ ;
/*+mycat:createDataSource{
"name" :"dr1" , 
"url" :"jdbc:mysql://192.168.253.140:3306",
"user":"root", 
"password" :"123456"
}*/ ;

手动创建

{
  "dbType":"mysql",
  "idleTimeout":60000,
  "initSqls":[],
  "initSqlsGetConnection":true,
  "instanceType":"READ_WRITE",
  "maxCon":1000,
  "maxConnectTimeout":3000,
  "maxRetryCount":5,
  "minCon":1,
  "name":"dw0",  #注意
  "password":"123456",
  "type":"JDBC",
  "url":"jdbc:mysql://192.168.253.139:3306?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true",  #注意主机ip 注意不指定库
  "user":"root",
  "weight":0
}


2、添加集群配置

把新添加的数据源配置成集群

#//在mycat终端输入
/*! mycat:createCluster{"name":"c0"," masters": ["dw0"],"replicas":["dr0"]}*/; 
/*!-mycat:createCluster{"name":"c1", "masters": ["dw1"],"replicas":["dr1"]}*/ ;
#可以查看集群配置信息
cd /usr/local/mycat/conf/clusters

手动配置

  "clusterType":"MASTER_SLAVE",
  "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
  },
  "masters":[
    "dw0"
  ],
  "maxCon":200,
  "name":"c0", #注意
  "readBalanceType":"BALANCE_ALL",
  "replicas":[
    "dr0"
  ],
  "switchType":"SWITCH"
}


启动 Mycat并登录

./mycat console

3、创建全局表

#添加数据库db1  主机2也要创建
CREATE DATABASE db1;



vim db1.schema.json

#在建表语句中加上关键字BROADCAST(广播,即为全局表)
CREATE TABLE db1.`travelrecord` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `use_id` varchar(100) DEFAULT NULL,
  `traveldate` date DEFAULT NULL,
  `fee` decimal(10,0) DEFAULT NULL,
  `days` int DEFAULT NULL,
  `blob` longblob, 
  PRIMARY KEY(`id`) , 
  KEY `id` (`id`) 
)ENGINE=InnoDB DEFAULT CHARSET=utf8 BROADCAST;
#进入相关目录查看schema 配置


4、 创建分片表(分库分表)

#在 Mycat终端直接运行建表语句进行数据分片
CREATE TABLE db1.orders(
  id BIGINT NOT NULL AUTO_INCREMENT,
  order_type INT,
  customer_id INT,
  amount DECIMAL(10,2),
  PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8
dbpartition BY mod_hash(customer_id) tbpartition BY mod_hash(customer_id) tbpartitions 1 dbpartitions 2;
#数据库分片规则,表分片规则,以及各分多少片
mysql> use TESTDB;
#在 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);
#同样可以查看生成的配置信息
#进入相关目录查看schema配置
vim db1.schema.json 


查看数据库可见,分片数据

主机1

主机2


在 Mycat终端查询依然可以看到全部数据

Mycat

5、创建ER表

与分片表关联的表如何分表,也就是ER表如何分表,如下

#在 Mycat终端直接运行建表语句进行数据分片
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 ; 
INSERT INTO orders_detail(id,detail,order_id) values(1,'detail1',1);
INSERT INTO orders_detail(id,detail,order_id) VALUES(2,'detail1',2);
INSERT INTO orders_detail(id,detail,order_id) VALUES(3,'detail1',3);
INSERT INTO orders_detail(id,detail,order_id) VALUES(4,'detail1',4);
INSERT INTO orders_detail(id,detail,order_id) VALUES(5,'detail1',5);
INSERT INTO orders_detail(id,detail,order_id) VALUES(6,'detail1',6);

mycat


主机1

不是按照想象的126划得


主机2

#上述两表具有相同的分片算法,但是分片字段不相同
#Mycat2在涉及这两个表的join分片字段等价关系的时候可以完成join的下推
#Mycat2无需指定ER表,是自动识别的,具体看分片算法的接口
#查看配置的表是否具有ER关系,使用/*+·mycat:showErGroup{}*/

#group_id表示相同的组,该组中的表具有相同的存储分布
#运行关联查询语句
Select o.*,od.detail from orders o inner join orders_detail od on o.id=od.order_id;



5.4-常用分片规则

1、分片算法简介

Mycat2支持常用的(自动)HASH型分片算法也兼容1.6的内置的(cobar)分片算法.

HASH型分片算法默认要求集群名字以c为前缀,数字为后缀, c0就是分片表第一个节点, c1就是第二个节点.该命名规则允许用户手动改变

2、Mycat2 与1.x版本区别

Mycat2-Hash型分片算法多数基于MOD_HASH(MOD对应.JAVA的%运算),实际上是取余运算。
Mycat2-Hash型分片算法对于值的处理,总是把分片值转换到列属性的数据类型再运算。

而1.x系列的分片算法统一转换到字符串类型再运算且只能根据一个分片字段计算出存储节点下标。

Mycat2-Hash型分片算法适用于等价条件查询。

而1.x系列由于含有用户经验的路由规则。1.x系列的分片规则总是先转换成字符串再运算。


3、分片规则与适用性

分片算法 描述 分库 分表 数值类型
MOD_HASH 取模哈希 数值,字符串口
UNI_HASH2 取模哈希 数值,字符串
RIGHT_SHIFT 右移哈希 数值
RANGE_HASH 两字段其一取模 数值,字符串
YYYYMM 按年月哈希 DATE,DATETIME
YYYYDD 按年日哈希 DATE,DATETIME
HASH 取模哈希 数值,字符串,如果不是,则转换成字符串
MM 按月哈希 DATE,DATETIME
DD 按日期哈希 DATE,DATETIME
MMDD 按月日哈希 DATE,DATETIME
WEEK 按周哈希 DATE,DATETIME
STR_HASH 字符串哈希 字符串
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10月前
|
Java 关系型数据库 MySQL
Mycat2【java提高】3
Mycat2【java提高】3
90 0
|
10月前
|
SQL 算法 Java
Mycat2【java提高】5
Mycat2【java提高】5
163 0
|
10月前
|
负载均衡 关系型数据库 MySQL
Mycat2【java提高】2
Mycat2【java提高】2
168 0
|
10月前
|
Java 中间件 关系型数据库
Mycat2【java提高】1
Mycat2【java提高】1
116 0
|
3天前
|
Java 程序员
从菜鸟到大神:JAVA多线程通信的wait()、notify()、notifyAll()之旅
【6月更文挑战第21天】Java多线程核心在于wait(), notify(), notifyAll(),它们用于线程间通信与同步,确保数据一致性。wait()让线程释放锁并等待,notify()唤醒一个等待线程,notifyAll()唤醒所有线程。这些方法在解决生产者-消费者问题等场景中扮演关键角色,是程序员从新手到专家进阶的必经之路。通过学习和实践,每个程序员都能在多线程编程的挑战中成长。
|
3天前
|
Java
并发编程的艺术:Java线程与锁机制探索
【6月更文挑战第21天】**并发编程的艺术:Java线程与锁机制探索** 在多核时代,掌握并发编程至关重要。本文探讨Java中线程创建(`Thread`或`Runnable`)、线程同步(`synchronized`关键字与`Lock`接口)及线程池(`ExecutorService`)的使用。同时,警惕并发问题,如死锁和饥饿,遵循最佳实践以确保应用的高效和健壮。
10 2
|
3天前
|
Java
Java Socket编程与多线程:提升客户端-服务器通信的并发性能
【6月更文挑战第21天】Java网络编程中,Socket结合多线程提升并发性能,服务器对每个客户端连接启动新线程处理,如示例所示,实现每个客户端的独立操作。多线程利用多核处理器能力,避免串行等待,提升响应速度。防止死锁需减少共享资源,统一锁定顺序,使用超时和重试策略。使用synchronized、ReentrantLock等维持数据一致性。多线程带来性能提升的同时,也伴随复杂性和挑战。
|
4天前
|
安全 Java
JAVA多线程通信新解:wait()、notify()、notifyAll()的实用技巧
【6月更文挑战第20天】Java多线程中,`wait()`, `notify()`和`notifyAll()`用于线程通信。在生产者-消费者模型示例中,它们确保线程同步。`synchronized`保证安全,`wait()`在循环内防止虚假唤醒,`notifyAll()`避免唤醒单一线程问题。关键技巧包括:循环内调用`wait()`,优先使用`notifyAll()`以保证可靠性,以及确保线程安全和正确处理`InterruptedException`。
|
4天前
|
安全 Java
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
【6月更文挑战第20天】JAVA多线程中,wait(), notify(), notifyAll()是Object类的关键同步机制。wait()让线程等待并释放锁,直到被notify()或notifyAll()唤醒或超时。它们必须在同步块中使用,持有锁的线程调用。notify()唤醒一个等待线程,notifyAll()唤醒所有。最佳实践包括:与synchronized结合,循环检查条件,避免循环内notify(),通常优先使用notifyAll()。
|
2天前
|
安全 Java 程序员
Java多线程详解
Java多线程详解
16 3