目录

  • MyCat简介
  • 术语简介
  • MyCat配置读写分离
  • MyCat搭建

一、MyCat简介

1.Java编写的数据库中间件,所以MyCat运行环境需要JDK

2.MyCat是中间件,运行在代码应用和Mysql数据库之间的应用

3.前身是corba,是阿里开发的数据库中间件,实现Mysql数据库分表分库集群管理的中间件,曾经出现过重大事故,二次开发,形成MyCat;

4.使用MyCat之后,编写的所有SQL语句,必须严格遵守SQL标准规范;例如insert语句



insert



5.使用MyCat中间件后的结构图:




java实现对mysql的分库分表 java mycat分库分表_数据库


二、MyCat术语简介

1.切分

逻辑上的切分,在物理层面,是使用多库[database],多表[table]实现的切分。

  • 纵向切分

把一个数据库切分成多个数据库,配置方便;

但是只能实现两张表的表连接查询;

将一张表中的数据,分散到若干个database的痛结构表中,多个表的数据的集合是当前表格的数据;

举个栗子:假设我现在有一个数据库test,数据库test里有一张表叫做t,纵向切分的意思就是把test切分成若干块,假设切为test1,test2,两个库中各有一张表都叫做t,两个t的结构完全相同,那我在做数据库的增删改查的时候,把数据分散在两张表中进行存储,那么这两个库中两张表数据的总和等于不分库时t表的数据量;


java实现对mysql的分库分表 java mycat分库分表_mycat是什么_02


  • 横向切分

把一个表切分成多个表,相比纵向切分配置更麻烦;

无法实现表连接查询;

将一张表的字段,分散到若干张表中,将若干表连接到一起,才是当前表的完整数据;

举个栗子:还是test数据库中有一张t表,假设t表中的字段是20个,除了主键之外还有19个字段,在进行横向切分的时候,把t这张表切分为若干张表,假设为t1,t2,t3,这3个表各有若干个字段,假设每个表各有7,8,7个字段,因为会在三张表里分别做一个主键字段,这样的话会把三张表当成一张表来看待,主键相同的合并在一起;

横向切分在查询的时候效率没有太直接的提升,但是我们把字段降低了,可以针对性的去查一些数据


java实现对mysql的分库分表 java mycat分库分表_数据_03


2. 逻辑库

MyCat中定义的database是逻辑上存在的,但是物理上未必存在;

主要是针对纵向切分提供的概念;

访问MyCat,就是将MyCat当做MySQL使用;

db数据库是MyCat中定义的database,通过SQL访问MyCat中的db库时,对应的是MySql中的db1,db2,db3三个库,物理上的database是db1,db2,db3,逻辑上的database,就是db


java实现对mysql的分库分表 java mycat分库分表_SQL_04


3. 逻辑表

MyCat中定义的table,是逻辑上存在,物理上未必存在;

主要是针对横向切分提供的概念;

MyCat中的表格table,其字段分散到MySQL数据库的表格table1,table2,table3中;


java实现对mysql的分库分表 java mycat分库分表_数据_05


4. 默认端口

MyCat默认端口是8066

5. 数据主机-dataHost

物理MySQL存放的主机地址,可以使用主机名,IP域名定义。

MyCat会管理很多MySQL,MySQL就是数据主机;

6. 数据节点-dataNode

物理的database是什么,数据保存的物理节点就是database,就是相当于MySQL中的DB

7. 分片规则

当控制数据的时候,如何访问物理database和table;意思就是当一条SQL语句来了的时候,MyCat怎么去找到对应的database和table;

就是访问dataHost和dataNode的算法;

在MyCat处理具体的数据CRUD的时候,如何快速访问dataHost和dataNode的算法,如:哈希算法,crc16算法等

三、MyCat配置读写分离

  1. MySQL主从备份
  • 主从备份概念

什么是主从备份:就是一种主备模式的数据库应用;

主库(master)和从库(slave)数据完全一致;

实现数据的多重备份,保证数据的安全;

可以在master[innodb]和slave[MyISAM]中使用不同的数据库引擎,实现读写的分离

  • MySQL5.5版本后本身支持主从备份
  • 主从备份的目的

