MyCat------基于java语言的数据库中间件

时间:2022-07-22
本文章向大家介绍MyCat------基于java语言的数据库中间件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、介绍

简介

MyCat 是目前最流行的基于 java 语言编写的数据库中间件,是一个实现了 MySQL 协议的服务器,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问, 而其后端可以用 MySQL 原生协议与多个 MySQL 服务器通信,也可以用 JDBC 协议与大多数 主流数据库服务器通信,其核心功能是分库分表。配合数据库的主从模式还可实现读写分离MyCat 是基于阿里开源的 Cobar 产品而研发,Cobar 的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得 MyCat 变得非常的强大。

MyCat 发展到目前的版本,已经不是一个单纯的 MySQL 代理了,它的后端可以支持 MySQL、 SQL Server、Oracle、DB2、PostgreSQL 等主流数据库,也支持 MongoDB 这种新型 NoSQL 方式的存储**,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在 MyCat 里,都是一个传统的数据库表,支持标准的 SQL 语句进行数据的操作,这样 一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。 MyCat 官网:http://www.mycat.io/

结构图

优势

1. 数据量级

单一的 MySQL 其数据存储量级和操作量级有限. Mycat 可以管理若干 MySQL 数据库,同时实现数据的存储和操作.

2. 开源性质

Mycat 是 java 编写的中间件. 开源,免费. Mycat 版本提升较快,可以跟随环境发展.如果有问题,可以快速解决. Mycat 有开源网站和开源社区.且有官方发布的电子书籍.

3 市场应用

性能决定需求,因此Mycat 在互联网应用中占比非常高.

二、MyCat中的术语

切分

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

垂直切分/纵向切分

就是把原本存储于一个库的数据存储到多个库上。 由于对数据库的读写都是对同一个库进行操作,所以单库并不能解决大规模并发写入的问题。

优点 1)减少增量数据写入时的锁对查询的影响。 2)由于单表数量下降,常见的查询操作由于减少了需要扫描的记录,使得单表单次查询所需的检索行数变少,减少了磁盘 IO,时延变短。 缺点: 无法解决单表数据量太大的问题。

例如 我们会建立定义数据库 workDB、商品数据库 payDB、用户数据库 userDB、日志 数据库 logDB 等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。

水平切分/横向切分

把原本存储于一个表的数据分块存储到多个表上。当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,进行划分,然后存储到多个结构相同的表,和不同的库上。

优点 1)单表的并发能力提高了,磁盘 I/O 性能也提高了。 2)如果出现高并发的话,总表可以根据不同的查询,将并发压力分到不同的小表里面。 缺点: 无法实现表连接查询。

逻辑库(Schema)

主要是针对纵向切分提供的概念. Mycat 中定义的 database.是逻辑上存在的.但是物理上是不存在的.

逻辑表(table)

主要是针对横向切分提供的概念. , Mycat 中定义的 table.是逻辑上存在,物理上是不存在的.

注: 逻辑库逻辑表是创建mycat 后就存在的 ,可以被覆盖 ,但是不可以被删除

开发过程中常用的默认端口

软件 / 协议名

默认端口

MySQL

3306

Mycat

8066

tomcat

8080

Oracle

1521

nginx

80

http

80

redis

6379

数据主机(dataHost)

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

数据节点(dataNode)

配置物理的 database. 数据保存的物理节点.就是 database.

分片规则

当控制数据的时候,如何访问物理 database 和 table. 就是访问 dataHost 和 dataNode 的算法. 如:哈希算法,crc32 算法等.

三、MyCat的作用

读写分离

需要搭建主从模式,让主数据库(master)处理事务性增、改、删操作(INSERT、 UPDATE、DELETE),而从数据库(slave)处理 SELECT 查询操作。 Mycat 配合数据库本身的复制功能,可以解决读写分离的问题。

主从备份

主从备份 , 就是一种主备模式的数据库应用. 主库(Master)数据与备库(Slave)数据完全一致. 实现数据的多重备份, 保证数据的安全. 可以在 Master[InnoDB]和 Slave[MyISAM]中使用不同的数据库引擎,实现读写的分离

MySQL5.5, 5.6 版本后本身支持主从备份 , 在老旧版本的 MySQL 数据库系统中,不支持主从备份,需要安装额外的 RPM 包. 如果需要安装 RPM,只能在一个位置节点安装.

主从备份目的

1 实现主备模式

保证数据的安全. 尽量避免数据丢失的可能.

2 实现读写分离

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

主从备份效果

