
学会数据库读写分离、分表分库——用Mycat
系统开发中,数据库是非常重要的一个点。除了程序的本身的优化,如:SQL语句优化、代码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分库等都是系统发展迟早会遇到的技术问题问题。Mycat是一个广受好评的数据库中间件,已经在很多产品上进行使用了。希望通过这篇文章的介绍,能学会Mycat的使用。安装Mycat官网:http://www.mycat.io/可以了解下Mycat的背景和应用情况,这样使用起来比较有信心。Mycat下载地址:http://dl.mycat.io/官网有个文档,属于详细的介绍,初次入门,看起来比较花时间。下载:建议大家选择 1.6-RELEASE 版本,毕竟是比较稳定的版本。安装:根据不同的系统选择不同的版本。包括linux、windows、mac,作者考虑还是非常周全的,当然,也有源码版的。(ps:源码版的下载后,只要配置正确,就可以正常运行调试,这个赞一下。)Mycat的安装其实只要解压下载的目录就可以了,非常简单。安装完成后,目录如下:目录说明binmycat命令,启动、重启、停止等catletcatlet为Mycat的一个扩展功能confMycat 配置信息,重点关注libMycat引用的jar包,Mycat是java开发的logs日志文件,包括Mycat启动的日志和运行的日志。配置Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:文件说明server.xmlMycat的配置文件,设置账号、参数等schema.xmlMycat对应的物理数据库和数据库表的配置rule.xmlMycat分片(分库分表)规则Mycat的架构其实很好理解,Mycat是代理,Mycat后面就是物理数据库。和Web服务器的Nginx类似。对于使用者来说,访问的都是Mycat,不会接触到后端的数据库。我们现在做一个主从、读写分离,简单分表的示例。结构如下图:服务器IP说明Mycat192.168.0.2mycat服务器,连接数据库时,连接此服务器database1192.168.0.3物理数据库1,真正存储数据的数据库database2192.168.0.4物理数据库2,真正存储数据的数据库Mycat作为主数据库中间件,肯定是与代码弱关联的,所以代码是不用修改的,使用Mycat后,连接数据库是不变的,默认端口是8066。连接方式和普通数据库一样,如:jdbc:mysql://192.168.0.2:8066/server.xml示例<user name="test"><property name="password">test</property><property name="schemas">lunch</property><property name="readOnly">false</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登录的用户名,也就是连接Mycat的用户名--password登录的密码,也就是连接Mycat的密码--schemas数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,dbs--privileges配置用户针对表的增删改查的权限,具体见文档吧我这里配置了一个账号test 密码也是test,针对数据库lunch,读写权限都有,没有针对表做任何特殊的权限。schema.xmlschema.xml是最主要的配置项,首先看我的配置文件。<?xml version="1.0"?><!DOCTYPE mycat:schema SYSTEM "schema.dtd"><mycat:schema xmlns:mycat="http://io.mycat/"><!-- 数据库配置,与server.xml中的数据库对应 --><schema name="lunch" checkSQLschema="false" sqlMaxLimit="100"><table name="lunchmenu" dataNode="dn1" /><table name="restaurant" dataNode="dn1" /><table name="userlunch" dataNode="dn1" /><table name="users" dataNode="dn1" /><table name="dictionary" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long" /></schema><!-- 分片配置 --><dataNode name="dn1" dataHost="test1" database="lunch" /><dataNode name="dn2" dataHost="test2" database="lunch" /><!-- 物理数据库配置 --><dataHost name="test1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"><heartbeat>select user();</heartbeat><writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="123456"></writeHost></dataHost><dataHost name="test2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"><heartbeat>select user();</heartbeat><writeHost host="hostS1" url="192.168.0.3:3306" user="root" password="123456"></writeHost></dataHost></mycat:schema> 参数说明schema数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应dataNode分片信息,也就是分库相关配置dataHost物理数据库,真正存储数据的数据库每个节点的属性逐一说明:schema:属性说明name逻辑数据库名,与server.xml中的schema对应checkSQLschema数据库前缀相关设置,建议看文档,这里暂时设为folsesqlMaxLimitselect 时默认的limit,避免查询全表table:属性说明name表名,物理数据库中表名dataNode表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的nameprimaryKey主键字段名,自动生成主键时需要设置autoIncrement是否自增rule分片规则名,具体规则下文rule详细介绍dataNode属性说明name节点名,与table中dataNode对应datahost物理数据库名,与datahost中name对应database物理数据库中数据库名dataHost属性说明name物理数据库名,与dataNode中dataHost对应balance均衡负载的方式writeType写入方式dbType数据库类型heartbeat心跳检测语句,注意语句结尾的分号要加。应用场景数据库分表分库配置如下:<?xml version="1.0"?><!DOCTYPE mycat:schema SYSTEM "schema.dtd"><mycat:schema xmlns:mycat="http://io.mycat/"><!-- 数据库配置,与server.xml中的数据库对应 --><schema name="lunch" checkSQLschema="false" sqlMaxLimit="100"><table name="lunchmenu" dataNode="dn1" /><table name="restaurant" dataNode="dn1" /><table name="userlunch" dataNode="dn1" /><table name="users" dataNode="dn1" /><table name="dictionary" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long" /></schema><!-- 分片配置 --><dataNode name="dn1" dataHost="test1" database="lunch" /><dataNode name="dn2" dataHost="test2" database="lunch" /><!-- 物理数据库配置 --><dataHost name="test1" maxCon="1000" minCon="10" balance=&