mycat
1.下载地址
:https://github.com/MyCATApache/Mycat-Server
2.大部分的安装和原理讲解已经很成熟了.这里也不再抄了,可参考:https://blog.51cto.com/u_15780455/6245373[linux安装]
window本地进行使用的时候,可以直接下载工程然后再idea中进行配置调试.也方便学习和试错
3.重点配置如下:
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> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户--> <property name="nonePasswordLogin">0</property> <!-- 0遇上没有实现的报文(Unknown command:),就会报错、1为忽略该报文,返回ok报文。 在某些mysql客户端存在客户端已经登录的时候还会继续发送登录报文,mycat会报错,该设置可以绕过这个错误--> <property name="ignoreUnknownCommand">0</property> <!--是否使用HandshakeV10Packet来与client进行通讯, 1:是 , 0:否(使用HandshakePacket) 使用HandshakeV10Packet为的是兼容高版本的jdbc驱动, 后期稳定下来考虑全部采用HandshakeV10Packet来通讯 这里需要配置为1,选择使用V10,否则在登录mycat的时候,提示密码错误。 ERROR 1045 (HY000): Access denied for user 'mycat', because password is error --> <property name="useHandshakeV10">1</property> <!-- default:1:mycat在处理SQL上,将不会发生移除SQL中``对关键字转义 --> <property name="removeGraveAccent">1</property> <!-- 1为开启实时统计、0为关闭 --> <property name="useSqlStat">1</property> <!-- 是否开启全局表的一致性检测。1为开启 ,0为关闭 。 --> <property name="useGlobleTableCheck">0</property> <!-- SQL 执行超时 单位:秒--> <property name="sqlExecuteTimeout">300</property> <!-- 用来指定Mycat全局序列类型,0 为本地文件,1 为数据库方式,2 为时间戳列方式,默认使用本地文件方式,文件方式主要用于测试 --> <property name="sequenceHandlerType">1</property> <!--<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property> INSERT INTO `travelrecord` (`id`,user_id) VALUES ('next value for MYCATSEQ_GLOBAL',"xxx"); --> <!--必须带有MYCATSEQ_或者 mycatseq_进入序列匹配流程 注意MYCATSEQ_有空格的情况--> <property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false --> <property name="subqueryRelationshipCheck">false</property> <property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property> <!--1为开启mysql压缩协议--> <property name="useCompression">1</property> <!--设置模拟的MySQL版本号--> <!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!-- 指定每次分配Socket Direct Buffer默认值为4096字节, 也会影响BufferPool长度, 如果一次性获取字节过多而导致buffer不够用, 则会出现警告, 可以调大该值 --> <!-- <property name="processorBufferChunk">40960</property> --> <!-- 指定系统可用的线程数量, 默认值为CPU核心 x 每个核心运行线程数量; processors 会影响 processorBufferPool, processorBufferLocalPercent, processorExecutor属性, 所有, 在性能调优时, 可以适当地修改processors值 --> <property name="processors">16</property> <!-- 指定NIOProcessor上共享 businessExecutor固定线程池的大小; MyCat把异步任务交给 businessExecutor线程池中, 在新版本的MyCat中这个连接池使用频次不高, 可以适当地把该值调小 --> <property name="processorExecutor">32</property> <!--指定的缓存类:默认为type 0: DirectByteBufferPool[堆外内存] | type 1 ByteBufferArena | type 2 NettyBufferPool --> <property name="processorBufferPoolType">0</property> <!--默认是65535 64K 用于sql解析时最大文本长度 --> <property name="maxStringLiteralLength">65535</property> <!--<property name="sequenceHandlerType">0</property>--> <!--<property name="backSocketNoDelay">1</property>--> <!--<property name="frontSocketNoDelay">1</property>--> <!--<property name="processorExecutor">16</property>--> <!-- mycat提供访问服务使用的端口 --> <property name="serverPort">8066</property> <!-- mycat管理端使用的端口 --> <property name="managerPort">9066</property> <!-- 指定连接的空闲时间的超时长度;如果超时,将关闭资源并回收, ms --> <property name="idleTimeout">300000</property> <!-- --> <property name="authTimeout">15000</property> <property name="bindIp">0.0.0.0</property> <!-- 5 * 60 * 1000L; //连接空闲检查 --> <property name="dataNodeIdleCheckPeriod">300000</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">0</property> <!-- 单位为m --> <property name="memoryPageSize">64k</property> <!-- 单位为k --> <property name="spillsFileBufferSize">1k</property> <property name="useStreamOutput">0</property> <!-- 单位为m--> <property name="systemReserveMemorySize">384m</property> <!--是否采用zookeeper协调切换 --> <property name="useZKSwitch">false</property> <!-- XA Recovery Log日志路径 --> <!--<property name="XARecoveryLogBaseDir">./</property>--> <!-- XA Recovery Log日志名称 --> <!--<property name="XARecoveryLogBaseName">tmlog</property>--> <!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接--> <property name="strictTxIsolation">true</property> <!--如果为0的话,涉及多个DataNode的catlet任务不会跨线程执行--> <property name="parallExecute">0</property> <property name="serverBacklog">2048</property> </system> <!-- 全局SQL防火墙设置 --> <!--白名单可以使用通配符%或着*--> <!--例如<host host="127.0.0.*" user="root"/>--> <!--例如<host host="127.0.*" user="root"/>--> <!--例如<host host="127.*" user="root"/>--> <!--例如<host host="1*7.*" user="root"/>--> <!--这些配置情况下对于127.0.0.1都能以root账户登录--> <!-- firewall标签用来定义防火墙;firewall下whitehost标签用来定义 IP白名单 ,blacklist用来定义 SQL黑名单。 详细可用参数可见:https://blog.csdn.net/qq_43753724/article/details/120619779 --> <firewall> <whitehost> <host host="1*7.0.0.*" user="root"/> </whitehost> <blacklist check="false"> <property name="selelctAllow">false</property> </blacklist> </firewall> <!-- 默认账户 --> <user name="root" defaultAccount="true"> <property name="password">root</property> <property name="schemas">db_consumer1</property> <!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 --> <property name="defaultSchema">db_consumer1</property> <!-- 表级 DML 权限设置 check表示是否开启DML权限检查。默认是关闭。 --> <privileges check="true"> <!-- privileges 的下级节点 schema 节点同样 可配置多个,对多库多表进行细粒度的 DML 权限控制; --> <schema name="db_consumer1" dml="1111" > <!-- 权限修饰符四位数字(0000 - 1111),对应的操作是 IUSD ( 增,改,查,删 ) <table name="t_sp" dml="1111"></table> <table name="tb" dml="1111"></table>--> </schema> </privileges> </user> </mycat:server>
schema.xml
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!-- name:自定义名字,对应server.xml中的schemas checkSQLschema:查询时是否增加库名称。如db1.table。false不加 sqlMaxLimit :一次最大读取行数 randomDataNode: --> <schema name="db_consumer1" checkSQLschema="false" sqlMaxLimit="1000" randomDataNode="db_consumer1" dataNode="db_consumer1"> <!-- plitTableNames 启用<table name 属性使用逗号分割配置多个表,即多个表使用这个配置 fetchStoreNodeByJdbc 启用ER表使用JDBC方式获取DataNode subTables:指定所有真实分表 primaryKey:主键字段 dataNode:数据库节点名 rule:数据分表规则,同rule.xml中保持一致 autoIncrement:自增 分表的情况下:可修改配置name="t_sp" 增加属性subTables="t_sp_$0-1" 但是此时dataNode只能配置一个 分库的情况下:增加属性subTables可不配置,name要配置准确的表名 dataNode可配置多个. --> <table name="t_sp_0" primaryKey="SP_ID" dataNode="db_consumer1,db_consumer2" rule="sp_split" autoIncrement="true" fetchStoreNodeByJdbc="true"> <!-- <childTable name="customer_addr" primaryKey="id" joinKey="customer_id" parentKey="id"> </childTable> --> </table> </schema> <!-- 数据库节点信息 name:节点名 dataHost:对应下面dataHost的名字,即:对应该数据库的登陆名、密码等设置 database:数据库名 --> <dataNode name="db_consumer1" dataHost="localhost1" database="cloudtravel_consumer1" /> <dataNode name="db_consumer2" dataHost="localhost1" database="cloudtravel_consumer2" /> <!-- 数据库节点信息 name: dataHost 标签唯一标识 ,供上层的标签使用 maxCon: 指定每个读写实例连接池的最大连接数。 minCon: 指定每个读写实例连接池的最小连接数。 balance: 负载均衡类型,目前的取值有4 种: “0”, 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。 “1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备), 正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。 ”2”,所有读操作都随机的在 writeHost、readhost 上分发。 ”3”,所有读请求随机的分发到wiriterHost 对应的 readhost 执行,writerHost 不负担读压 writeType 1. writeType=”0”:所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost, 重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties . 2. writeType=”1”,所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。默认0就好了! dbType:指定后端连接的数据库类型,目前支持二进制的 mysql 协议,还有其他使用 JDBC 连接的数据库。例如:mongodb、oracle、spark 等. dbDriver:数据库连接驱动,目前可选的值有 native 和 JDBC。 使用 native 的话,因为这个值执行的是二进制的 mysql 协议,所以可以使用 mysql 和 maridb。 其他类型的数据库则需要使用 JDBC 驱动来支持。 switchType: “-1” 表示不自动切换; “1” 默认值,自动切换; “2” 基于 MySQL 主从同步的状态决定是否切换心跳语句为 show slave status; “3” 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)心跳语句为 show status like ‘wsrep%’. slaveThreshold:switchType=2[主从同步]的时候,此时意味着开启 MySQL 主从复制状态绑定的读写分离与切换机制, Mycat 心跳 机 制 通 过 检 测 show slave status 中 的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master 主从复制时延, 当时,读写分离筛选器会过滤掉此 Slave 机器, 防止读到很久之前的旧数据,而当主节点宕机后,切换逻辑会检查 Slave 上的 Seconds_Behind_Master是否为 0,为 0 时则 表示主从同步,可以安全切换,否则不会切换。 --> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="hostM1" url="jdbc:mysql://127.0.0.1:3306" user="root" password="root"> <!--<readHost host="hostM2" url="127.0.0.1:3306" user="root" password="root" />--> </writeHost> </dataHost> </mycat:schema>
rule.xml没啥改动,需要自定义配置的话可以,参考原来的进行配置就好了.
mycat的缺点在于不支持又分库又分表,比如:a库:表1,表2 b库:表1,表2 . 这种形式的分库分表需要进行二次开发.
优点则是: 单一的分库/分表都配置简单,且中间件的方式当某个数据库挂掉,不需要去重启服务主机,只需要对mycat中间件进行修改调整就好了.
sharding-jdbc:则是需要在服务中引入相关的jar,在服务中进行开发.当然,其读写分离和分库分表的配置化也同样简单