实现主备模式:保证数据的安全,尽量避免数据丢失的可能

实现读写分离:使用不同的数据库引擎,实现读写分离,提高所有的操作效率;InnoDB使用DML预发操作,MyISAM使用DQL语法操作。

  • 主从备份效果

主库操作同步到备库:

所有对Master的操作,都会同步到salve中;

如果Master和Salve天生上环境不同,那么对Master的操作,可能会在Salve中出现错误;例如:在创建主从模式之前,Master有database:db1,db2,db3。salve有database:db1,db2,创建主从模式,现在的情况Master和Salve天生不同。主从模式创建成功后,在Master中drop database db3,Salve中抛出数据库SQL异常,后续所有命令不能同步,一旦出现错误,只能重新实现主从模式。

  • 主从备份配置

主要操作Master和Salve中的配置文件和DBMS的配置;

配置文件:定义主从模式的基础信息,如:日志,命令等;

DBMS配置:提供主从访问的用户,基础信息[Master和Salve的位置,用户名,密码,日志文件名等等]

建议:建立主从备份的多个MySQL,最好原始环境一致,database,table,data完全一致。

①修改Master配置文件

/etc/my.cnf

需要修改,在修改前建议复制一份备份文件,修改为下面的my.cnf

my.cnf中的一些配置解释:

server-id:本环境中server-id是1;这个是MySQL服务的唯一标识;是数字,自然数;配置的时候有要求;在单机使用的时候server-id任意配置,只要是数字即可;当在主从使用时server-id Master唯一标识数字必须小于Salve唯一标识数字。

log_bin:本环境log_bin值:master_log;表示日志文件命名,开启日志功能。此日志是命令日志,就是记录主库中执行的所有的SQL命令的。MySQL的log_bin不是执行日志,状态日志,是操作日志,就是在DBMS中所有的SQL命令;log_bin日志不是必要的,主要配置主从备份时才必要;变量的值就是日志文件名称,是日志文件名称的主体,MySQL数据库自动增加文件后缀和文件类型

②重启MySQL

service mysqld restart

③配置Master

访问MySQL:

mysql -uusername -ppassword(mysql -uroot -proot)

创建用户:

在MySQL数据库中,为不存在的用户授权,就是同步创建用户并授权;

此用户是从库访问主库使用的用户;

举个栗子说一下这个用户是干什么的,主库Master在每次操作SQL命令的时候都会记录在一个文件,就是log_bin,从库会通过远程访问的方式去访问主库,需要一个用户名和密码去进行访问,在登录之后会创建一个IO通道去读这个log_bin中的SQL命令,把读取的SQL命令在从库中再执行一遍

IP地址不能写为%,因为主从备份中,当前创建的用户,是给从库访问主库使用的,用户必须有指定的访问地址,而不是通用地址

grant all privileges on *.* to ‘username’@’ip’ identified by ‘password’ with grant option; flush privileges;

grant all privileges on *.* to 'slave'@'192.168.199.133' identified by 'slave' with grant option; //给salve开启所有权限
flush privileges; //让设置的权限生效

查看用户:
use mysql;

select host,name from user;

查看Master信息:

show master status;


java实现对mysql的分库分表 java mycat分库分表_数据_06


④从库配置

修改从库配置文件:

/etc/my.cnf

server-id:唯一标识,本环境中配置为2

log_bin:可以使用默认配置,也可以注释掉

修改uuid(可选): 主从模式要求多个 MySQL 物理名称不能相同. 即按装 MySQL 过程中 Linux 自动生成的物理标志. 唯一物理标志命名为 uuid. 保存位置是 MySQL 数据库的数据存放位置. 默认为 /var/lib/mysql 目录中. 文件名是 auto.cnf. 一般会不同,因为我在虚拟机中是直接复制了一份MySQL,所以两个uuid是相同的。
修改 auto.cnf 文件中的 uuid 数据. 随意修改,不建议改变数据长度.建议改变数据内容. /var/lib/mysql/auto.cnf

重启MySQL服务:

service mysqld restart;

配置Salve:

访问MySQL

mysql -uusername -ppassword;

停止Salve功能

stop salve;

配置主库信息

