文章目录
0、mycat的工作原理
- 拦截用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:
- 如分片分析、路由分析、读写分离分析、缓存分析等
- 然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
- 步骤
- mycat启动时,就生成了管理连接后端真实数据库的所有datasource
- 客户端系统只能连接mycat发送sql语句
- mycat接收到sql语句,执行各种计算,计算分片sql语句对应数据在哪个分片,计算读写分离,从这个分片主从结构中到哪个节点读/写,拿到了具体的数据源,获取连接发送sql语句
- 数据库拿到mycat执行的sql开始执行
mycat将数据库返回结果返回给客户端.
一、mycat的作用
- 由于数据量巨大需要分库分表
二、mycat的四个配置文件
1、server.xml
- 配置mycat连接信息
- 一些性能优化等管理信息
配置连接的信息
<user name="root">
<property name="password">123456</property>
<property name="schemas">itheima-news</property>
</user>
2、schema.xml
- 配置mycat的节点信息
- 配置mycat主机信息
- 配置分表策略
- 一些连接信息或者读写分离主机配置
1.1、定义数据节点:
<dataNode name="DNAP_0" dataHost="HOST0" database="app_info_0" />
- name:数据节点名称
- dataHost:主机名称 跟dataHost name="HOST0"标签 name值对应
- database:节点的数据库名
1.2、定义主机节点:
<dataHost name="HOST0" maxCon="600" minCon="200" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="HOST0_M" url="47.94.7.85:3306" user="root" password="root"/>
</dataHost>
- name:主机节点名称
- minCon:最小连接线程
- maxCon:最大连接线程
- balance:负载均衡策略
- writeHost 该标签配置节点对应的mysql主机
1.3、定义表信息:
<table name="ap_article" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40"/>
- name:数据库表名
- dataNode:该表在那些数据节点设置了分片
- autoIncrement:是否自增,如果设置为true,需要在sequence_db_conf.properties文件配置自增相关数据。
- rule:分片策略 mod-long40表示 主键求余40
1.3、连接信息或者读写分离主机配置
3、rule.xml
该文件主要定义分表策略:
示例:
主键求余策略:
- 配置 function class指定分片算法 本例为求余算法
- 配置 tableRule 设置对那个字段执行分片操作 本例为id对40求余
<function name="mod-long40" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">40</property>
</function>
<tableRule name="mod-long40">
<rule>
<columns>id</columns>
<algorithm>mod-long40</algorithm>
</rule>
</tableRule>
4、sequence_db_conf.properties
该文件为全局自增主键配置对于table定义了autoIncrement=“true” primaryKey="id"的表,需要配置全局自增序号(注意全大写)。
AP_ARTICLE=DNSQ
同时在DNSQ也就是app_seq表里插入一条记录:
INSERT INTO `app_seq`.`MYCAT_SEQUENCE` (`name`, `current_value`, `increment`) VALUES ('ap_article', '1000', '1000');
- current_value:为初始值
- increment:为每次获取序列的自增值,该值的数据根据对应表的数据新增速率设置。
三、mycat的集成
1、导入依赖、配置连接
- mycat的默认端口号为——
8066
2、自定分片算法
- 导入依赖
- 将mycat的自定义的四个主要配置文件copy到mycat模块中的config包下
- 设计算法
算法设计
在项目中分片字段规范命名为burst,类型为String,值格式为dataId-分表ID,dataId用于分组ID计算,为数据量提供扩展性;分表ID用于组内表的分配,其分片公式如下:
分片ID = *(dataId/volume) step +分表ID/mod **
-
Volume是每组分片的数据容量
-
Step是每组分片的DateNode数量
-
Mode是表在每组分片中的节点数量
算法实现
实现步骤如下:
-
创建类文件:com.heima.HeiMaBurstRuleAlgorithm
-
修改类继承AbstractPartitionAlgorithm 和实现RuleAlgorithm接口
-
在类中定义volume、step、mod三个变量,并提供set方法
-
实现calculate 等值分片DN计算方法(参数是burst值)
-
实现calculateRange范围分片DN计算方法(参数是burst值)
完整代码如下:
/**
* 自定义多字段算法计算
*/
public class HeiMaBurstRuleAlgorithm extends AbstractPartitionAlgorithm implements RuleAlgorithm {
// 单组数据容量
Long volume;
// 单组DN节点数量
Integer step;
// 分片模
Integer mod;
public void init(){}
/**
*
* @param columnValue 数据ID-桶ID
* @return
*/
public Integer calculate(String columnValue){
if(columnValue!=null){
String[] temp = columnValue.split("-");
if(temp.length==2){
try {
Long dataId = Long.valueOf(temp[0]);
Long burstId = Long.valueOf(temp[1]);
int group = (int)(dataId/volume)*step;
int pos = group + (int)(burstId%mod);
System.out.println("HEIMA RULE INFO ["+columnValue+"]-[{"+pos+"}]");
return pos;
}catch (Exception e){
System.out.println("HEIMA RULE INFO ["+columnValue+"]-[{"+e.getMessage()+"}]");
}
}
}
return 0;
}
/**
* 范围计算
* @param beginValue
* @param endValue
* @return
*/
public Integer[] calculateRange(String beginValue, String endValue){
if(beginValue!=null&&endValue!=null){
Integer begin = calculate(beginValue);
Integer end = calculate(endValue);
if(begin == null || end == null){
return new Integer[0];
}
if (end >= begin) {
int len = end - begin + 1;
Integer[] re = new Integer[len];
for (int i = 0; i < len; i++) {
re[i] = begin + i;
}
return re;
}
}
return new Integer[0];
}
public void setVolume(Long volume) {
this.volume = volume;
}
public void setStep(Integer step) {
this.step = step;
}
public void setMod(Integer mod) {
this.mod = mod;
}
}
算法的应用
- service-mycat/config/rule.xml
Burst5050单组有50个DN,单组容量为5亿,分50张表,每个DN上存储一张对应表;其定义在service-mycat/config/rule.xml中,定义代码为:
<tableRule name="burst5050">
<rule>
<columns>burst</columns>
<algorithm>burst5050</algorithm>
</rule>
</tableRule>
<function name="burst5050" class="com.heima.HeiMaBurstRuleAlgorithm">
<property name="volume">500000000</property><!-- 单组容量 -->
<property name="step">50</property><!-- 单组节点量 -->
<property name="mod">50</property><!-- 单组数据mod -->
</function>
- service-mycat/config/schema.xml
- 在service-mycat/config/schema.xml中,可使用以上定义的规则,示例如下:
<table name="ap_behavior_entry" dataNode="DNBE_$0-49" rule="burst5050"/>
- service-mycat/config/sequence_db_conf.properties
在service-mycat/config/sequence_db_conf.properties中去掉对应表的sequence配置:
AP_BEHAVIOR_ENTRY=...
AP_COLLECTION=...
算法部署
- 进入到项目service-mycat项目根路径,运行mvn clean package打包命令打包项目
- 拷贝service-mycat/config下的文件到mycat安装目录下的config文件夹下
- 拷贝service-mycat/target/ service-mycat-1.0-SNAPSHOT.jar文件到mycat安装目录lib文件夹下
- 重启mycat服务