数据库路由中间件MyCat - 使用篇(4)
此文已由作者张镐薪授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
配置MyCat
3. 配置conf/rule.xml
1.5GA版本中的规则配置比较笨,2.0中优化了一些,将tableRule标签和function标签合并了,并且支持Velocity模板语言,更加灵活。这里先介绍1.5GA的,2.0等以后稳定了,会推的:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mycat:rule SYSTEM "rule.dtd"><mycat:rule xmlns:mycat="http://org.opencloudb/">
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">2</property>
</function></mycat:rule>
tableRule标签(多个表可以对应一个表规则)
name 属性指定唯一的名字,用于标识不同的表规则。
内嵌的rule标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。columns 内指定要拆分的列名字。
algorithm 使用function标签中的name属性。连接表规则和具体路由算法。当然,多个表规则可以连接到同一个路由算法上。
function标签
name 指定算法的名字。
class 制定路由算法具体的类名字。
property 为具体算法需要用到的一些属性。
上面的例子有一个表规则,对应一个算法,是MyCat1.5GA中内置的算法。我们也可以实现自己的算法。
这里配置文件实现的原理,其实就是反射,MyCat动态加载里面的规则,并动态设置class中的filed的值。
分片规则涉及到的类(算法实现类不完整)图:
RuleAlgorithm :路由规则接口抽象,规定了分片规则的初始化(init),路由分片计算(calculate),及路由多值分片计算(calculateRange)。
分片规则中calculate方法是基本的分片路由计算方法,根据分片字段值,计算出分片。
分片规则中calculateRange方法是范围查询时分片计算,即如果查询类似:
select * from t_user t where t.id<100;
需要解析出指定范围的所有值对应分片。
自定义的分片规则只需要继承AbstractPartitionAlgorithm,按照自己的规则初始化配置文件(即正在介绍的rule.xml),并且实现calculate或者calculateRange方法即可。
AbstractPartitionAlgorithm是一个抽象类,只实现了多值路由计算。并且,根据下面的代码我们可以了解到路由算法必须继承AbstractPartitionAlgorithm
AbstractPartitionAlgorithm.java:
public abstract class AbstractPartitionAlgorithm implements RuleAlgorithm { @Override
public void init() {
} /**
* 返回所有被路由到的节点的编号
* 返回长度为0的数组表示所有节点都被路由(默认)
* 返回null表示没有节点被路由到
*/
@Override
public Integer[] calculateRange(String beginValue, String endValue) { return new Integer[0];
} /**
* 对于存储数据按顺序存放的字段做范围路由,可以使用这个函数
* @param algorithm
* @param beginValue
* @param endValue
* @return
*/
public static Integer[] calculateSequenceRange(AbstractPartitionAlgorithm algorithm, String beginValue, String endValue) {
Integer begin = 0, end = 0;
begin = algorithm.calculate(beginValue);
end = algorithm.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;
}else{ return null;
}
} }
下面看看PartitionByMod的源代码:
org.opencloudb.route.function.PartitionByMod:
private int count; @Override
public void init() { } public void setCount(int count) { this.count = count;
} @Override
public Integer calculate(String columnValue) {
BigInteger bigNum = new BigInteger(columnValue).abs(); return (bigNum.mod(BigInteger.valueOf(count))).intValue();
}
这段代码很简单,就是将列的值传入后,对count取模,之后的值就是分片节点id。分片节点个数就是count。查看rule.xml里面的配置,我们在function标签传入了count值,并且在tableRule标签定义是哪一列作为分片字段。
可以优化下这段代码,根据习惯,我们一般取2的n次方作为分片个数(这样做有很多好处)。对2的n次方取模等于对2的n次方-1取与运算。代码如下:
private int count; private boolean watch = false; @Override
public void init() { } public void setCount(int count) { this.count = count; if ((count & (count - 1)) == 0) {
watch = true;
}
} @Override
public Integer calculate(String columnValue) {
BigInteger bigNum = new BigInteger(columnValue).abs(); if (watch) {
System.out.println("sigoui"); return bigNum.intValue() & (count - 1);
} return (bigNum.mod(BigInteger.valueOf(count))).intValue();
}
下面我们更深入些,实现使用篇(2)中的7.多重规则-可扩容哈希路由:是从分片字段中抽取一段做分片路由,再取另一段做自动哈希分片。同时再规定某个范围内是某个分片规则,另一范围是另一个分片规则。
通过读取外部规则配置文件scalable-route-hash.txt,来实现灵活的规则配置。增加规则时,修改scalable-route-hash.txt之后在9066端口的控制台动态加载即可(之后会介绍)。
scalable-route-hash.txt:
北京(A0000000~A9999999)=0,1,2,3,4
北京(B0000000)=5,6,7,8,9
上海(00000000~10000000)=10,11
上海=10,11,12,13,14,15
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 SpringBoot入门(五)——自定义配置
【推荐】 小白用shiro(2)
【推荐】 Question | 移动端虚拟机注册等作弊行为的破解之道
数据库路由中间件MyCat - 使用篇(4)的更多相关文章
- 数据库路由中间件MyCat - 背景篇(2)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MyCat的前世今生 如前文所说,Amoeba.Cobar.MyCat等属于同宗一脉.若Amoeba能继续下 ...
- 数据库路由中间件MyCat - 使用篇(1)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 基本概念 直接介绍概念太枯燥了,还是拿个和背景篇相似的例子介绍 业务场景:客户完成下单,快递员接受并更新运单 ...
- 数据库路由中间件MyCat - 源代码篇(13)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 4.配置模块 4.2 schema.xml 接上一篇,接下来载入每个schema的配置(也就是每个MyCat ...
- 数据库路由中间件MyCat - 使用篇(3)上篇
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 全局序列号 数据切分后,原有的关系数据库中的主键约束在分布式条件下将无法使用,因此需要引入外部机制保证数据唯 ...
- 数据库路由中间件MyCat - 源代码篇(7)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 3. 连接模块 3.4 FrontendConnection前端连接 构造方法: public Fronte ...
- 数据库路由中间件MyCat - 源代码篇(15)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. public static void handle(String stmt, ServerConnectio ...
- 数据库路由中间件MyCat - 源代码篇(14)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 对于表的dataNode对应关系,有个特殊配置即类似dataNode="distributed(d ...
- 数据库路由中间件MyCat - 源代码篇(1)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 进入了源代码篇,我们先从整体入手,之后拿一个简单流程前端连接建立与认证作为例子,理清代码思路和设计模式.然后 ...
- 数据库路由中间件MyCat - 使用篇(3)下篇
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 2. 配置conf/server.xml server.xml几乎保存了所有mycat需要的系统配置信息.其 ...
随机推荐
- ABAP 性能优化001
红方框里那一步之行很慢,lt_iflos这个内表才200多条数据 1.关键是你from那个表有多少数据.... 注意点: 1.不要用 CORRESPONDING FIELDS OF 2.LT_IFLO ...
- Django—工程创建以及models数据库易错点
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...
- PAT天梯赛 L2-002. 链表去重 【STL】
题目链接 https://www.patest.cn/contests/gplt/L2-002 思路 用结构体 存储 一个结点的地址 值 和下一个地址 然后从首地址开始 往下走 并且每个值的绝对值 都 ...
- spring-boot3代码
App.java package com.kfit; import org.springframework.boot.SpringApplication; import org.springframe ...
- 使用aspnet_regiis.exe重新注册.NET Framework
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319 aspnet_regiis.exe -i 重新安装IIS以后,需要用aspnet_re ...
- 作业:xml练习1
作业:使用xml描述下表中的学生成绩信息,XML文件存为scores.xml. 1.打开eclipse软件. 2.file-new-java project,输入project name:201811 ...
- Android Studio 代码混淆(你真的会混淆吗)
一.前言 今天要打包新产品,突然忘了混淆的参数是怎么写的了,虽然之前也混淆过,可是具体配置的参数代码有些记不起来了,因此决定花点时间写篇博客记录一下,方便以后查找和自己的记忆. 二.Android S ...
- Java_Time_01_获取当前时间
1. Date SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// ...
- 1>/dev/null 2>&1 & 意思解析
原文:https://jingyan.baidu.com/article/6dad5075334e26a123e36e31.html 用 /dev/null 2>&1 这样的写法.这条命 ...
- str_2.判断两个字符串是否互为旋转词
1. 字符串str的前面任意部分挪到后面形成的字符串叫做字符串str的旋转词 $str1 = "2ab1"; $str2 = "ab12"; $ret = is ...