Mycat理论基础与配置详解

Mycat简介

Mycat是一个实现了MySQL协议的Server,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而后端可以用MySQL原生协议或JDBC协议与多个MySQL服务器通信,其核心功能是分库分表和读写分离,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或其他数据库里。

官网:http://www.mycat.org.cn/mycat1.html

Mycat核心概念

  1. 逻辑库

对数据进行分片处理之后,从原来的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。Mycat在操作时,使用逻辑库来代表数据库集群,便于对整个集群操作。

  1. 逻辑表

类似逻辑库

  1. 分片表

分片表,是指那些数据量很大,需要切分到多个数据库的表。每个分片都有一部分数据。如下mycat配置中的t_node就属于分片表,数据按照规则被分到dn1,dn2两个分片节点上。

<table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1,dn2"
rule="rule1" />
  1. 非分片表

就是那些不需要进行数据切分的表。如下配置t_node,只存在dn1分片节点上。

<table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1" />
  1. ER表

Mycat提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组保证数据join不会跨库操作。

  1. 全局表

一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动,字典表具有下面几个特性:

  • 变动不频繁
  • 数据量总体变化不大
  • 数据规模不大,很少超过数十万条记录

业务表与这些字典表之间的关联查询,会比较麻烦。所以Mycat通过数据冗余来解决,即所有分片都有一份字典表的拷贝,所有字典表或者符合字典表特性的一些表定义为全局表。

  1. 分片节点

数据分片后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点dataNode。

  1. 节点主机

数据切分后,每个分片节点不一定都会独占一台机器,同一个机器上面可以有多个分片数据库,这样一个或多个分片节点所在的机器就是节点主机,为了规避单节点主机并发数限制,尽量将读写压力高的分片节点均衡的放在不同的节点主机dataHost。

  1. 分片规则

数据在进行切分的时候需要一定的规则,这种按照业务规则把数据分到某个分片的规则就是分片规则。

配置文件解析

1. server.xml配置

server.xml主要是系统配置信息

1.1 user标签

这个标签主要定义登录mycat的用户和权限。例如下面的例子中,我们定义了一个用户,用户名为user,密码也为user,可访问的schema为lg_edu_order。

<user name="user">
    <property name="password">user</property>
    <property name="schemas">lg_edu_order</property>
    <property name="readOnly">true</property>
    <property name="defaultSchema">lg_edu_order</property>
</user>

1.2 firewall标签

<firewall>
    <!-- ip白名单 用户对应的可以访问的 ip 地址 -->
    <whitehost>
        <host host="127.0.0.*" user="root"/>
        <host host="127.0.*" user="root"/>
        <host host="127.*" user="root"/>
        <host host="1*7.*" user="root"/>
    </whitehost>
    <!-- 黑名单允许的 权限 后面为默认 -->
    <blacklist check="true">
        <property name="selelctAllow">false</property>
        <property name="selelctIntoAllow">false</property>
        <property name="updateAllow">false</property>
        <property name="insertAllow">false</property>
        <property name="deletetAllow">false</property>
        <property name="dropAllow">false</property>
    </blacklist>
</firewall>

1.3 全局序列号

在实现了分库分表的情况下,数据库自增主键无法保证主键的全局唯一。为此Mycat提供了全局sequence,并提供了包含本地配置和数据库配置等多种实现方式。

<system>
<property name="sequnceHandlerType">0</property>
</system>

0表示使用本地文件方式;1表示使用数据库方式生成;2表示使用本地时间戳方式;3表示基于ZK与本地配置的分布式ID生成器;4表示使用zookeeper递增方式生成

1.3.1 本地文件

此种方式Mycat将sequence配置到文件中,当使用到sequence中的配置后,Mycat会更新文件中的当前值。

#default global sequence
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000
# self define sequence
COMPANY.HISIDS=
COMPANY.MINID=1001
COMPANY.MAXID=2000
COMPANY.CURID=1000
ORDER.HISIDS=
ORDER.MINID=1001
ORDER.MAXID=2000
ORDER.CURID=1000

1.3.2 数据库方式

在数据库中建立一张表,存放sequence名称(name),sequence当前值(current_value),步长(increment) 等信息。

CREATE TABLE MYCAT_SEQUENCE
(
name VARCHAR(64) NOT NULL,
current_value BIGINT(20) NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (name)
) ENGINE = InnoDB;

1.3.3 本地时间戳

ID为64位二进制,42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)换算成十进制为18位数的long类型,每毫秒可以并发12位二进制的累加。

在Mycat下配置sequence_time_conf.properties文件

WORKID=0-31 任意整数
DATAACENTERID=0-31 任意整数

每个Mycat配置的WORKID、DATAACENTERID不同,组成唯一标识,总共支持32*32=1024种组合。

1.3.4 分布式ZK ID生成器

ZK的连接信息统一在myid.properties的zkURL属性中配置。基于ZK与本地配置的分布式ID生成器,InstanceID可以通过ZK自动获取,也可以通过配置文件配置。在sequence_distributed_conf.properties,只要配置INSTANCEID=ZK就表示从ZK上获取 InstanceID。

