springbootmycat-分表分库

69次阅读

共计 7742 个字符,预计需要花费 20 分钟才能阅读完成。

前言

对于业务量越来越大的时候,单表数据超过几千万,甚至上亿时,一张表里面查询真的会很费时。而在分布式系统中,分表分库也是常用的一种解决此类瓶颈的手段。今天就选用 springboot+mycat 简单聊下。mycat 官网:http://www.mycat.io/

  • 什么是 mycat?

    1. 一个彻底开源的,面向企业应用开发的大数据库集群
    2. 支持事务、ACID、可以替代 MySQL 的加强版数据库
    3. 一个可以视为 MySQL 集群的企业级数据库,用来替代昂贵的 Oracle 集群
    4. 一个融合内存缓存技术、NoSQL 技术、HDFS 大数据的新型 SQL Server
    5. 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
    6. 一个新颖的数据库中间件产品
  • 为什么要用 mycat?

    支持 MySQL、Oracle、DB2、SQL Server、PostgreSQL 等 DB 的常见 SQL 语法
    遵守 Mysql 原生协议,跨语言,跨平台,跨数据库的通用中间件代理
    基于心跳的自动故障切换,支持读写分离,支持 MySQL 主从,以及 galera cluster 集群。支持 Galera for MySQL 集群,Percona Cluster 或者 MariaDB cluster
    基于 Nio 实现,有效管理线程,解决高并发问题。支持数据的多片自动路由与聚合,支持 sum,count,max 等常用的聚合函数, 支持跨库分页。支持单库内部任意 join,支持跨库 2join,甚至基于 caltlet 的多表 join。支持通过全局表,ER 关系的分片策略,实现了高效的多表 join 查询。支持多租户方案。支持分布式事务(弱 xa)。支持 XA 分布式事务(1.6.5)。支持全局序列号,解决分布式下的主键生成问题。分片规则丰富,插件化开发,易于扩展。强大的 web,命令行监控。...

centos7 安装下载 mycat

  1. centos7 安装 mycat
    安装 mycat 比较简单,我这边也详细说明一下:

    #下载:wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
    #解压
    tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
    #授权
    chmod -R 777 mycat
    #环境变量添加:vi /etc/profile
    #在里面添加:export MYCAT_HOME=/crawler/mycat/mycat ## 自己的安装路径
    export PATH=$PATH:$MYCAT_HOME/bin
    #使环境变量生效
    source /etc/profile
    #注意:#Linux 下部署安装 MySQL,默认不忽略表名大小写,需要手动到 /etc/my.cnf 下配置:lower_case_table_names=1
  2. 前期准备
    ps:mycat 需要配置 java_home,就算安装了 java 如果没有配置 java_home. 还是会抛没有找到 java_home 的错,在此,我们检查一下有没有配置,若没有配置,请按以下步骤操作:

    A 确定 java 安装路径
    1. 终端输入:which java
    输出为:/usr/bin/java
    2. 终端输入:ls -lr /usr/bin/java
    输出为:/usr/bin/java ->
    3. 终端输入
    ls -lrt /etc/alternatives/java
    输出:/etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre/bin/java

至此,我们确定 java 的安装目录为:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64

B 配置 JAVA_HOME
1. 打开配置环境变量的文件
vi /etc/profile
2. 添加以下配置:export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
:wq 保存退出。3. 让配置生效
source /etc/profile
4. 测试配置结果
echo $JAVA_HOME

3. 配置关键配置

a: 配置 schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycatDatabase" checkSQLschema="false" sqlMaxLimit="100">
<table name="user" primaryKey="id" dataNode="dn01,dn02" rule="rule1" />
</schema>
<!-- 设置 dataNode 对应的数据库, 及 mycat 连接的地址 dataHost -->
<dataNode name="dn01" dataHost="dh01" database="db01" />
<dataNode name="dn02" dataHost="dh01" database="db02" />
<!-- mycat 逻辑主机 dataHost 对应的物理主机. 其中也设置对应的 mysql 登陆信息 -->
<dataHost name="dh01" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="server1" url="127.0.0.1:3306" user="root" password="这里是你的密码">
<!-- <readHost host="server1" url="cd-cdb-5p62gwp2.sql.tencentcdb.com:62918" user="root" password="123456"/> -->
</writeHost>
</dataHost>
</mycat:schema>