1.所有对 Master 的操作,都会同步到 Slave 中. 2. 如果 Master和 Salve天生上环境不同 , 那么对 Master的操作 , 可能会在 Slave中出现错误 3. 主从模式创建成功后 , 在 Master中 drop database db3. Slave中抛出数据库 SQL异常 . 后续所有的命令不能同步 . 一旦出现错误 . 只能重新实现主从模式

逻辑图

主从模式的实现时依赖主库的二进制日志文件实现的 , 当主库的数据发生改变时,会将相对应的SQL语句读取到日志文件中. 然后从库通过io线程将这个日志文件写入到从从库的日志文件中,并调用SQL线程完成数据的同步

四、主从模式环境搭建

安装Mysql

安装两个mysql分别作为主库和从库 主库:192.168.179.128 从库:192.168.179.129

主从备份设置

主库配置

1、进入配置文件中,修改server_id,开启日志文件并命名

   vim /etc/my.cnf 

2、重启Mysql

service mysqld restart

3、 配置Master,访问Mysql

mysql -uusername -ppassword 

4、创建用户,刷新权限

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

--刷新权限
flush privileges; 

@后跟的是从库的ip地址 ip 地址不能写为%. 因为主从备份中,当前创建的用户,是给从库 Slave 访问主库 Master 使用的.用户必须有指定的访问地址.不能是通用地址.

举例:

grant all privileges on *.* to 'myslave'@'192.168.179.129' identified by 'myslave' with grant option; 

5、查看用户主库是否创建好

use mysql; 

select host, user from user; 

出现勾选的即成功! 再次强调,千万不要配成主库的ip,截图中的128就是错误示范 , 三个字代表我的心情,mmp~~~

6、查看主库日志信息

show master status;

6 、关闭防火墙或者开放3306端口

service iptables stop

补充 : 如果mysql主从同步因为错误断开后修复同步 解决步骤:

在slave停止同步

stop slave;

在master端刷新日志

flush logs;

查看master状态

show master status;

在slave端输入

change master to master_host='192.168.40.128', master_user='username', master_password='password', master_log_file='master_log.logname',MASTER_LOG_POS=120;

MASTER_LOG_POS值为master状态中的position;不加会报错

启动slave

start slave;

从库配置

1、进入配置文件中,修改server_id,本环境中配置为3(大于主库id即可)

vim /etc/my.cnf 

server_id=3

2、重启MySQL服务,并访问

service mysqld restart

mysql -uusername -ppassword 

3、 停止Slave功能

stop slave;

4 、 配置主库信息

change master to master_host='主库ip', master_user='myslave', master_password='myslave', master_log_file='master_log.000001',MASTER_LOG_POS=120;

需要修改的数据是依据Master信息修改的. ip是Master所在物理机IP. 用户名和密码是 Master 提供的 Slave 访问用户名和密码. 日志文件是在 Master 中查看的主库信息提供的.在 Master 中使用命令 show master status 查看日志文件名称. 例如

change master to master_host='192.168.179.128',master_user='myslave',master_password='myslave',master_log_file='master_log.000003'; 

5、启动Slave功能

start slave;

6、查看Slave配置

mysql> show slave status G;

测试主从

在主库创建一个数据库,看从库能否查到 在主库创建一个数据表,看从库能否查到 在数据表中插入一条数据,看从库能否查到 如果都有,则配置成功, 如果没有,检查每个步骤,重新配置

-- 查看所有数据库表
show databases;

-- 使用该数据库
use database_name

MyCat的安装

前提

  • 需要有搭建好的主从模式的数据库
  • 需要将主从模式所在主机的3306端口打开(关闭防火墙或开放该端口)
  • 安装MyCat的主机需要配置JDK,关闭防火墙
  • 保证 root 用户可以被 mycat 访问

方法: 在 Mycat 中通过 Master 数据库的 root 用户访问 Master 数据库(主从数据库都要进行授权).

-- 授权
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option; 
 
 -- 刷新权限
flush privileges; 

步骤

1. 解压

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

2. 将解压后的文件夹复制到/usr/local/

[root@localhost chy]# cp mycat/ /usr/local/ -rf

mycat根目录下文件的简单介绍 bin 目录里是启动脚本 conf 目录里是配置文件 catlet 为 Mycat 的一个扩展功能 lib 目录里是 Mycat 和它的依赖 jar logs 目录里是 console.log 用来保存控制台日志,和 mycat.log 用来保存 mycat 的 log4j 日志

五、MyCat配置文件

Mycat 的架构其实很好理解,Mycat 是代理,Mycat 后面就是物理数据库和 Web 服务器的 Nginx 类似。对于使用者来说,访问的都是 Mycat,不会接触到后端的数据库。 我们现在做一个主从、读写分离。

