java高级 MyCat

目录

        一、什么是Mycat

        二、为什么使用数据库中间件?

        三、中间件的应用场景

                3.1 读写分离

        3.2:数据分片

        四、Mycat的原理

        五、Mycat完成读写分离

        5.1 搭建mysql数据库的主从模式

                5.1.1:mysql主从模式的原理

        5.1.2:搭建主节点--master

        5.1.3:配置从节点

        六、MyCat完成读写分离

        6.1 验证MyCat完成读写分离

        七、Mycat---垂直分库

        7.1 修改mycat配置文件--schema.xml文件

        7.2 分别再DN1节点和DN2节点创建不同的库

        7.3 通过mycat完成表的创建

        八、Mycat---水平分表

        8.3 修改schema.xml文件  

        8.4 修改rule.xml文件

        8.5 我们orders表只在mydb01库中存在,不在mydb02库中,所以我们需要再mydb02也创建orders表

        九、水平拆分后join

        十、全局表

        十一、常用分表的规则

                11.1 取模

                11.2 分片枚举

                11.3、范围约定

                        11.4 按日期(天)分片

        十二、Mycat的高可用


        一、什么是Mycat

       Mycat数据库中间件,所谓中间件,是一类连接软件组件和应用的计算机软件,以便软件各部件之间的通信。

         例如 tomcat,web的中间件。而数据库中间件是连接Java应用程序和数据库中间的软件

java高级 MyCat_第1张图片

        二、为什么使用数据库中间件?

  • Java与数据库的紧密耦合

  • 高访问量高并发对数据库的压力

  • 读写请求数据不一致

        

        我们现在普遍的Java应用程序都是直接连接了MySQL软件进行读写操作,也就是我们在Java中的配置文件等定义了mysql的数据源,直接连接到了我们的mysql软件,但是当某些情况下我们可能需要用到了多个数据库,这个时候我们可能就需要配多个数据源去连接我们的多个数据库,这个时候我们进行sql操作的时候就会很麻烦,因为Java与数据库有了一个紧密的耦合度,但是如果我们在Java应用程序与mysql中间使用了mycat,我们只需要访问mycat就可以了,至于数据源等问题,mycat会直接帮我们搞定。

        再来说一下高访问量高并发,我们都知道mysql数据库实际上在数据查询上是有一个瓶颈的,当我们的数据太多的时候,对于互联网上有高并发的请求的时候,这个时候对我们mysql的压力是非常大的,当访问量一大,就可能会出现查不出数据,响应的时间太长等,这个时候我们可能需要有多个服务器对数据库进行读写分离,以及对数据库进行集群,这个时候我们的sql语句要进行分类,哪个sql语句要访问哪个数据库,这个时候只要交给中间件就可以了。

java高级 MyCat_第2张图片

        三、中间件的应用场景

                3.1 读写分离

java高级 MyCat_第3张图片

        3.2:数据分片

        垂直拆分(分库)、水平拆分(分表)

        首先我们的数据库有多个表

        java高级 MyCat_第4张图片

        当我们的表足够多的时候,也会造成整个数据库的瓶颈,这个时候查询是非常慢的,这个时候我们可能要对这个数据库进行垂直拆分,也就是分库

java高级 MyCat_第5张图片

        我们需要垂直拆分了表4 5 6 放到另外一个库中。

当我们垂直拆分了之后,可能又会出现单个表中的数据达到千万以上,这个时候对表造成了一个瓶颈,这个时候我们对表进行拆分。

 java高级 MyCat_第6张图片

         我们可以把表的一部分数据拆分到另外的一个数据库。       

        中间件---完成: (1)读写分离 (2)垂直分库 (3)水平分表   

        四、Mycat的原理

        Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先对 SQL 语句做了一些特定的分析:如分片分析路由分析读写分离分析、缓存分析等,然后将此 SQL 发 往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

java高级 MyCat_第7张图片

          这种方式把数据库的分布式从代码中解耦出来,程序员察觉不出来后台使用 Mycat 还是 MySQL

        五、Mycat完成读写分离

                java高级 MyCat_第8张图片

        从上面的从我们可以看出,mycat可以对sql进行读写分离的操作。 当执行的sql语句为查询则访问从节点MySQL,如果执行的sql语句为写操作则访问主节点。

        5.1 搭建mysql数据库的主从模式

                5.1.1:mysql主从模式的原理

