上一篇文章讲到了mycat的安装和配置,相信验证过的朋友已经知道了,上一篇的做法已经实现了主从复制与读写分离的效果,这里给大家详细说以下读写分离部分:我的架构还是双主双从架构:(试验环境1主一从)效果
上一篇文章讲到了mycat的安装和配置,相信验证过的朋友已经知道了,上一篇的做法已经实现了主从复制与读写分离的效果,这里给大家详细说以下读写分离部分:
我的架构还是双主双从架构:(试验环境1主一从)效果一样,就是加几个配置的事情,和上一篇一样希望读完整篇文挡,中间出现的错误点后边有说明:
服务器 | IP | 说明 |
---|---|---|
Mycat | 192.168.0.2 | mycat服务器,连接数据库时,连接此服务器 |
database1 | 192.168.0.3 | 物理数据库1,真正存储数据的数据库 |
database2 | 192.168.0.4 | 物理数据库2,真正存储数据的数据库 |
Mycat作为主数据库中间件,肯定是与代码弱关联的,所以代码是不用修改的,使用Mycat后,连接数据库是不变的,默认端口是8066。连接方式和普通数据库一样,如:jdbc:mysql://192.168.0.2:8066/
server.
示例
<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. |
--privileges | 配置用户针对表的增删改查的权限,具体见文档吧 |
我这里配置了一个账号test 密码也是test,针对数据库lunch,读写权限都有,没有针对表做任何特殊的权限。
schema. 每个节点的属性逐一说明: schema: table: dataNode dataHost 配置如下: 我在192.168.0.2、192.168.0.3均有数据库lunch。 配置如下: 这样的配置与前一个示例配置改动如下: 注意:Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost,这个问题当时候我纠结了好久,数据写入writehost后,readhost一直没有数据,以为是自己配置的问题,后面才发现Mycat就没有实现主从复制的功能,毕竟数据库本身自带的这个功能才是最高效稳定的。 至于其他的场景,如同时主从和分表分库也是支持的了,只要了解这个实现以后再去修改配置,都是可以实现的。而热备及故障专业官方推荐使用haproxy配合一起使用,大家可以试试。 Mycat的启动也很简单,启动命令在Bin目录: 如果在启动时发现异常,在logs目录中查看日志。 wrapper.log 为程序启动的日志,启动时的问题看这个 mycat.log 为脚本执行时的日志,SQL脚本执行报错后的具体错误内容,查看这个文件。mycat.log是最新的错误日志,历史日志会根据时间生成目录保存。 mycat启动后,执行命令不成功,可能实际上配置有错误,导致后面的命令没有很好的执行。 Mycat带来的最大好处就是使用是完全不用修改原有代码的,在mycat通过命令启动后,你只需要将数据库连接切换到Mycat的地址就可以了。如下面就可以进行连接了: 连接成功后可以执行sql脚本了。 Mycat还有一个管理的连接,端口号是9906. 连接后可以根据管理命令查看Mycat的运行情况,当然,喜欢UI管理方式的人,可以安装一个Mycat-Web来进行管理,有兴趣自行搜索。 简而言之,开发中使用Mycat和直接使用Mysql机会没有差别。 使用Mycat后总会遇到一些坑,我将自己遇到的一些问题在这里列一下,希望能与大家有共鸣: Mycat是不是配置以后,就能完全解决分表分库和读写分离问题? Mycat支持哪些数据库,其他平台如 .net、PHP能用吗? Mycat 非JAVA平台如 .net、PHP能用吗?
schema.<?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. dataNode 分片信息,也就是分库相关配置 dataHost 物理数据库,真正存储数据的数据库 属性 说明 name 逻辑数据库名,与server. checkSQLschema 数据库前缀相关设置,建议看文档,这里暂时设为folse sqlMaxLimit select 时默认的limit,避免查询全表 属性 说明 name 表名,物理数据库中表名 dataNode 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name primaryKey 主键字段名,自动生成主键时需要设置 autoIncrement 是否自增 rule 分片规则名,具体规则下文rule详细介绍 属性 说明 name 节点名,与table中dataNode对应 datahost 物理数据库名,与datahost中name对应 database 物理数据库中数据库名 属性 说明 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="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>
lunchmenu、restaurant、userlunch、users这些表都只写入节点dn1,也就是192.168.0.2这个服务,而dictionary写入了dn1、dn2两个节点,也就是192.168.0.2、192.168.0.3这两台服务器。分片的规则为:mod-long。
主要关注rule属性,rule属性的内容来源于rule.table中的rule属性对应的就是rule.<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>
数据库读写分离
<?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" /> </schema><!-- 分片配置 --> <dataNode name="dn1" dataHost="test1" database="lunch" /><!-- 物理数据库配置 --> <dataHost name="test1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user();</heartbeat> <writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="123456"> <readHost host="hostM1" url="192.168.0.3:3306" user="root" password="123456"> </readHost> </writeHost> </dataHost></mycat:schema>
删除了table分配的规则,以及datanode只有一个
datahost也只有一台,但是writehost总添加了readhost,balance改为1,表示读写分离。
以上配置达到的效果就是102.168.0.2为主库,192.168.0.3为从库。使用
##启动mycat start##停止mycat stop##重启mycat restart
mysql -h192.168.0.1 -P8806 -uroot -p123456
所以,可以直接通过sql管理工具(如:navicat、datagrip)连接,执行脚本。我一直用datagrip来进行日常简单的管理,这个很方便。 mysql -h192.168.0.1 -P9906 -uroot -p123456
常见问题
Mycat配合数据库本身的复制功能,可以解决读写分离的问题,但是针对分表分库的问题,不是完美的解决。或者说,至今为止,业界没有完美的解决方案。
分表分库写入能完美解决,但是,不能完美解决主要是联表查询的问题,Mycat支持两个表联表的查询,多余两个表的查询不支持。 其实,很多数据库中间件关于分表分库后查询的问题,都是需要自己实现的,而且节本都不支持联表查询,Mycat已经算做地非常先进了。
分表分库的后联表查询问题,大家通过合理数据库设计来避免。
官方说了,支持的数据库包括MySQL、SQL Server、Oracle、DB2、PostgreSQL 等主流数据库,很赞。
尽量用Mysql,我试过SQL Server,会有些小问题,因为部分语法有点差异。
可以用。这一点MyCat做的也很棒。