需要修改的数据是依据 Master 信息修改的. ip 是 Master 所在物理机 IP. 用户名和密码是 Master 提供的 Slave 访问用户名和密码. 日志文件是在 Master 中查看的主库信息提供的.在 Master 中使用命令 show master status 查看日志文件名称.
change master to master_host=’ip’, master_user=’username’,master_password=’password’, master_log_file=’log_file_name’;

change master to master_host='192.168.199.212', master_user='slave', master_password='slave', master_log_file='master_log.000001';
启动Salve功能

start slave;

查看salve配置

show salve status /G;


Slave_IO_State: Waiting for master to send event 
 Master_Host: 192.168.120.139 Master_User: slave Master_Port: 3306 
 Connect_Retry: 60 Master_Log_File: master-log.000001 
 Read_Master_Log_Pos: 427
 Relay_Log_File: mysqld-relay-bin.000002 
 Relay_Log_Pos: 591 Relay_Master_Log_File: master-log.000001 
 Slave_IO_Running: Yes Slave_SQL_Running: Yes 
 Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: 
 Replicate_Ignore_Table: Replicate_Wild_Do_Table: 
 Replicate_Wild_Ignore_Table: Last_Errno: 0 
 Last_Error: Skip_Counter: 0 
 Exec_Master_Log_Pos: 427 Relay_Log_Space: 765 Until_Condition: None 
 Until_Log_File: Until_Log_Pos: 0 
 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: 
 Master_SSL_Cert: Master_SSL_Cipher: 
 Master_SSL_Key: Seconds_Behind_Master: 0 
 Master_SSL_Verify_Server_Cert: No
 Last_IO_Errno: 0 最后一次错误的 IO 请求编号 
 Last_IO_Error:
 Last_SQL_Errno: 0 最后一次错误的执行 SQL 命令编号. Last_SQL_Error: 
 Replicate_Ignore_Server_Ids: Master_Server_Id: 1 
 Master_UUID: 9ee988ac-8751-11e7-8a95-000c2953ac06 Master_Info_File: /var/lib/mysql/master.info 
 SQL_Delay: 0 
 SQL_Remaining_Delay: NULL
 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O 
 thread to update it
 Master_Retry_Count: 86400 
 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 
 Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 
 Executed_Gtid_Set: Auto_Position: 0 
 1 row in set (0.00 sec)


⑤测试主从

主从之间的延迟:主从之间一定会有一个延迟,尤其是在主库进行了批量的增删改,而从库要跟着同时做批量的增删改,这样就会造成一个延迟,但这不会造成很大的问题,因为数据库是一个非常稳定的应用,他的延迟是在数据操作和索引维护上的一个延迟,他一定会保证数据的一致性,因为从库获取的是主库的命令,而不是直接获取主库的数据,如果有延迟无非是命令的堆积,还没有运行。

可以在从库中做查询操作,其他的操作不能做,因为他是通过获取主库的命令来进行操作的。他仅仅是一个备份。我们执行的错误的SQL命令是不会进入log_bin中的。

四、MyCat搭建

  1. 安装JDK
  2. 主从备份搭建完成
  3. 安装MyCat

解压缩: tar -zxf mycat-xxxx.tar.gz

4. Master提供可被MyCat访问的用户

在 Mycat 中通过 Master 数据库的 root 用户访问 Master 数据库.
grant all privileges on *.* to ‘username’@’ip’ identified by ‘password’ with grant option; grant all privileges on *.* to 'mycat'@'%' identified by 'mycat' with grant option;
5. 上传MyCat

Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

6. 解压缩

tar -zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

7. MyCat配置文件介绍

MyCat所有的配置文件都在应用的conf目录中

  • rule.xml

用于定义分片规则的配置文件;

主要是查看,很少修改;

mycat 默认的分片规则: 以 500 万为单位,实现分片规则。例如:逻辑库A对应dataNode - db1和db2;1-500万保存在db1中, 500万零1到1000万保存在 db2 中,1000 万零 1 到 1500 万保存在 db1 中.依次类推.。


<tableRule


crc32slot规则: 在CRUD操作时,根据具体数据的crc32算法计算,数据应该保存在哪一个 dataNode 中. 算法类似模运算.


<tableRule


  • schema.xml