b: 配置 rule.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="rule1"> <!-- 这个 name 和 schema 里面对应 -->
<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>
</mycat:rule>

c: 配置 server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property> <!-- 1 为开启实时统计、0 为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1 为开启全加班一致性检测、0 为关闭 -->
<property name="sequnceHandlerType">2</property>
<!-- <property name="useCompression">1</property>--> <!-- 1 为开启 mysql 压缩协议 -->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!-- 设置模拟的 MySQL 版本号 -->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!-- 默认为 type 0: DirectByteBufferPool | type 1 ByteBufferArena-->
<property name="processorBufferPoolType">0</property>
<!-- 默认是 65535 64K 用于 sql 解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!-- 分布式事务开关,0 为不过滤分布式事务,1 为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2 为不过滤分布式事务, 但是记录分布式事务日志 -->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1 开启 0 关闭
-->
<property name="useOffHeapForMerge">1</property>
<!--
单位为 m
-->
<property name="memoryPageSize">1m</property>
<!--
单位为 k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为 m
-->
<property name="systemReserveMemorySize">384m</property>
<!-- 是否采用 zookeeper 协调切换 -->
<property name="useZKSwitch">true</property>
</system>
<!-- 全局 SQL 防火墙设置 -->
<!--
<firewall>
<whitehost>
<host host="127.0.0.1" user="mycat"/>
<host host="127.0.0.2" user="mycat"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="crawler"> <!-- 连接 mycat 的用户名 -->
<property name="password">123456</property> <!-- 连接 mycat 的密码 -->
<property name="schemas">mycatDatabase</property> <!-- 逻辑数据库名,这里会和 schema.xml 中的配置关联,多个用逗号分开 -->
<property name="readOnly">false</property>
</user>
</mycat:server>

此时,我们运行 mycat:mycat/bin/startup_nowrap.sh
如果是阿里云或者其他云服务器,需要把 mycat 的端口打开,默认端口是 8066
此时,我们可以看一下日志:
mycat/logs/..

若没什么问题,那么就可以在 springboot 上做集成了
ps:我们必须在上面所涉及到的地方建两个库哦:如上面我建的是 db01 db02

springboot 集成 mycat

spring:
datasource:
url: jdbc:mysql://www.iamcrawler.cn:8066/mycatDatabase?serverTimezone=Asia/Shanghai
username: crawler
password: 123456
driver-class-name: com.mysql.jdbc.Driver

service

/**
* create by liuliang
* on 2019-07-30 17:16
*/
@Service
public class MycatUserService extends ServiceImpl<MycatUserMapper, MycatUser> {public List<MycatUser> getUsers(){List<MycatUser> list = this.list(new QueryWrapper<>());
return list;
}
}

controller

/**
* create by liuliang
* on 2019-07-30 17:17
*/
@RestController
@RequestMapping("/mycat/user")
public class MyCatUserController {
@Autowired
private MycatUserService userService;
@PostMapping
public ResponseEntity insertUser(@RequestBody MycatUser mycatUser){return ResponseEntity.ok(userService.save(mycatUser));
}
@GetMapping
public ResponseEntity getUsers(){return ResponseEntity.ok(userService.getUsers());
}
}

调试:这个时候我们启动程序,先后插入两条数据:

localhost:9090/mycat/user post
{
"id":"10",
"name":"zhangsan"
}
localhost:9090/mycat/user post
{
"id":"11",
"name":"lisi"
}

数据库看的时候,发现已经进入了两个不同的库。
而我们查询的时候:

localhost:9090/mycat/user get
[
{
"id": 11,
"name": "lisi"
},
{
"id": 10,
"name": "zhangsan"
}
]

可以看到是,数据都查询出来了,mycat 分库生效

ps:如果各位有项目使用的是 liquibase,那么与 mycat 集成的时候会抛错,原因是因为 liquibase 需要简历 changelog 表,而使用的库是 mycatDatabase,这个是 mycat 的连接,而不是真实数据库的连接 …
github : https://github.com/iamcrawler…

最后,码字不易,转载复制请指明原创 https://segmentfault.com/a/11…,违者必究 …

正文完
 0