Mycat2【java提高】5

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Mycat2【java提高】5

4、常用分片规则简介

(1)MOD_HASH

[数据分片]HASH型分片算法-MOD_HASH

如果分片值是字符串则先对字符串进行hash转换为数值类型
分库键和分表键是同键

分表下标=分片值%(分库数量*分表数量)

分库下标=分表下标/分表数量
分库键和分表键是不同键:

分表下标=分片值%分表数量

分库下标=分片值%分库数量
(2) RIGHT_SHIFT

[数据分片]HASH型分片算法-RIGHT_SHIFT

RIGHT_SHIFT(字段名,位移数)

仅支持数值类型

分片值右移二进制位数,然后按分片数量取余
( 3) YYYYMd

[数据分片]HASH型分片算法-YYYYMM

仅用于分库

(YYYY*12+MM)%分库数.MM是1-12
( 4)MMDD

仅用于分表

仅DATE/DATETIME

一年之中第几天%分表数

tbpartitions不超过366

5.5 全局序列

Mycat2在1.x版本上简化全局序列,自动默认使用雪花算法生成全局序列号,如不需要Mycat.默认的全局序列,可以通过配置关闭自动全局序列

1、建表语句方式关闭全局序列

如果不需要使用mycat的自增序列,而使用mysql本身的自增主键的功能,需要在配置中更改对应的建表sql,不设置AUTO_INCREMENT关键字,这样, mycat就不认为这个表有自增主键的功能,就不会使用mycat的全局序列号.这样,对应的插入sql.在mysql.处理,由mysql的自增主键功能补全自增值.


雪花算法:引入了时间戳和ID保持自增的分布式ID生成算法


建表sql可以自动在原型库对应的逻辑表的物理表获取,如果逻辑表的建表SQL 与物理表的建表SQL不对应,则需要在配置文件中配置建表SQL.

例如:

