上回聊到了mycat的分库分表,大家到底知道什么是mycat吗?它的另一个重要功能读写分离又该怎么实现呢?下面就让小编为你说道说道。
Mycat是什么?
Mycat,是一个强大的数据库中间件,不仅仅可以用作读写分离、分表分库、容灾备份,还能用于多租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性,借助于即将发布的Mycat智能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表映射到不同存储引擎上,而整个应用的代码一行也不用改变。
Mycat实现原理是什么?
Mycat 的原理中最重要的一个动词是“拦截”,它会拦截用户发送过来的SQL语句,先对SQL语句做一些特定的分析:例如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
如何实现读写分离呢?
配置好Mycat最重要的三个配置文件,一切的一切都要靠它们,配置好它们就万事俱备了。
1. 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="root"> <property name="password">mysql</property> <property name="schemas">testdb</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="user"> <property name="password">user</property> <property name="schemas">TESTDB</property> <property name="readOnly">true</property> </user> --> </mycat:server>
2. schema.xml配置
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!-- 数据库配置,与server.xml中的数据库对应 --> <schema name="testdb" checkSQLschema="true" sqlMaxLimit="100"> <table name="travel_record" primaryKey="id" autoIncrement="true" dataNode="dn1"/> </schema> <!-- 分片配置 --> <dataNode name="dn1" dataHost="host1" database="testdb"/> <!-- <dataNode name="dn2" dataHost="host2" database="testdb"/> <dataNode name="dn3" dataHost="host3" database="testdb"/> --> <!-- 物理数据库配置 --> <dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user();</heartbeat> <writeHost host="M1" url="192.168.153.130:3306" user="root" password="mysql"> <readHost host="S1" url="192.168.153.131:3306" user="root" password="mysql"/> </writeHost> <writeHost host="M2" url="192.168.153.133:3306" user="root" password="mysql"/> </dataHost> <!-- <dataHost name="host2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user();</heartbeat> <writeHost host="M2" url="192.168.153.131:3306" user="root" password="mysql"/> </dataHost> <dataHost name="host3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user();</heartbeat> <writeHost host="M3" url="192.168.153.133:3306" user="root" password="mysql"/> </dataHost> --> </mycat:schema>
启动mycat前需要在130、131、133mysq服务中创建数据库,测试表:
--创建数据库 create database testdb; --使用当前数据库 use testdb; --创建测试表travel_record CREATE TABLE IF NOT EXISTS `travel_record`( `id` INT(11) NOT NULL AUTO_INCREMENT, `org_code` VARCHAR(20) NOT NULL, `org_name` VARCHAR(20) DEFAULT NULL, PRIMARY KEY ( `id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
再通过bin目录下mycat脚本启动,执行./mycat start。通过管理端9066端口查看数据源:mysql -uroot -pmysql -P9066 -h127.0.0.1(8066用于操作数据库)
1) 当balance=0时,不开启读写分离机制,所有读写操作都发送到当前的writeHost上。通过日志分析所有读写操作都发送到M1。
2) 当balance=1时,开启读写分离机制,所有读操作都发送到当前writeHost对应的readHost和备用的writeHost上,通过日志分析所有读操作都发送到S1、M2。
3) 当balance=2时,读操作发送到发送到每一个writeHost和readHost。
4) 当balavce=3时,读操作只发送到当前writeHost对应的readHost。
注:mycat不会负责任何数据同步问题,所以要提前配置好mysql的主从复制数据自动同步。因为M1、S1已配置mysql主从复制故可完成数据同步,若M2没有配置同M1的mysql的主从复制则没有数据写入即便其被定义为writeHost。
以上就是mycat读写分离的全部内容了,想了解Java常见问答更多详情的话,就请一直关注我们的网站吧。