现代Java服务端开发核心技术之分布式数据库中间件MyCAT入门

Posted ittimeline

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了现代Java服务端开发核心技术之分布式数据库中间件MyCAT入门相关的知识,希望对你有一定的参考价值。

现代Java服务端开发核心技术之分布式数据库中间件MyCAT入门

MyCAT系统环境搭建

如下列表展示了搭建MyCAT运行时环境所需要的软件及其版本说明。

软件名称软件版本
os centos7.5
JDK JDK1.8u191
mysql MySQL5.7
Mycat Mycat1.6.5
Navicat Navicat12.08

在非集群的环境下,MyCAT仅仅依赖JDK就可以良好的运行在Windows,Linux,macOS等操作系统之上。

CentOS7下载和安装

目前主流的服务端操作系统centOS版本为centOS6和centOS7两个版本,这里给出
阿里云的镜像下载地址。可以根据镜像提示安装。
下载地址
https://mirrors.aliyun.com/centos/7.5.1804/isos/x86_64/

查看centOS版本

[[email protected] Downloads]# cat /etc/redhat-release #查看安装版本 
CentOS Linux release 7.5.1804 (Core) 

JDK8安装和配置

MyCAT是基于JDK1.7开发,目前互联网公司主流JDK版本为1.8,因此这里介绍JDK1.8在CentOS7.5下的安装、配置。

JDK8下载地址: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

[[email protected] Downloads]# mkdir -p /usr/local/java
[[email protected] Downloads]# tar -xvf jdk-8u191-linux-x64.tar.gz 
[[email protected] Downloads]# cp -r jdk1.8.0_191/ /usr/local/java/

配置

[[email protected] Downloads]# vim /etc/profile

export JAVA_HOME=/usr/local/java/jdk1.8.0_191
export PATH=$PATH:$JAVA_HOME/bin

[[email protected] Downloads]# source /etc/profile

验证安装

[[email protected] Downloads]# javac -version
javac 1.8.0_191

[[email protected] Downloads]# java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

MySQL5.7安装和配置

目前主流的MySQL版本为5.6和5.7两个版本,这里介绍MySQL5.7在centOS7.5下的安装、基本配置(修改密码、远程连接、开机启动)及其使用Navicat连接MySQL。

MySQL的下载和安装

首先检查系统中是否已经安装过MySQL,以下提供两种方式

[[email protected] Downloads]# yum list installed |grep mysql
[[email protected] Downloads]# rpm -qa|grep mysql

如果已经安装过,可以使用如下命令删除

[[email protected] Downloads]# yum -y remove 

下载MySQL

[[email protected] Downloads]# wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz

解压缩并复制到/usr/local/mysql目录下

[[email protected] Downloads]# tar -xvf mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz 

[[email protected] Downloads]# mv mysql-5.7.24-linux-glibc2.12-x86_64 /usr/local/mysql

创建数据存储目录

[[email protected] Downloads]# mkdir -p /data/mysql

新建mysql用户、组和目录

[[email protected] Downloads]# groupadd mysql
[[email protected] Downloads]# useradd -r -s /sbin/nologin  -g mysql mysql -d /usr/local/mysql/

改变目录所有者

[[email protected] Downloads]# cd /usr/local/mysql/
[[email protected] mysql]# chown -R mysql .
[[email protected] mysql]# chgrp -R mysql .
[[email protected] mysql]# chown -R mysql /data/mysql

MySQL初始化参数配置

指定mysql服务端的用户以及安装目录和数据存放的目录以及生成root账号密码