java高级 MyCat_第9张图片

        从上层来看,复制分成三步:

  • Master 主库在事务提交时,会把数据变更作为事件Events 记录在二进制日志文件 Binlog 中。

  • 主库推送二进制日志文件 Binlog 中的日志事件到从库的中继日志 Relay Log 。

  • slave重做中继日志中的事件,将改变反映它自己的数据。  

                准备的条件

        1. 安装数据库----如果没安装就查看这个网址---https://www.cnblogs.com/tony-hyn/p/15777762.html
        2. 启动mysql -----systemctl start mysqld
        3. 查看mysql是否设置了远程连接.  window中的navicat连接mysql. 

java高级 MyCat_第10张图片

                克隆一份虚拟机 

java高级 MyCat_第11张图片

        

         修改mysql的UUID保证不一样

java高级 MyCat_第12张图片

         

         找到 find -name auto.cnf 并删除该问题

         重启mysql服务器

        

        5.1.2:搭建主节点--master

        158作为主节点

                在master 的配置文件(/etc/my.cnf)中,配置如下内容:

#mysql 服务ID,保证整个集群环境中唯一
server-id=1

#mysql binlog 日志的存储路径和文件名
log-bin=/var/lib/mysql/mysqlbin

#错误日志,默认已经开启
#log-err

#mysql的安装目录
#basedir

#mysql的临时目录
#tmpdir

#mysql的数据存放目录
#datadir

#是否只读,1 代表只读, 0 代表读写
read-only=0

#忽略的数据, 指不需要同步的数据库
binlog-ignore-db=mysql

#指定同步的数据库
#binlog-do-db=db01

         执行完毕之后,需要重启Mysql:                 systemctl restart mysqld

         查看master状态                         show master status;

java高级 MyCat_第13张图片

         字段含义:

                File : 从哪个日志文件开始推送日志文件
                Position : 从哪个位置开始推送日志
                Binlog_Ignore_DB : 指定不需要同步的数据库

        5.1.3:配置从节点

                在 slave 端/etc/my.cnf配置文件中,配置如下内容:

#mysql服务端ID,唯一
server-id=2

#指定binlog日志
log-bin=/var/lib/mysql/mysqlbin

                执行完毕之后,需要重启Mysql:                 systemctl restart mysqld

                执行如下指令 :---指定主从关系         

change master to master_host= '192.168.223.158', master_user='root', master_password='123456',master_log_file='mysqlbin.000001',master_log_pos=154;

java高级 MyCat_第14张图片

         指定当前从库对应的主库的IP地址,用户名,密码,从哪个日志文件开始的那个位置开始同步推送日志。

        开启同步操作

        start slave;

        show slave status\G;

java高级 MyCat_第15张图片

        上面截图的必须是yes才可以。  

                

        停止同步操作:

        stop slave;
        reset master;

        六、MyCat完成读写分离

        java高级 MyCat_第16张图片

                准备一台mycat服务器。192.168.223.160.

         目录结构

java高级 MyCat_第17张图片

        修改配置文件

  1. schema.xml: 定义我们的逻辑库和节点信息

  2. rule.xml: 定义分表的规则

  3. server.xml 定义mycat账户和密码

        1.修改schema.xml  




    
	
		
	
	
	
	
	
			  
		select user()
		
		
		
				   
		
		
	
	

        2.修改server.xml

        定义逻辑账户和密码






	
	
		
		******
		
		TESTDB
	

        3. 启动MyCat

java高级 MyCat_第18张图片

        6.1 验证MyCat完成读写分离

        springboot+整合mybatis-plus

        原因是mycat使用的mysql驱动版本为5.1的 而springboot的mysql驱动8.0的。 必须保证他们的版本号一致  

        

java高级 MyCat_第19张图片

         从上面的结果无法看出读取的是主节点还是从节点的数据。为了让你能看出从slave节点读取的数据,我们故意让从节点的数据与主节点不一致。

java高级 MyCat_第20张图片

        七、Mycat---垂直分库

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

java高级 MyCat_第21张图片

java高级 MyCat_第22张图片

        分库的原则:

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

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

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

        客户表----独立放入一个库中.

订单表 订单详情表 订单状态表----独立放入一个库中

        为了减少服务器的启动数量.---我们就把原来的主从关系先取消  

java高级 MyCat_第23张图片

                 stop slave; 关闭主从关系

        7.1 修改mycat配置文件--schema.xml文件




    
	
		 
		 
select user() select user()

        7.2 分别再DN1节点和DN2节点创建不同的库

                dn1=====>mydb01
                dn2=====>mydb02