server.xml

MyCat 的配置文件,设置账号、参数等

主要内容展示

<user name="root">
                <property name="password">123456</property>
                <property name="schemas">TESTDB</property>

                <!-- 表级 DML 权限设置 -->
                <!--            
                <privileges check="false">
                        <schema name="TESTDB" dml="0110" >
                                <table name="tb01" dml="0000"></table>
                                <table name="tb02" dml="1111"></table>
                        </schema>
                </privileges>           
                 -->
        </user>

        <user name="user">
                <property name="password">user</property>
                <property name="schemas">TESTDB</property>
                <property name="readOnly">true</property>
        </user>

配置信息

节点/属性

作用

user

用户配置节点 -

-name

登录的用户名,也就是连接 Mycat 的用户名

-password

登录的密码,也就是连接 Mycat 的密码

- schemas

逻辑库名,这里会和 schema.xml 中的配置关联,多个用逗号分开,例如需要这个用户管理两个数据库 db1,db2,则配置 db1,db2

-privileges

配置用户针对表的增删改查的权限

如: 配置Mycat 中的用户,用户可以访问的逻辑库,可以访问的逻辑表,服务的端口号等 默认配置了一个账号 root 密码也是 123456,针对数据库 TESTDB,读写权限都有,没有 针对表做任何特殊的权限。

配置权限

schema.xml

MyCat 对应的物理数据库和数据库表的配置

主要内容展示

<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">                 
         <table name="t_user" dataNode="dn1,dn2,dn3" rule="crc32slot" /> 
</schema> 
 <dataNode name="dn1" dataHost="localhost1" database="db1" />        
 <dataNode name="dn2" dataHost="localhost1" database="db2" />         
 <dataNode name="dn3" dataHost="localhost1" database="db3" />         
	 <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">   
	  <heartbeat>select user()</heartbeat>                 
	  <writeHost host="hostM1" url="localhost:3306" user="root"  password="root">   
	   <readHost host="hostS2" url="192.168.1.200:3306" user="root" password="root" />   
	   </writeHost>         
   </dataHost> 
   </mycat:schema>   

用于定义逻辑库和逻辑表的配置文件

schema 配置逻辑库,name 与 server.xml 中 schema 对应 dataNode 定义数据节点的标签,也就是分库相关配置 dataHost 物理数据库,真正存储数据的数据库

节点与属性

节点/属性

作用

schema标签

配置逻辑库的标签

- name

逻辑库名称

- checkSQLschema

是否检测 SQL 语法中的 schema 信息

-sqlMaxLimit

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

table标签

定义逻辑表的标签

-name

逻辑表名

-database

数据节点名称. 即物理数据库中的 database 名称.多个名称使用逗号分隔

-rule

分片规则名称.具体的规则名称参考 rule.xml 配置文件.

dataNode标签

定义数据节点的标签

-name

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

-dataHost

dataHost 标签的 name 值,代表使用的物理数据库所在位置和配置信息.

-database

在 dataHost 物理机中,具体的物理数据库 database 名称.

dataHost标签

定义数据主机的标签

- name

定义逻辑上的数据主机名称

- maxCon/minCon

最大连接数, max connections 最小连接数, min connections

- dbType

数据库类型指定 : mysql 数据库

-dataHost

引用 dataHost 标签的 name 值,代表使用的物理数据库所在位置和配置信息.

- dbDirver

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

dataHost 子标签 writeHost : 指定负责增删改的数据库的配置信息 属性 host 数据库命名 属性 url 数据库访问路径 属性 user 数据库访问用户名 属性 password 访问用户密码

writeHost 子标签 readHost :指定负责查询的数据库的配置信息 属性 host 数据库命名 属性 url 数据库访问路径 属性 user 数据库访问用户名 属性 password 访问用户密码

注意

  1. 关于 checkSQLschema 如: Mycat 逻辑库名称 A, dataNode 名称 B SQL : select * from A.table; checkSQLschema 值是 true, Mycat 发送到数据库的 SQL 是 select * from table; checkSQLschema 只是 false,Mycat 发送的数据库的 SQL 是 select * from A.table;
  2. sqlMaxLimit SQL : select * from table . mycat 解析后: select * from table limit 100 SQL : select * from table limit 10 . mycat 不做任何操作修改.

rule.xml

用于定义分片规则的配置文件 mycat 默认的分片规则: 以 500 万为单位,实现分片规则. 逻辑库 A 对应 dataNode - db1 和 db2. 1-500 万保存在 db1 中, 500 万零 1 到 1000 万保存 在 db2 中,1000 万零 1 到 1500 万保存在 db1 中.依次类推.

