前言
对于业务量越来越大的时候,单表数据超过几千万,甚至上亿时,一张表里面查询真的会很费时。而在分布式系统中,分表分库也是常用的一种解决此类瓶颈的手段。今天就选用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的连接,而不是真实数据库的连接...