java高级 MyCat_第24张图片

        7.3 通过mycat完成表的创建

                mysql -uaaa -P 8066 -h 192.168.223.160 -p123456

        -u: mycat逻辑账户

        -P: mycat的端口号

        -h: mycat服务端的ip

        -p: mycat的逻辑密码

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

        八、Mycat---水平分表

    1、简介

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

     2、水平分表按照什么列来分?                        例如: 订单表

                        订单表 rows:1000万

CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id) 
); 

        按照一列进行拆分。

        按照id---- 查询订单时---查询最近的订单数据。---之前的订单很少有人访问

        按照订单的日期---双11 双12 ---这种日期的数据存入一张表---该表的记录会非常多。

        客户id---->比较均匀的分到相应的表中,而且访问也比较均匀。

        8.3 修改schema.xml文件  




    
	
		 
		 
select user() select user()

        8.4 修改rule.xml文件

                该文件是用来定义分表的规则

java高级 MyCat_第25张图片

        8.5 我们orders表只在mydb01库中存在,不在mydb02库中,所以我们需要再mydb02也创建orders表

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

java高级 MyCat_第26张图片

        通过mycat往orders表添加数据。

        分表插入数据时,必须提高列的列表。因为你如果不提供人家无法知道对应那一列的值  

        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);

         最终效果:java高级 MyCat_第27张图片

 java高级 MyCat_第28张图片

        九、水平拆分后join

        join:联表查询。

        思考: 如果订单详情表和订单表进行联表查询,由于订单表中的记录被拆分到两个库中了,而我们的订单详情表在一个库中存在,那么如果真的要联表查询的化,订单详情只会关联当前库中的订单表。

        原则:

        使用ER表解决上面的字表关联查询的问题,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了JION 的效率和性能问 题,根据这一思路,提出了基于E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上。

        修改schema.xml 




    
	
		 
		 
select user() select user()

        在159服务器创建订单详情表 

CREATE TABLE orders_detail(
 id INT AUTO_INCREMENT,
 detail VARCHAR(2000),
 order_id INT,
 PRIMARY KEY(id)
);

        通过mycat添加订单详情表的记录  

INSERT INTO orders_detail(id,detail,order_id) values(7,'detail1',1);
INSERT INTO orders_detail(id,detail,order_id) VALUES(8,'detail1',2);
INSERT INTO orders_detail(id,detail,order_id) VALUES(9,'detail1',3);
INSERT INTO orders_detail(id,detail,order_id) VALUES(10,'detail1',4);
INSERT INTO orders_detail(id,detail,order_id) VALUES(11,'detail1',5);
INSERT INTO orders_detail(id,detail,order_id) VALUES(12,'detail1',6);

java高级 MyCat_第29张图片

        java代码测试 ------联表查询

 @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Test
    public void test08(){
        List allWithOrders = orderDetailMapper.findAllWithOrders();
        allWithOrders.stream().forEach(System.out::println);
    }

        dao层





  
      
      
      
      
          
           
           
           
      
  

  
      od.id odid,detail,order_id,o.id oid,order_type,customer_id,amount
  
  

        十、全局表

        dict---->状态 比如支付状态 性别 0 1

        订单数据字典表.---存放订单得状态---->支付 未支付 取消 待发货 已发货 已确认。。。。

        由于订单数据字典表 再每个节点上都需要。所以我们把数据字典表定义为全局表。

        什么样得表适合做全局表.

  • 变动不频繁

  • 数据量总体变化不大

  • 数据规模不大,很少有超过数十万条记录.

        鉴于此,Mycat 定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:

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

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

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

        修改schema.xml  




    
	
		 
		 
select user() select user()

        通过mycat创建全局表  

CREATE TABLE dict_order_type(
 id INT AUTO_INCREMENT,
 order_type VARCHAR(200),
 PRIMARY KEY(id)
);

        添加数据

INSERT INTO DICT_ORDER_TYPE(id,order_type) VALUES(101,'Pay');
INSERT INTO DICT_ORDER_TYPE(id,order_type) VALUES(102,'NotPay');

        观察到每个节点都存在该表,而且该表的数据内容是一样

        十一、常用分表的规则

                11.1 取模

                此规则为对分片字段求摸运算。也是水平分表最常用规则

                11.2 分片枚举

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

                实现方式如下:1.修改schema.xml配置文件

java高级 MyCat_第30张图片

        测试表为orders_ware_info,配置在dn1和dn2节点,规则是新增一个sharding_by_intfile

                                        2.修改rule.xml配置文件