#带AUTO_INCREMENT 关键字使用默认全局序列
CREATE TABLE db1.travelrecord (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_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 ;
#带AUTO_INCREMENT 关键字使用默认全局序列
CREATE TABLE db1.travelrecord (
  `id` bigint NOT NULL,
  `user_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 ;

2、设置Mycat数据库方式获取全局序列

#1、在prototype服务器的db1库导入dbseq.sql文件

Mycat2已经为用户提供了相关sql脚本,需要在对应数据库下运行脚本,不能通过Mycat客户端执行。

脚本所在目录mycat/confe

脚本内容

DROP TABLE IF EXISTS MYCAT_SEQUENCE;
CREATE TABLE MYCAT_SEQUENCE (  name VARCHAR(64) NOT NULL,  current_value BIGINT(20) NOT NULL,  increment INT NOT NULL DEFAULT 1, PRIMARY KEY (name) ) ENGINE=InnoDB;
-- ----------------------------
-- Function structure for `mycat_seq_currval`
-- ----------------------------
DROP FUNCTION IF EXISTS `mycat_seq_currval`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(64)) RETURNS varchar(64) CHARSET latin1
    DETERMINISTIC
BEGIN
    DECLARE retval VARCHAR(64);
    SET retval="-1,0";
    SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval FROM MYCAT_SEQUENCE  WHERE name = seq_name;
    RETURN retval ;
END
;;
DELIMITER ;
-- ----------------------------
-- Function structure for `mycat_seq_nextval`
-- ----------------------------
DROP FUNCTION IF EXISTS `mycat_seq_nextval`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(64)) RETURNS varchar(64) CHARSET latin1
    DETERMINISTIC
BEGIN
    DECLARE retval VARCHAR(64);
    DECLARE val BIGINT;
    DECLARE inc INT;
    DECLARE seq_lock INT;
    set val = -1;
    set inc = 0;
    SET seq_lock = -1;
    SELECT GET_LOCK(seq_name, 15) into seq_lock;
    if seq_lock = 1 then
      SELECT current_value + increment, increment INTO val, inc FROM MYCAT_SEQUENCE WHERE name = seq_name for update;
      if val != -1 then
          UPDATE MYCAT_SEQUENCE SET current_value = val WHERE name = seq_name;
      end if;
      SELECT RELEASE_LOCK(seq_name) into seq_lock;
    end if;
    SELECT concat(CAST((val - inc + 1) as CHAR),",",CAST(inc as CHAR)) INTO retval;
    RETURN retval;
END
;;
DELIMITER ;
-- ----------------------------
-- Function structure for `mycat_seq_setvals`
-- ----------------------------
DROP FUNCTION IF EXISTS `mycat_seq_nextvals`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_nextvals`(seq_name VARCHAR(64), count INT) RETURNS VARCHAR(64) CHARSET latin1
    DETERMINISTIC
BEGIN
    DECLARE retval VARCHAR(64);
    DECLARE val BIGINT;
    DECLARE seq_lock INT;
    SET val = -1;
    SET seq_lock = -1;
    SELECT GET_LOCK(seq_name, 15) into seq_lock;
    if seq_lock = 1 then
        SELECT current_value + count INTO val FROM MYCAT_SEQUENCE WHERE name = seq_name for update;
        IF val != -1 THEN
            UPDATE MYCAT_SEQUENCE SET current_value = val WHERE name = seq_name;
        END IF;
        SELECT RELEASE_LOCK(seq_name) into seq_lock;
    end if;
    SELECT CONCAT(CAST((val - count + 1) as CHAR), ",", CAST(val as CHAR)) INTO retval;
    RETURN retval;
END
;;
DELIMITER ;
-- ----------------------------
-- Function structure for `mycat_seq_setval`
-- ----------------------------
DROP FUNCTION IF EXISTS `mycat_seq_setval`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(64), value BIGINT) RETURNS varchar(64) CHARSET latin1
    DETERMINISTIC
BEGIN
    DECLARE retval VARCHAR(64);
    DECLARE inc INT;
    SET inc = 0;
    SELECT increment INTO inc FROM MYCAT_SEQUENCE WHERE name = seq_name;
    UPDATE MYCAT_SEQUENCE SET current_value = value WHERE name = seq_name;
    SELECT concat(CAST(value as CHAR),",",CAST(inc as CHAR)) INTO retval;
    RETURN retval;
END
;;
DELIMITER ;
INSERT INTO MYCAT_SEQUENCE VALUES ('GLOBAL', 1, 1);

#2、添加全局序列配置文件

进入/mxcat/conf/sequences目录,添加配置文件

{数据库名字}_{表名字}.sequence.jison

配置内容:

{
  "clazz": "io.mycat.plug.sequence.SequenceMySQLGenerator" ,
  "name": "db1_travelrecord" , 
  "targetName": "prototype" , 
  "schemaName": "db1"//指定物理库名
}

可选参数targetName·更改序列号服务器

“targetName”: "prototype”是执行自增序列的节点,也是dbsea.sal导入的节点

dbseq.sql导入的当前库的库名与逻辑表的逻辑库名一致

导入后检查库下有没有mvcat sequence表。


其中increment是序列号自增的步伐,为1的时候严格按1递增,当1000的时候,mycat会每次批量递增1000取序列号.此时在多个myeat访问此序列号表的情况下,不能严格自增

NAME列中的值是对应的 库名_表名 该值需要用户设置,即插入一条逻辑表相关的记录,用于记录序列号


#3、切换为数据库方式全局序列号

使用注释前要导入dbsega.sal以及设置mycat…sequence表内的逻辑表记录通过注释设置为数据库方式全局序列号

/*+·mycat:setSequence {
"name" :"db1_travelrecord" , 
"clazz" :"io.mycat.plug.sequence.SequenceMySQLGenerator" ,
"name" :"db1_travelrecord" , 
  "targetName" : "prototype" , 
  "schemaName" : " db2"
}*/;

#4、切换为雪花算法方式全局序列号4

/*+mycat:setSequence{"name" :"dbl_travelrecord","time":true}·*/ ;

第六章 Mycat 安全设置

6.1 权限配置

1、 user 标签权限控制


目前 Mycat 对于中间件的连接控制并没有做太复杂的控制,目前只做了中间件逻辑库级别的读写权限控制。是通过mycat/conf/users目录下的{用户名}.user.json进行配置。

#root.user.json
{
        "dialect":"mysql",
        "ip":null,
        "password":"123456",
        "transactionType":"xa",
        "username":"root"
}

配置说明

标签属性 说明
name 应用连接中间件逻辑库的用户名
password 该用户对应的密码
ip 建议为空,填写后会对客户端的ip进行限制
dialectc 使用语言,默认mvsal
transactionType 事务类型,默认proxy
proxy:本地事务,在涉及大于1个数据库的事务, commit阶段失败会导致不一致,但是兼容性最好

2、·权限说明

Mycat2权限分为两块:登录权限、sql权限

(1)登录权限:

Mycat2在 MySQL 网终协议的时候检查客户端的IP,用户名,密码其中IP使用正则表达式匹配,一旦匹配成功,就放行

( 2) sql权限

使用自定义拦截器实现

第七章·Mycat 相关工具

7.1-Mycat2-UI

Mycat2·UI是官方推出的 Mycat2监控工具。

1、下载

http://dl.mycat.org.cn/2.0/ui/

2、运行环境

在安装JDK8的环境,双击 jar包就可以打

assistant-1.22-release-jar-with-dependencies-2022-5-19.jar

3、使用

#双击
java -jar .\assistant-1.22-release-jar-with-dependencies-2022-5-19.jar

(1)连接

连接Mycat2(需要Mycat2服务器正常启动)

点击文件->点击新连接



(2)编辑分片表


导入文件是csv格式,无表头

(6项)

prototype,s0,t0,0,0,0

prototype,s0,t1,0,1,1


(3项)

prototype, s0,t0

prototype, s0, t1


暂时不支持自动 HASH 型算法的分区导入


物理分库下标,物理分表下标是根据分片算法要求填入,没有明确要求不需要填写

对于1.6的分片算法,物理分库下标,物理分表下标是没有意义的,只有总物理分表下标有意义(总分表的下标)


(3)编辑索引表


(4)编辑全局表



最后


Markdown 37371 字数 2290 行数

HTML 30680 字数 1484 段落


2022/8/26 18:50


暑假学习结束

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
Java 关系型数据库 MySQL
Mycat2【java提高】3
Mycat2【java提高】3
110 0
|
存储 算法 Java
Mycat2【java提高】4
Mycat2【java提高】4
174 0
|
负载均衡 关系型数据库 MySQL
Mycat2【java提高】2
Mycat2【java提高】2
201 0
|
Java 中间件 关系型数据库
Mycat2【java提高】1
Mycat2【java提高】1
165 0
|
9天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
18天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
6天前
|
安全 Java 开发者
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
25 9
|
9天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
5天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
9天前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
22 3