[[email protected] mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
2018-10-27T03:09:02.164480Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2018-10-27T03:09:02.764905Z 0 [Warning] InnoDB: New log files created, LSN=45790
2018-10-27T03:09:02.852039Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2018-10-27T03:09:02.923109Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: a8263578-d995-11e8-a863-000c29be37a9.
2018-10-27T03:09:02.924734Z 0 [Warning] Gtid table is not ready to be used. Table ‘mysql.gtid_executed‘ cannot be opened.
2018-10-27T03:09:02.925516Z 1 [Note] A temporary password is generated for [email protected]: <Xdfhi4Wvy6(

此处需要注意生成的临时密码 ,如上问结尾处的<Xdfhi4Wvy6(

[[email protected] mysql]# bin/mysql_ssl_rsa_setup  --datadir=/data/mysql

修改系统配置文件,复制mysql.server到/etc/init.d/mysql

[[email protected] mysql]# cd /usr/local/mysql/support-files/
[[email protected] support-files]# cp mysql.server  /etc/init.d/mysql
[[email protected] support-files]# vim /etc/init.d/mysql 

然后配置mysql的安装目录和数据存储目录,修改以下内容

basedir=/usr/local/mysql
datadir=/data/mysql

MySQL的启动和登录

启动MySQL

[[email protected] support-files]# /etc/init.d/mysql start
Starting MySQL.Logging to ‘/data/mysql/ittimeline.net.err‘.
 SUCCESS! 

重启MySQL

[[email protected] ~]# /etc/init.d/mysql restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL. SUCCESS! 

本机客户端登录MySQL

[[email protected] support-files]# mysql -h127.0.0.1 -uroot -p
bash: mysql: command not found...
#创建一个软连接
[[email protected] support-files]# ln -s /usr/local/mysql/bin/mysql /usr/bin
#再次登录MySQL,输入之前的临时密码
[[email protected] support-files]# mysql -h127.0.0.1 -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 3
Server version: 5.7.24

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘h‘ for help. Type ‘c‘ to clear the current input statement.

mysql>

MySQL的基本配置

  1. 修改随机生成的root密码
    由于MySQL的初始化随机密码不太容易记住,因此这里需要修改生成的随机密码,在使用root登录MySQL后使用如下命令修改,即root用户的密码为root
[[email protected] ~]# mysql -uroot -p -h127.0.0.1
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 21
Server version: 5.7.24 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;‘ or ‘h‘ for help. Type ‘c‘ to clear the current input statement.

mysql> set password=password(‘root‘);
Query OK, 0 rows affected, 1 warning (0.00 sec)

  1. 配置远程登录连接

通过授权root账号,设置root的host为%,表示任意的客户端都可以通过root账户登录到MySQL服务器。

mysql> grant all privileges on *.* to ‘root‘@‘%‘ identified by ‘root‘;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

查看mysql数据库的user表的host信息,当root的host值为%则可以实现远程链接


mysql> use mysql; ##切换到mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select host,user from user; ##查看user信息
+-----------+---------------+
| host      | user          |
+-----------+---------------+
| %         | root          |
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
4 rows in set (0.00 sec)
  1. MySQL设置开机启动
[[email protected] bin]# chmod 755 /etc/init.d/mysql
[[email protected] bin]# chkconfig --add mysql
[[email protected] bin]# chkconfig --level 345 mysql on

检测是否开机启动成功

[[email protected] bin]# reboot #重启系统
[[email protected] ~]# ps -ef|grep mysql #使用ps命令查看MySQL进程信息
root       1052      1  0 21:10 ?        00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --pid-file=/data/mysql/ittimeline.net.pid
mysql      1242   1052  1 21:10 ?        00:00:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=ittimeline.net.err --pid-file=/data/mysql/ittimeline.net.pid
root       1902   1855  0 21:11 pts/0    00:00:00 grep --color=auto mysql

MySQL的远程连接

通常情况下都是通过MySQL客户端(例如Navicat)来远程连接MySQL服务端,首先使用ifconfig命令查看MySQL所在的centOS服务的IP地址

[[email protected] ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.105  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::20c:29ff:febe:37a9  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:be:37:a9  txqueuelen 1000  (Ethernet)
        RX packets 1412887  bytes 2058226957 (1.9 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 276749  bytes 22287862 (21.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

然后检测防火墙的状态
systemctrl status firewalld 命令显示当前防火墙正在运行,如下所示

[[email protected] ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: active (running) since Fri 2018-10-26 20:42:21 PDT; 24s ago
     Docs: man:firewalld(1)
 Main PID: 9444 (firewalld)
    Tasks: 2
   CGroup: /system.slice/firewalld.service
           └─9444 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

此时我们需要使用 systemctl stop firewalld关闭防火墙

[[email protected] ~]# systemctl stop firewalld

或者使用如下命令让防火墙放行3306端口

[[email protected] ~]# firewall-cmd  --zone=public --add-port=3306/tcp --permanent  
success
[[email protected] ~]# service firewalld restart
Redirecting to /bin/systemctl restart firewalld.service

然后使用Navicat客户端登录MySQL服务,如下图所示
技术分享图片

MyCAT数据初始化

在学习到MyCAT的分库分表以及读写分离操作时需要使用到相关的表和数据已经上传至GitHub仓库
只需要在Navicat客户端中执行该SQL脚本完成以后会得到以下的数据库表
技术分享图片

MyCAT概述

什么是MyCAT

  • DBA看到的MyCAT
    • Mycat相当于MySQLServer层
    • MySQL相当于MyCAT存储层
    • MyCAT中不存储数据,所有数据存储在MySQL的存储引擎(例如InnoDB)中
  • 研发人员看到的MyCAT
    • MyCAT就是MySQL
    • MyCAT对使用的SQL有些限制
  • 系统架构师看到的MyCAT
    • MyCAT是一个数据库中间件
    • MyCAT可以实现对后端数据库集群的分库分表和读写分离
    • MyCAT对前端应用隐藏了后端数据库的存储逻辑

数据库中间件

如下图所示,应用通过连接数据库中间件(MyCAT),完成数据库的读写操作。 数据库中间件(MyCAT)位于前端应用和后端数据库集群的中间。
技术分享图片

MyCAT的主要作用

  • 数据库中间件

当应用中引入MyCAT之后,作为分布式数据库系统的中间件使用,而分布式数据库系统通常是由分布在不同的机器的数据库实例所组成,应用通过连接MyCAT,完成数据库的读写操作。
而且MyCAT原生支持MySQL,还可以通过JDBC来支持MSSQLSERVER,Oracle以及像Mongo这样的NoSQL数据库。

  • 实现后端数据库的主从数据库读写分离以及负载均衡
    • 读写分离:
      通常一般的业务系统,读写数据通常都在一个数据库(主库)内进行。
      常见的业务场景读写比例通常是10:1甚至更高,而某些度读请求的SQL容易产生慢查询,而单台数据库无法处理大量读数据请求的情况下,为了保证写数据请求的业务正常进行,为了解决这种业务场景的数据库瓶颈,通常采用读写分离,也就是将原有的数据库复制一份充当从库,当写数据时,写入到主库后同步到从库,而读数据时则在从库中进行,进而降低主库写请求的压力。
    • 负载均衡:因为一般业务系统主要以查询为主,而当一台从库不能满足读取数据的业务场景时,需要引入多台从库,为了能够合理的分配读取数据的请求,此时需要引入负载均衡。

MyCAT的独特之处在一主一从的情况下,当主数据库宕机之后,MyCAT会将主库从集群中剔除,后续的写数据请求可以路由到从库上进行。

而一主多从的情况下,推荐使用MySQL的MHA工具实现。

  • 对业务数据库进行垂直切分
    在业务系统(例如典型的电商业务)上线初期,所有的数据库表可能存储在一个数据库中。
    而垂直切分就是将一个数据库中的表按照不同的业务模块(例如用户模块,商品模块。订单模块,仓储配送模块等等)拆分成多个不同的数据库存储。
    完成数据库切分之后前端应用就可以使用MyCAT来连接切分之后不同的数据库,如何垂直切分?有啥好处?下回见分晓。

  • 对业务数据库进行水平切分
    如果垂直切分依然解决不了数据库性能的瓶颈问题,那么在垂直切分的基础之上需要引入水平切分,水平切分就是将原来存储在单个数据库表的数据拆分成多个数据库表存储,因为不同的数据库表存储的数据量过大会影响性能。
    如何水平切分?有啥好处?下回见分晓。

  • 控制数据库连接的数量
    每个连接到数据库的客户端都会占用数据库的连接资源,而数据库的连接数量是有一定的限制,在MySQL中通过max_connections参数来配置。
    当数据库的连接数占满之后,所有新建的连接都不能访问数据库,这会影响业务的正常运行,典型的业务场景就是电商的大促。
    在引入MyCAT之后可以通过MyCAT建立公共的连接池来管理数据库的连接。

MyCAT运行环境搭建

关于MyCAT涉及到的软件以及版本如下表格所示

软件名称软件版本
os centOS7.5
JDK JDK1.8u191
MyCAT-server 1.6.5
MySQL MySQL5.7

MyCAT-server二进制版本下载点我

MyCAT-server源码下载点我

首先去Mycat官网提供的地址下载基于Linux版本的二进制包

[[email protected] Downloads]# wget http://dl.mycat.io/1.6.5/Mycat-server-1.6.5-release-20180122220033-linux.tar.gz

然后解压并复制到目录/usr/local/mycat1.6.5

[[email protected] Downloads]# tar -xvf Mycat-server-1.6.5-release-20180122220033-linux.tar.gz 
[[email protected] Downloads]# cp -r mycat/ /usr/local/ 

并将mycat的bin目录添加到系统环境变量中,后面使用mycat命令启动mycat服务时会用到该环境变量

[[email protected] mycat]# vim /etc/profile
#添加如下内容
export MYCAT_HOME=/usr/local/mycat
export PATH=$PATH:$MYCAT_HOME/bin

[[email protected] mycat]# source /etc/profile

验证配置

[[email protected] ~]# echo $MACAT_HOME
/usr/local/mycat

然后添加一个用户名和密码为mycat的用户,并将/usr/local/mycat的所有者改为mycat

[[email protected] Downloads]# useradd mycat
[[email protected] mycat]# passwd mycat
Changing password for user mycat.
New password: 
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 
passwd: all authentication tokens updated successfully.
[[email protected] Downloads]# cd /usr/local/mycat/
[[email protected] mycat]# chown mycat:mycat -R /usr/local/mycat
[[email protected] mycat]# pwd
/usr/local/mycat
[[email protected] mycat]# ls -al .
total 12
drwxr-xr-x.  7 mycat mycat   85 Oct 26 23:22 .
drwxr-xr-x. 15 root  root   169 Oct 26 23:22 ..
drwxr-xr-x.  2 mycat mycat  190 Oct 26 23:22 bin
drwxr-xr-x.  2 mycat mycat    6 Oct 26 23:22 catlet
drwxr-xr-x.  4 mycat mycat 4096 Oct 26 23:22 conf
drwxr-xr-x.  2 mycat mycat 4096 Oct 26 23:22 lib
drwxr-xr-x.  2 mycat mycat    6 Oct 26 23:22 logs
-rwxr-xr-x.  1 mycat mycat  219 Oct 26 23:22 version.txt

MyCAT的启动方式

当我们进入到MCAT_HOMEin目录下,会看到如下文件列表

[[email protected] bin]# pwd
/usr/local/mycat/bin
[[email protected] bin]# ls -al
total 384
drwxr-xr-x. 2 mycat mycat    190 Oct 26 23:22 .
drwxr-xr-x. 7 mycat mycat     85 Oct 26 23:22 ..
-rwxr-xr-x. 1 mycat mycat   3567 Oct 26 23:22 dataMigrate.sh
-rwxr-xr-x. 1 mycat mycat   1225 Oct 26 23:22 init_zk_data.sh
-rwxr-xr-x. 1 mycat mycat  15714 Oct 26 23:22 mycat
-rwxr-xr-x. 1 mycat mycat   2941 Oct 26 23:22 rehash.sh
-rwxr-xr-x. 1 mycat mycat   2496 Oct 26 23:22 startup_nowrap.sh
-rwxr-xr-x. 1 mycat mycat 140198 Oct 26 23:22 wrapper-linux-ppc-64
-rwxr-xr-x. 1 mycat mycat  99401 Oct 26 23:22 wrapper-linux-x86-32
-rwxr-xr-x. 1 mycat mycat 111027 Oct 26 23:22 wrapper-linux-x86-64

我们可以运行mycat命令和startup_nowrap.sh脚本来启动MyCAT服务,当运行mycat命令时,需要修改MYCAT_HOME/config/目录下的wrapper.properties文件。
如下所示,调整MyCAT的内存大小,默认为2G。

wrapper.java.additional.5=-XX:MaxDirectMemorySize=2G

使用mycat命令启动服务如下所示


[[email protected] Downloads]# mycat --help ## 查看mycat命令的帮助
Usage: /usr/local/mycat/bin/mycat { console | start | stop | restart | status | dump }
[[email protected] Downloads]# mycat start #启动mycat
Starting Mycat-server...

然后可以通过如下命令实时查看mycat的运行日志

[[email protected] Downloads]# tail -f /usr/local/mycat/logs/mycat.log  

因为mycat启动服务是会读取schema.xml文件中的相关配置,如果没有修改过schema.xml文件,那么会看到如下的连接数据库失败的错误

tail: no files remaining
[[email protected] logs]# tail -f mycat.log 
2018-10-26 23:59:46.854  INFO [$_NIOConnector] (io.mycat.sqlengine.SQLJob.connectionError(SQLJob.java:117)) - can‘t get connection for sql :select user()
2018-10-26 23:59:47.824 ERROR [$_NIOConnector] (io.mycat.net.NIOConnector.finishConnect(NIOConnector.java:155)) - error:
java.net.NoRouteToHostException: No route to host
        at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) ~[?:1.8.0_191]
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717) ~[?:1.8.0_191]
        at io.mycat.net.NIOConnector.finishConnect(NIOConnector.java:165) ~[Mycat-server-1.6.5-release.jar:?]
        at io.mycat.net.NIOConnector.finishConnect(NIOConnector.java:143) ~[Mycat-server-1.6.5-release.jar:?]
        at io.mycat.net.NIOConnector.run(NIOConnector.java:98) ~[Mycat-server-1.6.5-release.jar:?]

MyCAT核心配置

如果想要使用MyCAT数据库中间件实现数据的读写分离、分库分表、负载均衡等任务,就需要对MYCAT_HOMEconfig目录下配置文件的使用非常熟悉。

而MyCAT最主要的配置文件包括server.xml,schema.xml和rule.xml以及MyCAT采用的日志框架Log4j2的log4j2.xml,配置文件对应的作用说明如下表格所示

配置文件名称作用
server.xml 配置系统运行时的参数以及用户权限控制
schema.xml 配置逻辑库、逻辑表的使用
rule.xml 配置逻辑表的切分规则
log4j2.xml 记录MyCAT的运行日志

应用连接MyCAT也是通过配置来自于server.xml中配置的远程连接端口(默认是8066)、用户名(默认是root)、密码(123456)以及逻辑库(默认是TESTDB)名称。
而且应用所要操作的表都应该配置在schema.xml文件中。

MyCAT核心配置之server.xml

  • 文件用途
    • 配置系统运行相关参数
    • 配置用户访问权限
    • 配置SQL防火墙以及SQL拦截功能

service.xml中配置系统运行的相关属性都是在<system></system>节点中配置的,其中常见需要自定义配置的节点如下

<!-- 定义MyCAT对外提供的访问端口,默认是8066-->
<property name="serverPort">8066</property>

<!-- 定义MyCAT的管理端口,通过命令查看MyCAT的运行信息监控,默认是9066-->
<property name="managerPort">9066</property> 
<!-- 登录时是否需要密码 0为需要输入密码-->
<!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
    <property name="nonePasswordLogin">0</property> 
    
<!-- 指定MyCAT监听的IP,如果服务器是多网卡和IP地址,可以监控指定IP 如果想要监控所有IP地址,可以使用0.0.0.0的配置-->
<property name="bindIp">0.0.0.0</property> 

<property name="frontWriteQueueSize">4096</property>
<!--MyCAT的线程数量 -->
<property name="processors">32</property> 
<property name="processorExecutor">32</property> 

<!-- 客户端连接MyCAT空闲超时时间 默认为30分钟-->
<property name="idleTimeout">300000</property>
<!-- TODO-->
<property name="charset">utf8</property>
<property name="txIsolation">2</property>
<property name="defaultMaxLimit">100</property>
<property name="maxPacketSize">104857600</property>

service.xml中配置访问MyCAT的用户及其相关权限都是在<user></user>节点中配置的。如下所示为service.xml中的默认配置
分别配置了两个用户,root和user,其密码分别是123456和user,而且名为user的用户还是只读用户,如果访问MyCAT不需要密码,则可以使用root作为默认用户。

root用户可以访问TESTDB逻辑库,如果想要让其访问多个逻辑库,在TESTDB后面使用逗号分隔即可。

<user name="root" defaultAccount="true">
        <property name="password">123456</property>
        <property name="schemas">TESTDB,TEST_MySQL_Cluster</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>

如果想要控制某些用户使用表的访问权限,可以通过<privileges></privileges>节点来配置,其中<privileges>标签的check属性表示是否开启权限控制。
<schema></schema>标签用于定义作用的逻辑库对象,<schema>标签的dml属性是用户具有该逻辑库下所有表的权限定义。
<table></table>标签指定了用户访问表的具体权限,<table>的name属性指定了表名,而dml的四个数值分别对应insert,update,select和delete权限。0表示没有该权限,1表示有该权限,如果<table></table>标签中没有dml属性的定义,将会引用<schema></schema>标签的dml属性值。

因为<user></user>节点中配置的MyCAT密码是明文的,这样是及其不安全,我们可以使用如下命令对明文密码进行加密。

[[email protected] lib]# cd /usr/local/mycat/lib
[[email protected] lib]# java -cp Mycat-server-1.6.5-release.jar io.mycat.util.DecryptUtil 0:root:123456
GO0bnFVWrAuFgr1JMuMZkvfDNyTpoiGU7n/Wlsa151CirHQnANVk3NzE3FErx8v6pAcO0ctX3xFecmSr+976QA==

其中0表示前端应用对MyCAT密码进行加密,root表示加密的用户,123456就是加密之前的明文密码。
如果想要root用户使用加密之后的密码,只需要在<user></user>节点内增加<property name="usingDecrypt">1</property>,然后修改root用户的pasword属性值,
技术分享图片

而客户端(例如Java应用)连接MyCAT时就必须使用加密后的密钥进行访问了。

MyCAT日志

MyCAT的日志目录在MYCAT_HOMElogs目录下,它依赖Log4j2日志框架实现,如果想要改变日志的相关配置,可以通过修改MyCAT_HOMEconfig目录下的log4j2.xml。

完整的log4j2.xml如下所示

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <!--定义控制台输出的日志格式-->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d [%-5p][%t] %m %throwable{full} (%C:%F:%L) %n"/>
        </Console>

        <!--定义归档日志-->
        <RollingFile name="RollingFile" fileName="../logs/mycat.log"
                     filePattern="logs/$${date:yyyy-MM}/mycat-%d{MM-dd}-%i.log.gz">
            <PatternLayout>
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] (%l) - %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="250 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <!--<AsyncLogger name="io.mycat" level="info" includeLocation="true" additivity="false">-->
            <!--<AppenderRef ref="Console"/>-->
            <!--<AppenderRef ref="RollingFile"/>-->
        <!--</AsyncLogger>-->
        <!--定义输出日志级别-->
        <asyncRoot level="debug" includeLocation="true">
            <!--引用控制台输出和归档日志-->
            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingFile"/>

        </asyncRoot>
    </Loggers>
</Configuration>

MyCAT核心配置之rule.xml

当数据库需要进行水平拆分时,需要指定拆分的规则以及分片规则所对应的分片函数,而rule.xml正是MyCAT用来配置分片的配置文件。

分片的配置案例如下所示

使用<tableRule></tableRule>定义一个表的分片规则,name属性指定了分片规则的名字,名字必须要唯一。

<!-- 指定了数据库表的分片规则的名字-->
    <tableRule name="mod-long">
    <!-- 配置分片规则-->
        <rule>
            <!-- 指定分片的列-->
            <columns>id</columns>
            <!-- 指定分片的算法-->
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
        <!--分片算法的实现 哈希取模 -->
        <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <!-- 方法参数-->
        <property name="count">3</property>
    </function>

MyCAT常用分片算法实现

MyCAT常用分片算法的实现包括简单取模、哈希取模,枚举分片,字符串范围四种,其中简单取模,哈希取模无法人为的定义分片范围,由分片列的值来决定。

  • 简单取模
    对指定的分片列的值进行取模运算,把数据平均分配在多个表中
    优点:数据分布均匀,适用于分片的列为整数(例如id)的表。

配置实现如下所示

<tableRule name="mod-long">
        <rule>
            <columns>id</columns>
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <!-- 定义分片的数量-->
        <property name="count">2</property>
    </function>
  • 哈希取模
    如果想要用到非整数(字符串,日期)的列进行取模分片,这时候就可以采用哈希取模算法来实现,通过计算列的哈希值来取模实现分片。与简单取模分片算法不同的是哈希取模的分片会不均匀。
    配置实现如下所示
<tableRule name="mod-string">
        <rule>
            <!-- 哈希取模的类型可以是非整数类型-->
            <columns>name</columns>
            <algorithm>mod-string</algorithm>
        </rule>
    </tableRule>
    <function name="mod-string" class="io.mycat.route.function.PartitionByHashMod">
        <!-- how many data nodes -->
        <!-- 定义分片的数量-->
        <property name="count">2</property>
    </function>
  • 枚举分片算法
    如果想要人为的指定分片规则,那么就需要使用到枚举分片算法,可以根据枚举值指定数据存储的位置,其典型的应用场景是数据库需要进行异地多活时,通过mapFile配置分片列的值对应指定的数据节点

配置实现如下所示

<tableRule name="mod-enum-mapFile">
        <rule>
            <!-- 哈希取模的类型可以是非整数类型-->
            <columns>name</columns>
            <algorithm>mod-enum-mapFile</algorithm>
        </rule>
    </tableRule>
    <function name="mod-enum-mapFile" class="io.mycat.route.function.PartitionByFileMap">
    <!--config目录下 partition-map-file.txt文件配置枚举值对应的数据节点的关系-->
        <property name="mapFile">partition-map-file.txt</property>
        <!-- 0 枚举值的key为整数类型  非0 字符串类型-->
        <property name="type">0</property>
        <!--大于等于0表示启用默认节点  小于0表示不启用默认节点 具体的默认节点在partition-map-file中定义 -->
        <property name="defaultNode">0</property>
    </function>

partition-map-file.txt

#数据节点的索引是从0开始的,顺序就是schema.xml文件中定义dataNode的顺序
100000=0
100001=1
DEFAULT_NODE=0
  • 字符串范围取模分片
    字符串范围分片取模也就意味着分片列的类型必须是字符串,根据指定分片列字符串的前N个字符确定分片存储的节点位置。
    其算法实现是分别求字符串前缀的字符对应的ASC||值求和后执行求模运算来计算数据分片的节点位置。
    而我们可以通过mapFile文件定义取模的结果的区间对应数据节点。

配置文件如下所示

<tableRule name="mod-prefix-mapFile">
        <rule>
            <!-- 哈希取模的类型可以是非整数类型-->
            <columns>name</columns>
            <algorithm>mod-prefix-mapFile</algorithm>
        </rule>
    </tableRule>
    <function name="mod-prefix-mapFile" class="io.mycat.route.function.PartitionByPrefixPattern">
    <!-- 取模基数-->
    <property name="patternValue">128</property>
    <!-- 截取字符串前缀的长度-->
    <property name="prefixLength">2</property>
    <!-- 分区配置-->
<property name="mapFile">prefix-partition-pattern.txt</property>
    </function>

prefix-partition-pattern.txt

0-63=0
64-127=1

MyCAT核心配置之schema.xml

文件用途:

  • 配置逻辑库和逻辑表
    • 对应用来说相当于MySQL中的数据库
    • 在对数据库进行分库分表操作后,逻辑库对应后端多个物理数据库
    • 逻辑库中并不保存数据
  • 配置逻辑表所存储的数据节点
    • 对于应用来说相当于MySQL数据库中的表
    • 在对数据库进行分库分表操作后,逻辑表可以对应多个后端物理数据库中的表
    • 逻辑表中并不保存数据
    • 类别
      • 分片表:进行水平切后的表,具有相同的表结构,但是数据存储在不同的数据库表中
      • 非分片表:垂直切分的表
      • 全局表:在所有分片中存在的表
      • ER关系表:按照实体关系模型进行分片的表,可以将子表的记录和关联的父表存储在一个分片中。
  • 配置数据节点所对应的屋里数据库服务器信息

逻辑库的配置

<!--
定义一个名为TESTDB的逻辑库(可以定义多个),name表示唯一的逻辑库名字
checkSQLschema属性用来判断是或否检查发给MyCAT的SQL是否包含库名
sqlMaxLimit表示限制返回结果集的行数,-1表示关闭limit限制
-->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 
定义逻辑表
name表示逻辑表的名字
primaryKey表示逻辑表的主键
dataNode表示逻辑表存储的数据节点,水平切分时可以有多个数据节点,用逗号分隔多个数据节点
rule表示指定分片规则,对应rule.xml文件的tableRule节点的name属性
-->
        <table name="customer_inf" primaryKey="id" dataNode="MySQLDataNode"></table>
    </schema>

数据节点的配置

<!-- 定义逻辑表存储的物理数据库-->
<!--
    name表示数据节点的名字,必须唯一
    dataHost定义分片所在的物理主机,对应<dataHost></dataHost>节点的name属性
    database对应物理数据库的名称
-->
    <dataNode name="MySQLDataNode" dataHost="MySQLDataHost" database="mycat"></dataNode>

后端数据库的主机信息配置

<!-- 定数据库的主机信息配置-->
<!-- 
dataHost属性说明:
    name:表示数据主机的名称,必须唯一
    maxCon:表示最大连接数
    minCon:表示最小连接数
    balance:用于控制数据的读写分离和读数据的负载均衡,取值有四种
        0:不开启读写分离机制(单台数据库服务器)
        1:全部的readHost与stand by writeHost( 具有多个writeHost,例如双主双从)参与select语句的负载均衡
        2:所有的readHost与writeHost都参与select语句的负载均衡(写数据压力不大的应用场景)
        3:所有的readHost参与select语句的负载均衡,也就是所有的读请求会随机分发到writeHost对应的ReadHost,适合一主多从的数据库架构应用场景。
    writeType:后端数据库写操作类型配置,目前取值0和1,0表示所有的写操作都是由第一个writeHost执行,当第一个writeHost主机宕机之后才会切换到其他的writeHost,而当取值为1的时候,所有的写请求会随机发送到配置的writeHost定义的写数据库服务器上执行。MySQL pxc集群推荐1,默认为0
    dbType:mysql,sqlserver
    dbDriver:native/jdbc
    switchType:写数据库的高可用切换配置,1表示当每个writeHost不可用时自动切换到第二个writeHost,-1表示关闭自动切换,如果采用了一主多从的架构并且采用了MHA或者3M这样的主从复制的高可用管理工具,这里就需要在MyCAT中关闭切换的功能。
    
-->
<dataHost name="MySQLDataHost"  maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
<!-- 
MyCAT对后端数据库检测心跳连接 检测后端数据库是否可用 SQL需要足够简单,否则影响性能
-->
        <heartbeat>select user()</heartbeat>
        <!--MySQL 一主多从配置 -->
        <!--
            写请求的数据库服务器(Master)
            host表示主机名称
            url表示ip:port
            user:数据库的用户名
            password:数据库的密码
        -->
        <writeHost host="MySQLMaster" url="127.0.0.1:3306" user="root" password="root">
        <!--读请求 -->
            <readHost host="" url="" user="" password="" ></readHost>
            <readHost host="" url="" user="" password="" ></readHost>

        </writeHost>		  
    </dataHost>




































以上是关于现代Java服务端开发核心技术之分布式数据库中间件MyCAT入门的主要内容,如果未能解决你的问题,请参考以下文章

现代Java服务端开发核心技术之Java基础项目搭建

现代Java服务端开发核心技术之Java基础项目搭建

现代Java服务端开发核心技术之开发工具箱

现代Java服务端开发核心技术之开发工具箱

现代Java服务端开发核心技术之开发工具箱

现代Java服务端开发核心技术之开发工具箱