java高级 MyCat_第31张图片java高级 MyCat_第32张图片

                                        3.修改partition-hash-int.txt配置文件

                

        表示areacode为110就存到第一个数据节点,为120就存到第二个数据节点  

                                        4.重启Mycat使配置生效

java高级 MyCat_第33张图片

                使用mycat创建订单归属区域信息表:

CREATE TABLE orders_ware_info
(
`id` INT AUTO_INCREMENT comment '编号',
`order_id` INT comment '订单编号',
`address` VARCHAR(200) comment '地址',
`areacode` VARCHAR(20) comment '区域编号',
PRIMARY KEY(id)
);

                插入数据:

INSERT INTO ORDERS_WARE_INFO(id, order_id,address,areacode) VALUES (1,1,'北京','110');
INSERT INTO ORDERS_WARE_INFO(id, order_id,address,areacode) VALUES (2,2,'天津','120');

java高级 MyCat_第34张图片

                通过数据库直接查询:

                spdb_pzex:

java高级 MyCat_第35张图片      

                spdb_portal_wechat:  

java高级 MyCat_第36张图片

                11.3、范围约定

                此分片适用于,提前规划好分片字段某个范围属于哪个分片。

        

                        1.修改schema.xml配置文件

java高级 MyCat_第37张图片

        上面定义以及所存储的数据节点分片规则

                    2.修改rule.xml配置文件    

java高级 MyCat_第38张图片java高级 MyCat_第39张图片

                3. 修改autopartition-long.txt配置文件

                java高级 MyCat_第40张图片

                4.重启Mycat使配置生效

java高级 MyCat_第41张图片

                在mycat中创建支付信息表payment_info:

CREATE TABLE payment_info( `id` INT AUTO_INCREMENT comment '编号', `order_id` INT comment '订单编号', `payment_status` INT comment '支付状态', PRIMARY KEY(id));

                插入数据:  

INSERT INTO PAYMENT_INFO (id,order_id,payment_status) VALUES (1,101,0);INSERT INTO PAYMENT_INFO (id,order_id,payment_status) VALUES (2,102,1);INSERT INTO PAYMENT_INFO (id,order_id ,payment_status) VALUES (3,103,0);INSERT INTO PAYMENT_INFO (id,order_id,payment_status) VALUES (4,104,1);

java高级 MyCat_第42张图片

                分别查看两个host数据节点的数据:         

                        spdb_pzex:

java高级 MyCat_第43张图片

                        spdb_portal_wechat:

java高级 MyCat_第44张图片

                        11.4 按日期(天)分片

                        此规则为按天分片。设定时间格式、范围 ---日志

                1.修改schema.xml配置文件

                java高级 MyCat_第45张图片

                2.修改rule.xml配置文件

                java高级 MyCat_第46张图片

         需要自定义一个分片函数shardingByDate:

java高级 MyCat_第47张图片

            3.重启Mycat使配置生效    

java高级 MyCat_第48张图片

                在mycat中创建用户信息表login_info:

CREATE TABLE login_info( `id` INT AUTO_INCREMENT comment '编号', `user_id` INT comment '用户编号', `login_date` date comment '登录日期', PRIMARY KEY(id));

                 插入数据:

INSERT INTO LOGIN_INFO(id,user_id,login_date) VALUES (1,101,'2019-01-01');
INSERT INTO LOGIN_INFO(id,user_id,login_date) VALUES (2,102,'2019-01-02');
INSERT INTO LOGIN_INFO(id,user_id,login_date) VALUES (3,103,'2019-01-03');
INSERT INTO LOGIN_INFO(id,user_id,login_date) VALUES (4,104,'2019-01-04');
INSERT INTO LOGIN_INFO(id,user_id,login_date) VALUES (5,103,'2019-01-05');
INSERT INTO LOGIN_INFO(id,user_id,login_date) VALUES (6,104,'2019-01-06');

        java高级 MyCat_第49张图片 

                分别查看两个host数据节点的数据:

                        spdb_pzex:

java高级 MyCat_第50张图片

                        spdb_portal_wechat:

java高级 MyCat_第51张图片

        十二、Mycat的高可用

  java高级 MyCat_第52张图片

        详情可查看:基于 HA 机制的 Mycat 高可用_爱上口袋的天空的博客-CSDN博客

         总结: mycat -- 读写分离 垂直分库 水平分表[ 联表操作【ER原理】 水平拆分的规则]。

你可能感兴趣的:(java高级,java,开发语言)