tableRule

 <tableRule name="rule1">                 
	 <rule>                         
		 <columns>id</columns>                         
		 <algorithm>func1</algorithm> 
	 </rule>         
 </tableRule> 

属性/节点

作用

name

属性指定唯一的名字,用于标识不同的分片规则。内嵌的 rule 标签则指定对物理表中的哪一列进行拆分和使用什么分片算法

columns

指定要拆分的列名字

algorithm

使用 function 标签中的 name 属性。连接表规则和具体分片算法。 table 标签内使用。让逻辑表使用这个规则进行分片

function

用于指定分片算法

 <function name="func1" class="io.mycat.route.function.PartitionByLong">                
		  <property name="partitionCount">8</property>                 
		  <property name="partitionLength">128</property>         
  </function> 

节点/属性

作用

name

指定算法的名字

class

指定分片算法具体的类名字

property

为具体算法需要用到的一些属性

六、配置读写分离

schema.xml

对配置文件进行适当的删改,以此达到方便使用的效果 , 然后对schema标签内容进行修改 注意:balance的作用 balance=”0”, 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上 balance=”1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡 balance=”2”,所有读操作都随机的在 writeHost、 readhost 上分发。 balance=”3”, 所有读请求随机的分发到 writeHost 对应的 readhost 执行,writerHost 不负担读压力

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<schema name="schema_t_users" checkSQLschema="false" sqlMaxLimit="100">
		<table name="数据表名"  dataNode="dn1" />
	</schema>
	<dataNode name="dn1" dataHost="localhost1" database="主从数据库名" />
	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<!-- can have multi write hosts -->
		<writeHost host="hostM1" url="192.168.179.128:3306" user="root"
				   password="root">
			<!-- can have multi read hosts -->
			<readHost host="hostS2" url="192.168.179.129:3306" user="root" password="root" />
		</writeHost>
	</dataHost>
</mycat:schema>

server.xml

注意用户名密码的设置,以及将通过sechema.xml设置的name属性放入到server.xml中

<user name="mycat登陆用户名(root)">
		<property name="password">mycat登陆密码(root)</property>
		<property name="schemas">schema_t_users</property>
		
		<!-- 表级 DML 权限设置 -->

	</user>

	<user name="mycat登陆用户名(普通用户)">
		<property name="password">mycat登陆用户名(普通用户)</property>
		<property name="schemas">schema_t_users</property>
		<property name="readOnly">true</property>
	</user>

七、测试读写分离

前提

主从模式搭建完毕 访问防火墙或相应端口全部关闭

相关命令

在根目录下 ,输入以下命令

-- 启动 Mycat 命令 
./bin/mycat start 

-- 停止命令 
./bin/mycat stop 

-- 重启命令 
./bin/mycat restart 

--查看 MyCat 状态 
./bin/mycat status 

访问方式

命令行访问:

mysql -u 用户名 -p 密码 -hmycat 主机 IP -P8066 链接成功后,可以当做 MySQL 数据库使用. 访问约束

软件访问:

通过Navicat继续访问 注意端口不是3306,而是8066

进行测试

在MyCat中插入数据,看主从数据库能否同步到主从数据库中

八、MyCat分库

分片规则

auto-sharding-long 范围约定

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

crc32slot 规则

在 CRUD 操作时,根据具体数据的 crc32 算法计算,数据应该保存在哪一个 dataNode 中

注意

1)id中推荐配置主键列 2)所有的 tableRule 只能使用一次。如果需要为多个表配置相同的分片规则,那么需要在此重新定义该规则。 (可以重新复制一份tableRule,修改其name属性,引用改变后的name属性) 3)在 crc32Slot 算法中的分片数量一旦给定,MyCat 会将该分片数量和 slor 的取值范围

配置分库

1)在 master 中创建 3 个数据库 2)在 MyCat 中创建物理表,虽然MyCat上已经有t_users这张表,但这是逻辑表, 需要同SQL语句创建物理表 3) 在MyCat中配置分库

-- 创建数据库
create database java1 default character set utf8; 
create database java2 default character set utf8; 
create database java3 default character set utf8; 

-- 创物理表t_users
CREATE TABLE `t_users` (   
`id` int(11) NOT NULL,   
`name` varchar(30) DEFAULT NULL,   
PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

配置schema.xml

配置 rule.xml

注意:

配置后需要重启, 重启前首先要查看conf目录下是否生成了默认的分片文件ruledata,如果有,删除后在重启

./mycat restart

测试

在MyCat插n条数据入数据 看这些数据是否会随机分配在不同的数据库中 如果是,则测试成功!!!