ID 最大为63位二进制,可以承受单机房单机器单线程 1000*(2^6)=640000 的并发。结构如下

  • current time millis(微秒时间戳 38 位,可以使用 17 年)
  • clusterId(机房或者 ZKid,通过配置文件配置,5 位)
  • instanceId(实例 ID,可以通过 ZK 或者配置文件获取,5 位)
  • threadId(线程 ID,9 位)
  • increment(自增,6 位)

1.3.5 ZK递增方式

ZK的连接信息统一在myid.properties的zkURL属性中配置。需要配置sequence_conf.properties文件

  • TABLE.MINID 某线程当前区间内最小值
  • TABLE.MAXID 某线程当前区间内最大值
  • TABLE.CURID 某线程当前区间内当前值

2. schema.xml配置

schema.xml作为Mycat中重要的配置文件之一,管理着Mycat的逻辑库、表、分片节点、主机等信息。

2.1 schema标签

schema标签用于定义Mycat实例中的逻辑库,Mycat可以有多个逻辑库,每个逻辑库都有自己相关配置。可以使用schema标签来划分这些不同的逻辑库。

<!-- 逻辑库 -->
<schema name="lg_edu_order" checkSQLschema="true" sqlMaxLimit="100"
dataNode="dn1"></schema>
属性名 类型 说明
dataNode String 分片节点
sqlMaxLimit Integer 查询返回记录数限制
checkSQLschema boolean 是否去表库名

2.2 table标签

table标签定义了Mycat中的逻辑表,所有需要拆分的表都需要在这个标签中定义

<table name="b_order" dataNode="dn1,dn2" rule="b_order_rule" primaryKey="ID"
autoIncrement="true"/>
属性名 类型 说明
name String 逻辑表名
dataNode String 分片节点
rule String 分片规则
ruleRequired boolean 是否强制绑定分片规则
primaryKey String 主键
type String 逻辑表类型,全局表、普通表
autoIncrement boolean 自增长主键
subTables String 分表
needAddLimit boolean 是否为查询SQL自动加limit限制

2.3 dataNode标签

dataNode标签定义了Mycat中的分片节点,也就是我们通常所说的数据分片。

<!-- 数据节点 -->
<dataNode name="dn1" dataHost="lg_edu_order_1" database="lg_edu_order_1" />
属性名 类型 说明
name String 数据节点名称,这个名称需要是唯一的
dataHost String 用于定义分片属于哪个分片主机,属性值是引用 dataHost标签上定义的name属性。
database String 用于定义该分片节点属于哪个具体的库

2.4 dataHost标签

dataHost标签在Mycat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。

<dataHost name="lg_edu_order_1" maxCon="100" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
</dataHost>
属性名 类型 说明
name String 节点主机名
maxCon Integer 最大连接数
minCon Integer 最小连接数
balance Integer 读操作负载均衡类型,0:所有读操作发送到当前可用的writeHost;1:所有读操作发送到readHost和stand by writeHost;2:所有读操作发送到writeHost和readHost;3:所有读操作发送到writeHost对应的readHost上,但是writeHost不参与读
writeType Integer 写操作负载均衡类型,0:所有写操作发送到writeHost;1:所有写操作发送到readHost;2:所有写操作发送到readHost和writeHost
dbType String 数据库类型
dbDriver String 数据库驱动
switchType String 主从切换类型,-1:表示不自动切换;1:表示自动切换;2:基于mysql主从同步状态决定是否切换;3:基于Mysql cluster集群切换机制

2.5 heartbeat标签

指明心跳检查的语句

<dataHost>
<heartbeat>select user()</heartbeat>
</dataHost>

2.6 writeHost和readHost标签

writeHost和readHost标签都指定后端数据库的相关配置给Mycat,用于实例化后端连接池。唯一不同的是,writeHost指定写实例、readHos指定读实例。在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去。

<writeHost host="M1" url="192.168.95.133:3306" user="root" password="1234">
</writeHost>
属性名 类型 说明
host String 主机名
url String 连接字符串
password String 密码
user String 用户名
weight String 权重
usingDecrypt String 是否对密码加密,默认0

3. rule.xml配置

rule.xml用于定义分片规则

3.1 tableRule标签

<tableRule name="c_order_rule">
<rule>
<columns>user_id</columns>
<algorithm>partitionByOrderFunc</algorithm>
</rule>
</tableRule>
属性名 类型 说明
name String 表规则名称
columns String 要拆分的列名
algorithm String 使用function标签中的name属性,连接表规则和具体路由算法

3.2 function标签

<function name="partitionByOrderFunc"
class="io.mycat.route.function.PartitionByMod">
<property name="count">2</property>
</function>
属性名 类型 说明
name String 算法的名称
class String 指定路由算法具体的类名字
property String 具体算法中需要用到的一些属性
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章