用于定义逻辑库和逻辑表的配置文件,在配置文件中可以定义读写分离,逻辑库,逻辑表,dataHost,dataNode等信息。

①标签schema:配置逻辑库的标签;

属性name:逻辑库名称;

属性checkSQLschema:是否检测SQL语法中的schema信息;如MyCat逻辑库名称,dataNode名称

例如:SQL : select * from A.table;
checkSQLschema 值是 true, Mycat 发送到数据库的 SQL 是 select * from table; checkSQLschema 值是 false,Mycat 发送的数据库的 SQL 是 select * from A.table;

sqlMaxLimit: Mycat 在执行 SQL 的时候,如果 SQL 语法中没有 limit 子句.自动增加 limit 子句. 避免一次性得到过多的数据,影响效率. limit 子句的限制数量默认配置为 100.如果 SQL 中有具体的 limit 子句,当前属性失效.
例如:SQL : select * from table . mycat 解析后: select * from table limit 100

SQL : select * from table limit 10 . mycat 不做任何操作修改.

②标签table: 定义逻辑表的标签,如果需要定义多个逻辑表,编写多个 table 标签。要求逻辑表的表名和物理表(MySQL 数据库中真实存在的表)的表名一致。

属性name:逻辑表名

属性dataNode: 数据节点名称. 配置文件中后续需要定义的标签(即物理数据库中的 database 名称). 多个名称使用逗号分隔;多个 database 定义后,代表分库。

属性rule: 分片规则名称.具体的规则名称参考 rule.xml 配置文件;SQL 语句发送到 Mycat 中后,Mycat 如何计算,应该将当期的 SQL 发送到哪一个物理数据库管理系统或物理 database 中。

③标签dataNode:定义数据节点的标签, 定义具体的物理 database 信息的。

属性name: 数据节点名称, 是定义的逻辑名称,对应具体的物理数据库 database

属性dataHost: 引用 dataHost 标签的 name 值,代表使用的物理数据库所在位置和配置信息.
属性database: 在 dataHost 物理机中,具体的物理数据库 database 名称.

④dataHost标签

定义数据主机的标签, 就是物理 MYSQL 真实安装的位置。

属性name: 定义逻辑上的数据主机名称

属性maxCon/minCon:最大/小连接数

属性dbType: 数据库类型 : mysql 数据库

属性dbDriver: 数据库驱动类型, native,使用 mycat 提供的本地驱动.

dataHost子标签writeHost

写数据的数据库定义标签. 实现读写分离操作.

属性host:数据库命名

属性url:数据库访问路径

属性user:数据库访问用户名

属性password:访问用户密码


<?xml version="1.0"?>


  • server.xml

配置MyCat服务信息的;如:Mycat 中的用户,用户可以访问的逻辑库,可以访问的逻辑表,服务的端口号等.


<property


8. 启动MyCat命令

bin/mycat start

9. 停止命令

bin/mycat stop

10. 查看MyCat状态

bin/mycat status

11. 访问方式

可以使用命令行或者客户端软件访问

①命令行访问

mysql -u 用户名 -p 密码 -hmycat 主机 IP -P8066
链接成功后,可以当做 MySQL 数据库使用.
访问成功后,不能直接使用。因为 Mycat 只能访问 MYSQL 的 schema(database),不能自动创建逻辑库对应的物理库。且不能自动创建逻辑表对应的物理表。
必须人工链接 master 数据库,手动创建 database。
表格可以在 mycat 控制台创建。注意:在 mycat 控制台创建的表,必须是 schema.xml 配置文件中定义过的逻辑表。启动后,经过测试,crc32slot 分片规则无效,执行 DML 语句的时候只能识别 db1 和 db2。 DDL 语句,可以识别 db3。


<function


12.访问约束

①表约束

不能创建未在 schema.xml 中配置的逻辑表

②DML约束

尤其是新增: 必须在 insert into 语法后携带所有的字段名称.至少携带主键名称. 因为分片规则,绝大多数都是通过主键字段计算数据分片规则的.

13.查看MyCat日志

logs/wrapper.log
日志中记录的是所有的 mycat 操作. 查看的时候主要看异常信息 caused by 信息