共计 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,支持跨库 2 表 join,甚至基于 caltlet 的多表 join。支持通过全局表,ER 关系的分片策略,实现了高效的多表 join 查询。支持多租户方案。支持分布式事务(弱 xa)。支持 XA 分布式事务(1.6.5)。支持全局序列号,解决分布式下的主键生成问题。分片规则丰富,插件化开发,易于扩展。强大的 web,命令行监控。...
centos7 安装下载 mycat
-
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 -
前期准备
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…,违者必究 …