基本原理
mycat是一个把自己伪装成mysql服务的中间件,推荐阅读Mycat权威指南官方下载:下载地址
安装
下载安装包解压即用 点击我下载
,下载对应的版本:Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
,建议安装在 usr/local/mycat
,解压到当前目录,目录结构:
bin catlet conf lib logs version.txt
环境变量配置MYCAT_HOME,vim /etc/profile
添加 MYCAT_HOME=/usr/local/mycat
运行
linux:
./mycat start 启动
./mycat stop 停止
./mycat console 前台运行
./mycat restart 重启服务
./mycat pause 暂停
./mycat status 查看启动状态
windows:
startup_nowrap.bat
基本配置:
启动需要配置一些jvm 参数,这个根据系统的需要来设置,打开conf/wrapper.conf文件,里面有一些我们平时常用的jvm参数,一般只要调整Xmx、Xms、MaxDirectMemorySize 内存大小就可以, JVM 参数,必须设置-
XX:MaxDirectMemorySize 和 -Xmx
例如:-Xmx1024m -Xmn512m -XX:MaxDirectMemorySize=2048m -Xss256K -XX:+UseParallelGC了, MaxDirectMemorySize 尽可能设置大些,可以加快结果集处理时间
# Java Additional Parameters
wrapper.java.additional.1=-DMYCAT_HOME=.
wrapper.java.additional.2=-server
wrapper.java.additional.3=-XX:MaxPermSize=64M
wrapper.java.additional.4=-XX:+AggressiveOpts
wrapper.java.additional.5=-XX:MaxDirectMemorySize=2G
wrapper.java.additional.6=-Dcom.sun.management.jmxremote
wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984
wrapper.java.additional.8=-Dcom.sun.management.jmxremote.authenticate=false
wrapper.java.additional.9=-Dcom.sun.management.jmxremote.ssl=false
wrapper.java.additional.10=-Xmx1G
wrapper.java.additional.11=-Xmn512M
规则配置
Mycat最重要的3大配置文件:
- server.xml
主要有user 和 system 标签。
这个user标签主要用于定义登录 mycat的用户和权限。例如上面的例子中,我定 义了一个用户,用户名为 mycat、密码也为 mycat,可访问的 schema 也只有 TESTDB 一个。
如果我在 schema.xml 中定义了多个 schema,那么这个用户是无法访问其他的 schema。
mycat
TESTDB
同时访问多个 schema 的话使用 , 隔开,例如:
TESTDB,db1,db2
system
这个标签内嵌套的所有 property 标签都与系统配置有关,如果没有特殊需求默认即可
utf8
1
32
0
...
- schema.xml
文件地址
mycat/conf/schema.xml
,这个xml 是mycat配置的重头戏,里面有几个很关键的标签schema
table
dataNode
dataHost
等等。
首先配置schema
标签:table
:
schema标签中包含了table
属性,mycat中table有2种类型,一种是全局广播表,一种是分片表,如果没有在这里面配置的表呢,schema 标签有个dataNode
属性,没有配置默认读写在这个库里面,
table中还有一个属性subTables
,是指把一个表拆分成多个子表,例如下面表示有3个表 t_order1,t_order2,t_order3
subTables="t_order$1-2,t_order3"
目前分表 1.6 以后开始支持 并且 dataNode 在分表条件下只能配置一个,分表条件下不支持各种条件的 join 语句, 这种适合单个数据库需要分表的情况。
dataNode
: 标签定义了 MyCat 中的数据节点,也就是我们通常说所的数据分片。一个 dataNode 标签就是 一个独立的数据分片
dataHost
: 该标签在 mycat 逻辑库中也是作为最底层的标签存在,直接定义了具 体的数据库实例、读写分离配置和心跳语句。writeHost
标签、readHost
标签, writeHost 指 定写实例、readHost 指定读实例, 用来做读写分离。
select user()
select user()
- rule.xml
/usr/local/mycat/conf/rule.xml
这个标签定义表规则,这个文件里面主要有 tableRule 和 function 这两个标签。
tableRule标签中的 name 对应上面table标签中的rule 属性,columns 内指定要拆分的列名字。
algorithm 使用 function 标签中的 name 属性。
id
func1
name 指定算法的名字。
class 制定路由算法具体的类名字。
partition-hash-int.txt
Mycat 常用的分片规则
这个是本次分库分表的核心所在,直接影响到后续的sql执行效率,所以在分片规则的选择上,需要对表有比较清楚的认识
1. 分片枚举
通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省 份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则
user_id hash-int
partition-hash-int.txt 0
0
partition-hash-int.txt 配置:
10000=0
10010=1
DEFAULT_NODE=1
其中分片函数配置中,mapFile 标识配置文件名称,type 默认值为 0,0 表示 Integer,非零表示 String, 所有的节点配置都是从 0 开始,及 0 代表节点 1
/**
- defaultNode 默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点 * 默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点
- 如果不配置默认节点(defaultNode 值小于 0 表示不配置默认节点),碰到
- 不识别的枚举值就会报错,
- like this:can’t find datanode for sharding column:column_nameval:ffffffff */
2. 固定分片 hash 算法
本条规则类似于十进制的求模运算,区别在于是二进制的操作,是取 id 的二进制低 10 位,即 id 二进制 &1111111111。
此算法的优点在于如果按照 10 进制取模运算,在连续插入 1-10 时候 1-10 会被分到 1-10 个分片,增 大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减少插入事务事务控制难度。
user_id func1
2,1
256,512
分区长度:默认为最大 2^n=1024 ,即最大支持 1024 分区 约束:
count,length 两个数组的长度必须是一致的。
1024 = sum((count[i]*length[i])). count 和 length 两个向量的点积恒等于 1024 ,例如: 2*256 + 1*512 = 1024
。
例如:
以上分为二个分区:0-512,512-1023
1023的二进制&1111111111运算后为1023,故落入第二个分区
1024的二进制&1111111111运算后为0,故落入第一个分区
0266 的二进制&1111111111运算后为266,故落入第一个分区内
如果只需要平局分配,配置如下
4
256
3. 范围约定
此分片适用于,提前规划好分片字段某个范围属于哪个分片
user_id
rang-long
autopartition-long.txt
0
rang-long 函数中 mapFile 代表配置文件路径
defaultNode 超过范围后的默认节点。
所有的节点配置都是从 0 开始,及 0 代表节点 1,此配置非常简单,即预先制定可能的 id 范围到某个分片
0-500M=0
500M-1000M=1
1000M-1500M=2
或
0-10000000=0
10000001-20000000=1
4. 取 模
此种配置非常明确即根据 id 进行十进制求模预算,相比固定分片 hash,此种在批量插入时可能存在批量插入单 事务插入多数据分片,增大事务一致性难度。
user_id mod-long
2
- 按日期(天)分片
按天分片
create_time
sharding-by-date
yyyy-MM-dd
2014-01-01
2014-01-02
10
配置说明:
dateFormat :日期格式
sBeginDate :开始日期
sEndDate:结束日期
sPartionDay :分区天数,即默认从开始日期算起,分隔 10 天一个分区
如果配置了 sEndDate 则代表数据达到了这个日期的分片后后循环从开始分片插入
- 取模范围约束
- 截取数字做 hash 求模范围约束
- 应用指定
9. 截取数字 hash 解析
该方法适合那种拆分键是字符串的,每个字符的二进制unicode值换算出一个长整型数值,然后就直接调用内置hash算法求解分片路由:先求模得到逻辑分片号,再根据逻辑分片号直接映射到物理分片。
user_id sharding-by-stringhash
512
2
0:2
partitionCount 表示分区数,
partitionCount * partitionLength = 1024
hashSlice 表示你要截图的字符串
hashSlice : 0 means str.length(), -1 means str.length()-1
大于0只代表数字自身可以理解为substring(start,end),start为0则只表示0。例1:值“45abc”,hash预算位0:2 ,取其中45进行计算
例2:值“aaaabbb2345”,hash预算位-4:0 ,取其中2345进行计算。
- 一致性 hash
- 按单月小时拆分
....
规则源码:有兴趣可以看下 github 规则源码
日志排查
设置 conf/log4j2.xml
,设置mycat 日志地址
后面可以在logs 中查看mycat.log 文件