Mysql系列六:(Mycat分片路由原理、Mycat常用分片规则及对应源码介绍)

Mysql系列六:(Mycat分片路由原理、Mycat常用分片规则及对应源码介绍),第1张

概述 一、Mycat分片路由原理我们先来看下面的一个SQL在Mycat里面是如何执行的:select * from travelrecord where id in(5000001, 10000001);有3个分片dn1,dn2,dn3, id=5000001这条数据在dn2上,id=10000001这条数据在dn3上。查询时可能有出现的问题:1)全部扫描一遍dn1  dn2  dn3,结果导致性能浪费。2)只扫描某个片。漏掉数据的情况。总结:不能多扫——>性能不足也不能少——>漏掉数据那么Mycat是如何解决上面的问题的呢?Mycat使用Druid的DruidParser作为分析器/解析器,解析的过程主要有Visitor和Statement两个阶段说明:1)Visitor过程,解析出如下属性:哪一张表字段列表条件信息什么样的SQL解析出以上信息以后就可以根据schema.xml和rule.xml文件确认要去哪个分片上进行DML *** 作了2)Statement过程转化:转化后知道执行的是什么样的SQL(增删改查)3)改写SQL通过查询条件可以知道要查询的数据都在哪些分片上Dn2, id= 5000001Dn3, id= 100000001所以SQL被改写成以下的形式:select * from travelrecord where id = 5000001;(dn2执行)select * from travelrecord where id = 10000001;(dn3执行)4)分别在分片dn2,dn3上执行第 3)步改写的SQL,然后把从dn2,dn3上得到的结果进行拼装就是最终的结果了备注:多表关联查询的时候,visitor会遍历出所有的表,然后去各个分片上去获取结果,同时把结果缓存起来,最后根据关联查询计算出结果。确定分片的过程:首先看where条件里面是否含有分片字段,有就根据分片字段的值结合schema.xml、rule.xml的值确定是哪个分片。当不能确定在哪一个分片上的时候,mycat会到所有的分片上去找二、Mycat常用分片规则1. 时间类:按天分片、自然月分片、单月小时分片2. 哈希类:Hash固定分片、日期范围Hash分片、截取数字Hash求模范围分片、截取数字Hash分片、一致性Hash分片3. 取模类:取模分片、取模范围分片、范围求模分片4. 其他类:枚举分片、范围约定分片、应用指定分片、冷热数据分片下面基于源码来介绍Mycat的常用分片规则,源码地址三、Mycat常用分片规则介绍说明:分片规则都定义在rule.xml文件里面<!--tableRule标签:定义table分片策略--><tableRule name="rule1"><!--rule标签:策略定义标签--><rule><!--columns标签:对应的分片字段--><columns>id</columns><!--algorithm标签:tableRule分片策略对应的function名称--><algorithm>func1</algorithm></rule></tableRule><!-- 定义分片函数 --><function name="func1" class="io.mycat.route.function.PartitionByLong"><property name="partitionCount">1,1,2,3,1</property><!-- 分片数 --><property name="partitionLength">128,128,128,128,128</property><!-- 分片长度 --></function>1. 自动范围分片在rule.xml里面的配置:<tableRule name="auto-sharding-long"><rule><columns>id</columns><algorithm>rang-long</algorithm></rule></tableRule><function name="rang-long"class="io.mycat.route.function.AutoPartitionByLong"><property name="mapFile">autopartition-long.txt</property></function>说明:有3个分片,第1个分片存储的是1-500000的数据,第2个分片存储的是500001-1000000的数据,第3个分片存储的是1000001-1500000的数据insert into employee(id, name) value(1,Tom);在第1个分片insert into employee(id, name) value(500002,Jack);在第2个分片insert into employee(id, name) value(1000002,Lucy);在第3个分片对应代码:package io.mycat.route.function;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.util.HashSet;import java.util.LinkedList;import java.util.Set;import io.mycat.config.model.rule.RuleAlgorithm;/*** auto partition by Long ,can be used in auto increment primary key partition** @author wuzhi*/public class AutoPartitionByLong extends AbstractPartitionAlgorithm implements RuleAlgorithm{private String mapFile;private LongRange[] longRongs;private int defaultNode = -1;@Overridepublic void init() {initialize();}public void setMapFile(String mapFile) {this.mapFile = mapFile;}@Overridepublic Integer calculate(String columnValue) {// columnValue = NumberParseUtil.eliminateQoute(columnValue);try {long value = Long.parseLong(columnValue);Integer rst = null;for (LongRange longRang : this.longRongs) {if (value <= longRang.valueEnd && value >= longRang.valueStart) {return longRang.nodeIndx;}}//数据超过范围,暂时使用配置的默认节点if (rst == null && defaultNode >= 0) {return defaultNode;}return rst;} catch (NumberFormatException e){throw new IllegalArgumentException(new StringBuilder().append("columnValue:").append(columnValue).append(" Please eliminate any quote and non number within it.").toString(),e);}}@Overridepublic Integer[] calculateRange(String beginValue, String endValue) {return AbstractPartitionAlgorithm.calculateSequenceRange(this, beginValue, endValue);}@Overridepublic int getPartitionNum() {// int nPartition = longRongs.length;/** fix #1284 这里的统计应该统计Range的nodeIndex的distinct总数*/Set<Integer> distNodeIdxSet = new HashSet<Integer>();for(LongRange range : longRongs) {distNodeIdxSet.add(range.nodeIndx);}int nPartition = distNodeIdxSet.size();return nPartition;}private void initialize() {BufferedReader in = null;try {// FileInputStream fin = new FileInputStream(new File(fileMapPath));InputStream fin = this.getClass().getClassLoader().getResourceAsStream(mapFile);if (fin == null) {throw new RuntimeException("can't find class resource file "+ mapFile);}in = new BufferedReader(new InputStreamReader(fin));LinkedList<LongRange> longRangeList = new LinkedList<LongRange>();for (String line = null; (line = in.readLine()) != null;) {line = line.trim();if (line.startsWith("#") || line.startsWith("//")) {continue;}int ind = line.indexOf('=');if (ind < 0) {System.out.println(" warn: bad line int " + mapFile + " :"+ line);continue;}String pairs[] = line.substring(0, ind).trim().split("-");long longStart = NumberParseUtil.parseLong(pairs[0].trim());long longEnd = NumberParseUtil.parseLong(pairs[1].trim());int nodeId = Integer.parseInt(line.substring(ind + 1).tri  一、Mycat分片路由原理

我们先来看下面的一个sql在Mycat里面是如何执行的:

travelrecord ID (,);

有3个分片dn1,dn2,dn3,ID=5000001

dn1  dn2  dn3

2)只扫描某个片。漏掉数据的情况。

@H_301_40@

那么Mycat是如何解决上面的问题的呢?

Mycat解析的过程主要有Visitor和Statement两个阶段

1)Visitor过程,解析出如下属性:

              哪一张表

              字段列表

              条件信息

              什么样的sql

通过查询条件可以知道要查询的数据都在哪些分片上

travelrecord ID travelrecord ID ;(dn3执行)

4)分别在分片dn2,dn3上执行第 3)步改写的sql,然后把从dn2,dn3上得到的结果进行拼装就是最终的结果了

visitor

where

二、Mycat常用分片规则

1. 时间类:按天分片、自然月分片、单月小时分片

2. 哈希类:Hash固定分片、日期范围Hash分片、截取数字Hash求模范围分片、截取数字Hash分片、一致性Hash分片

3. 取模类:取模分片、取模范围分片、范围求模分片

4. 其他类:枚举分片、范围约定分片、应用指定分片、冷热数据分片

下面基于源码来介绍Mycat的常用分片规则,href="https://github.com/MyCATApache/Mycat-Server" target="_blank">源码地址

三、Mycat常用分片规则介绍

分片规则都定义在rule.xml文件里面

ID func1 1,1,2,3,1 128,128,128 1. 自动范围分片

在rule.xml里面的配置:

ID rang-long

<span ><<span >function <span >name<span >="rang-long"<span >
class<span >="io.mycat.route.function.AutopartitionByLong"<span >>
<span ><<span >property <span >name<span >="mapfile"<span >>autopartition-long.txt<span ></<span >property<span >>
<span ></<span >function<span >>

有3个分片,第1个分片存储的是1-500000的数据,第2个分片存储的是500001-1000000的数据,第3个分片存储的是1000001-1500000的数据

insert into employee(ID,name) value(1,Tom);在第1个分片

insert into employee(ID,name) value(500002,Jack);在第2个分片

insert into employee(ID,name) value(1000002,Lucy);在第3个分片

对应代码:

<span >import<span > java.io.BufferedReader;
<span >import
<span > java.io.inputStream;
<span >import
<span > java.io.inputStreamReader;
<span >import
<span > java.util.HashSet;
<span >import
<span > java.util.linkedList;
<span >import
<span > java.util.Set;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;

<span >/**<span >

auto partition by Long,can be used in auto increment primary key partition

<span >@author<span > wuzhi
<span >*/
<span >public <span >class AutopartitionByLong <span >extends AbstractPartitionAlgorithm <span >implements<span > RuleAlgorithm{

<span >private<span > String mapfile;
<span >private<span > LongRange[] longRongs;

<span >private <span >int defaultNode = -1<span >;
@OverrIDe
<span >public <span >voID<span > init() {

 initia<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ze();

}

<span >public <span >voID<span > setMapfile(String mapfile) {
<span >this.mapfile =<span > mapfile;
}

@OverrIDe
<span >public<span > Integer calculate(String columnValue) {
<span >//<span > columnValue = NumberParseUtil.eliminateQoute(columnValue);
<span >try<span > {
<span >long value =<span > Long.parseLong(columnValue);
Integer rst = <span >null<span >;
<span >for (LongRange longRang : <span >this<span >.longRongs) {
<span >if (value <= longRang.valueEnd && value >=<span > longRang.valueStart) {
<span >return<span > longRang.nodeIndx;
}
}
<span >//<span >数据超过范围,暂时使用配置的默认节点
<span >if (rst == <span >null && defaultNode >= 0<span >) {
<span >return<span > defaultNode;
}
<span >return<span > rst;
} <span >catch<span > (NumberFormatException e){
<span >throw <span >new IllegalArgumentException(<span >new StringBuilder().append("columnValue:").append(columnValue).append(" Please eliminate any quote and non number within it."<span >).toString(),e);
}
}

@OverrIDe
<span >public<span > Integer[] calculaterange(String beginValue,String endValue) {
<span >return AbstractPartitionAlgorithm.calculateSequenceRange(<span >this<span >,beginValue,endValue);
}

@OverrIDe
<span >public <span >int<span > getPartitionNum() {
<span >//<span > int nPartition = longRongs.length;

 <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;/*</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;  * fix #1284 <a href="https://m.jb51.cc/tag/zheli/" target="_blank" >这里</a>的<a href="https://www.jb51.cc/tag/tongji/" target="_blank" >统计</a>应该<a href="https://www.jb51.cc/tag/tongji/" target="_blank" >统计</a>Range的nodeIndex的<a href="https://www.jb51.cc/tag/dis/" target="_blank" >dis</a>tinct总数  </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;*/</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Set</span><Integer> <a href="https://www.jb51.cc/tag/dis/" target="_blank" >dis</a>tNode<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>xSet = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> HashSet<Integer><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;(); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;(LongRange range : longRongs) {     <a href="https://www.jb51.cc/tag/dis/" target="_blank" >dis</a>tNode<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>xSet.add(range.nodeIndx); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> nPartition =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://www.jb51.cc/tag/dis/" target="_blank" >dis</a>tNode<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>xSet.size(); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; nPartition;

}

<span >private <span >voID<span > initialize() {
BufferedReader in = <span >null<span >;
<span >try<span > {
<span >//<span > fileinputStream fin = new fileinputStream(new file(fileMapPath));
inputStream fin = <span >this<span >.getClass().getClassLoader()
.getResourceAsstream(mapfile);
<span >if (fin == <span >null<span >) {
<span >throw <span >new RuntimeException("can't find class resource file "
+<span > mapfile);
}
in = <span >new BufferedReader(<span >new<span > inputStreamReader(fin));
linkedList longRangeList = <span >new linkedList<span >();

     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span> (String <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span>; (<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne = in.read<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne()) != <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;) {         <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.trim();         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.startsWith("#") || <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.startsWith("//"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;continue</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> ind = <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.indexOf('='<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (ind < 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {             Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>" warn: bad <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne int " + map<a href="https://m.jb51.cc/tag/file/" target="_blank" >file</a> + " :"                     +<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne);             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;continue</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }             String pa<a href="https://www.jb51.cc/tag/irs/" target="_blank" >irs</a>[] </span>= <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.substring(0,ind).trim().sp<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>t("-"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> longStart = NumberParseUtil.parseLong(pa<a href="https://www.jb51.cc/tag/irs/" target="_blank" >irs</a>[0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;].trim());             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> longEnd = NumberParseUtil.parseLong(pa<a href="https://www.jb51.cc/tag/irs/" target="_blank" >irs</a>[1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;].trim());             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> node<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a> = Integer.parseInt(<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.substring(ind + 1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)                     .trim());             longRange<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>                     .add(</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; LongRange(node<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>,longStart,longEnd));     }     longRongs </span>= longRange<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.toArray(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; LongRange[longRange<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>             .size()]); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (e <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;instanceof</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; RuntimeException) {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (RuntimeException) e;     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; RuntimeException(e);     } } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;finally</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;try</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         in.close();     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e2) {     } }

}

<span >public <span >int<span > getDefaultNode() {
<span >return<span > defaultNode;
}

<span >public <span >voID setDefaultNode(<span >int<span > defaultNode) {
<span >this.defaultNode =<span > defaultNode;
}

<span >static <span >class<span > LongRange {
<span >public <span >final <span >int<span > nodeIndx;
<span >public <span >final <span >long<span > valueStart;
<span >public <span >final <span >long<span > valueEnd;

 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> LongRange(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> nodeIndx,<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> valueStart,<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; valueEnd) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;super</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.nodeIndx =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; nodeIndx;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.valueStart =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; valueStart;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.valueEnd =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; valueEnd; }

}
}

2. 枚举分片

把数据分类存储

在rule.xml里面的配置:

sharding_ID hash-int partition-hash-int.txt 0

0

对应代码:

<span >import<span > java.io.BufferedReader;
<span >import
<span > java.io.inputStream;
<span >import
<span > java.io.inputStreamReader;
<span >import
<span > java.util.HashMap;
<span >import
<span > java.util.HashSet;
<span >import
<span > java.util.Map;
<span >import
<span > java.util.Set;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;

<span >/**<span >

<span >@author<span > mycat
<span >*/
<span >public <span >class PartitionByfileMap <span >extends AbstractPartitionAlgorithm <span >implements<span > RuleAlgorithm {

<span >private<span > String mapfile;
<span >private Map<Object,Integer><span > app2Partition;
<span >/**<span >

Map<Object,Integer> app2Partition中key值的类型:默认值为0,0表示Integer,非零表示String
<span >*/

<span >private
<span >int
<span > type;

<span >/**<span >

默认节点在map中的key
<span >*/

<span >private
<span >static
<span >final
String DEFAulT_NODE = "DEFAulT_NODE"<span >;

<span >/**<span >

默认节点:小于0表示不设置默认节点,大于等于0表示设置默认节点默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点如果不配置默认节点(defaultNode值小于0表示不配置默认节点),碰到不识别的枚举值就会报错,like this:can't find datanode for sharding column:column_name val:ffffffff
<span >*/

<span >private
<span >int
defaultNode = -1<span >;

@OverrIDe
<span >public <span >voID<span > init() {

 initia<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ze();

}

<span >public <span >voID<span > setMapfile(String mapfile) {
<span >this.mapfile =<span > mapfile;
}

<span >public <span >voID setType(<span >int<span > type) {
<span >this.type =<span > type;
}

<span >public <span >voID setDefaultNode(<span >int<span > defaultNode) {
<span >this.defaultNode =<span > defaultNode;
}

@OverrIDe
<span >public<span > Integer calculate(String columnValue) {
<span >try<span > {
Object value =<span > columnValue;
<span >if (type == 0<span >) {
value =<span > Integer.valueOf(columnValue);
}
Integer rst = <span >null<span >;
Integer pID =<span > app2Partition.get(value);
<span >if (pID != <span >null<span >) {
rst =<span > pID;
} <span >else<span > {
rst =<span > app2Partition.get(DEFAulT_NODE);
}
<span >return<span > rst;
} <span >catch<span > (NumberFormatException e){
<span >throw <span >new IllegalArgumentException(<span >new StringBuilder().append("columnValue:").append(columnValue).append(" Please check if the format satisfIEd."<span >).toString(),e);
}
}

@OverrIDe
<span >public <span >int<span > getPartitionNum() {
Set set = <span >new HashSet<span >(app2Partition.values());
<span >int count =<span > set.size();
<span >return<span > count;
}

<span >private <span >voID<span > initialize() {
BufferedReader in = <span >null<span >;
<span >try<span > {
<span >//<span > fileinputStream fin = new fileinputStream(new file(fileMapPath));
inputStream fin = <span >this<span >.getClass().getClassLoader()
.getResourceAsstream(mapfile);
<span >if (fin == <span >null<span >) {
<span >throw <span >new RuntimeException("can't find class resource file "
+<span > mapfile);
}
in = <span >new BufferedReader(<span >new<span > inputStreamReader(fin));

     app2Partition </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> HashMap<Object,Integer><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span> (String <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span>; (<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne = in.read<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne()) != <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;) {         <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.trim();         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.startsWith("#") || <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.startsWith("//"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;continue</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> ind = <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.indexOf('='<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (ind < 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;continue</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;try</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {             String key </span>= <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.substring(0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;,ind).trim();             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> p<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a> = Integer.parseInt(<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.substring(ind + 1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;).trim());             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(type == 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {                 app2Partition.put(Integer.parseInt(key),p<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>);             } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {                 app2Partition.put(key,p<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>);             }         } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e) {         }     }     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;<a href="https://m.jb51.cc/tag/shezhi/" target="_blank" >设置</a><a href="https://www.jb51.cc/tag/mo/" target="_blank" >默</a>认节点</span>     <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(defa<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>tNode >= 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {         app2Partition.put(DEFA<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>T_NODE,defa<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>tNode);     } } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (e <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;instanceof</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; RuntimeException) {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (RuntimeException) e;     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; RuntimeException(e);     } } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;finally</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;try</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         in.close();     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e2) {     } }

}
}

3. Hash固定分片(固定分片Hash算法)

Hash

在rule.xml里面的配置:

ID func1 1,128

1) partitionCount.length

2) sum((partitionCount[i]*partitionLength[j])) === 1024——>partitionCount[0]*partitionLength[0]+partitionCount[1]*partitionLength[1] === 1024

1*128+1*128+2*128+3*128+1*128 === 1024

eg:

8

1

2

...................

8

ID

ID%1024 = 128

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;
<span >import
<span > io.mycat.route.util.PartitionUtil;

<span >public <span >final <span >class PartitionByLong <span >extends AbstractPartitionAlgorithm <span >implements<span > RuleAlgorithm {
<span >protected <span >int<span >[] count;
<span >protected <span >int<span >[] length;
<span >protected<span > PartitionUtil partitionUtil;

</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;static</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;[] toIntArray(String string) {    String[] strs </span>= io.mycat.util.Sp<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>tUtil.sp<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>t(string,',<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;true</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span>[] ints = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;[strs.length];    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i = 0; i < strs.length; ++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i) {        ints[i] </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Integer.parseInt(strs[i]);    }    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; ints;}</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;vo<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; setPartitionCount(String partitionCount) {    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.count =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; toIntArray(partitionCount);}</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;vo<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; setPartitionLength(String partitionLength) {    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.length =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; toIntArray(partitionLength);}@Overr<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>e</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;vo<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; init() {    partitionUtil </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; PartitionUtil(count,length);}@Overr<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>e</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Integer cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(String c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue)  {

<span >//<span > columnValue = NumberParseUtil.eliminateQoute(columnValue);
<span >try<span > {
<span >long key =<span > Long.parseLong(columnValue);
<span >return<span > partitionUtil.partition(key);
} <span >catch<span > (NumberFormatException e){
<span >throw <span >new IllegalArgumentException(<span >new StringBuilder().append("columnValue:").append(columnValue).append(" Please eliminate any quote and non number within it."<span >).toString(),endValue);
}

<span >//<span > @OverrIDe
<span >//<span > public int getPartitionCount() {
<span >//<span > int nPartition = 0;
<span >//<span > for(int i = 0; i < count.length; i++) {
<span >//<span > nPartition += count[i];
<span >//<span > }
<span >//<span > return nPartition;
<span >//<span > }
<span >
}

4. 求模分片

ID%

在rule.xml里面的配置:

ID mod-long 3

对应代码:

<span >import<span > java.math.BigInteger;
<span >import
<span > java.util.ArrayList;
<span >import
<span > java.util.HashMap;
<span >import
<span > java.util.List;
<span >import
<span > java.util.Map;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;

<span >/**<span >

number column partion by Mod operator

if count is 10 then 0 to 0,21 to 1 (21 % 10 =1)

<span >@author<span > wuzhih

<span >*/
<span >public <span >class PartitionByMod <span >extends AbstractPartitionAlgorithm <span >implements<span > RuleAlgorithm {

<span >private <span >int<span > count;
@OverrIDe
<span >public <span >voID<span > init() {

}

<span >public <span >voID setCount(<span >int<span > count) {
<span >this.count =<span > count;
}

@OverrIDe
<span >public<span > Integer calculate(String columnValue) {
<span >//<span > columnValue = NumberParseUtil.eliminateQoute(columnValue);
<span >try<span > {
BigInteger bigNum = <span >new<span > BigInteger(columnValue).abs();
<span >return<span > (bigNum.mod(BigInteger.valueOf(count))).intValue();
} <span >catch<span > (NumberFormatException e){
<span >throw <span >new IllegalArgumentException(<span >new StringBuilder().append("columnValue:").append(columnValue).append(" Please eliminate any quote and non number within it."<span >).toString(),e);
}

}

@OverrIDe
<span >public <span >int<span > getPartitionNum() {
<span >int nPartition = <span >this<span >.count;
<span >return<span > nPartition;
}

<span >private <span >static <span >voID<span > hashtest() {
PartitionByMod hash=<span >new<span > PartitionByMod();
hash.setCount(11<span >);
hash.init();

 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span>[] bucket=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;[hash.count]; Map</span><Integer,<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a><Integer>> hashed=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> HashMap<><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;(); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> total=1000_0000;<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;数据量</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> c=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i=100_0000;i<total+100_0000;i++){<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;假设分片键从100万开始</span>     c++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> h=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;hash.cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(Integer.toString(i));     bucket[h]</span>++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a></span><Integer> <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;hashed.get(h);     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>==<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;){         <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a></span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Array<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a><><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;();         hashed.put(h,<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>);     }     <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.add(i); } Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(c</span>+"   "+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;total); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span> d=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; c</span>=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> <a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>"index    bucket   ratio"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; i:bucket){     d</span>+=i/(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)total;     c</span>+=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i;     Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x</span>+++"  "+i+"   "+(i/(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)total)); } Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(d</span>+"  "+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;c); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>"****************************************************"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;); rehashTest(hashed.get(</span>0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;));

}
<span >private <span >static <span >voID rehashTest(List<span > partition) {
PartitionByMod hash=<span >new<span > PartitionByMod();
hash.count=110;<span >//<span >分片数
<span > hash.init();

 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span>[] bucket=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;[hash.count]; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> total=partition.size();<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;数据量</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> c=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i:partition){<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;假设分片键从100万开始</span>     c++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> h=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;hash.cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(Integer.toString(i));     bucket[h]</span>++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; } Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(c</span>+"   "+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;total); c</span>=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> <a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>"index    bucket   ratio"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; i:bucket){     c</span>+=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i;     Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x</span>+++"  "+i+"   "+(i/(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)total)); }

}
<span >public <span >static <span >voID<span > main(String[] args) {
<span >//<span > hashtest();
PartitionByMod partitionByMod = <span >new<span > PartitionByMod();
partitionByMod.count=8<span >;
partitionByMod.calculate("\"6\""<span >);
partitionByMod.calculate("\'6\'"<span >);
}
}

5. 自然月分片

按照自然月的方式进行分片

在rule.xml里面的配置:

create_time partbymonth yyyy-MM-dd 2015-01-01

sEndDated

3

分片

分片

分片

1

5

9

2

6

10

3

7

11

4

8

12

对应代码:

<span >import<span > java.text.ParseException;
<span >import
<span > java.text.SimpleDateFormat;
<span >import
<span > java.util.ArrayList;
<span >import
<span > java.util.Calendar;
<span >import
<span > java.util.Collections;
<span >import
<span > java.util.List;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;
<span >import<span > org.apache.log4j.Logger;

<span >/**<span >

例子 按月份列分区 ,每个自然月一个分片,格式 between *** 作解析的范例

<span >@author<span > wzh

<span >*/
<span >public <span >class PartitionByMonth <span >extends AbstractPartitionAlgorithm <span >implements<span >
RuleAlgorithm {
<span >private <span >static <span >final Logger LOGGER = Logger.getLogger(PartitionByDate.<span >class<span >);
<span >private<span > String sBeginDate;
<span >private<span > String dateFormat;
<span >private<span > String sEndDate;
<span >private<span > Calendar beginDate;
<span >private<span > Calendar endDate;
<span >private <span >int<span > nPartition;

<span >private ThreadLocal<span > formatter;

@OverrIDe
<span >public <span >voID<span > init() {
<span >try<span > {
beginDate =<span > Calendar.getInstance();
beginDate.setTime(<span >new<span > SimpleDateFormat(dateFormat)
.parse(sBeginDate));
formatter = <span >new ThreadLocal<span >() {
@OverrIDe
<span >protected<span > SimpleDateFormat initialValue() {
<span >return <span >new<span > SimpleDateFormat(dateFormat);
}
};
<span >if(sEndDate!=<span >null&&!sEndDate.equals(""<span >)) {
endDate =<span > Calendar.getInstance();
endDate.setTime(<span >new<span > SimpleDateFormat(dateFormat).parse(sEndDate));
nPartition = ((endDate.get(Calendar.YEAR) - beginDate.get(Calendar.YEAR)) * 12

endDate.get(Calendar.MONTH) - beginDate.get(Calendar.MONTH)) + 1<span >;
         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (nPartition <= 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> <a href="https://www.jb51.cc/tag/javalang/" target="_blank" >java.lang</a>.Ille<a href="https://www.jb51.cc/tag/gal/" target="_blank" >gal</a>ArgumentException("Incorrect time range for month partitioning!"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);         }     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         nPartition </span>= -1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     } } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (ParseException e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://www.jb51.cc/tag/javalang/" target="_blank" >java.lang</a>.Ille<a href="https://www.jb51.cc/tag/gal/" target="_blank" >gal</a>ArgumentException(e); }

}

<span >/**<span >

For circulatory partition,calculated value of target partition needs to be

rotated to fit the partition range
<span >*/
<span >private <span >int reCalculatePartition(<span >int<span > targetPartition) {
<span >/**<span >

If target date is prevIoUs of start time of partition setting,shiftthe delta range between target and start date to be positive value
<span >*/

<span >if
(targetPartition < 0<span >) {
targetPartition
= nPartition - (-targetPartition) %<span > nPartition;
}

<span >if (targetPartition >=<span > nPartition) {
targetPartition = targetPartition %<span > nPartition;
}

<span >return<span > targetPartition;
}

@OverrIDe
<span >public<span > Integer calculate(String columnValue) {
<span >try<span > {
<span >int<span > targetPartition;
Calendar curTime =<span > Calendar.getInstance();
curTime.setTime(formatter.get().parse(columnValue));
targetPartition = ((curTime.get(Calendar.YEAR) -<span > beginDate.get(Calendar.YEAR))
* 12 +<span > curTime.get(Calendar.MONTH)
-<span > beginDate.get(Calendar.MONTH));

     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;/**</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;      * For cir<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>tory partition,cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>ted value of target partition needs to be      * rotated to fit the partition range       </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;*/</span>     <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (nPartition > 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {         targetPartition </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; reCal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>tePartition(targetPartition);     }     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; targetPartition; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (ParseException e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Ille<a href="https://www.jb51.cc/tag/gal/" target="_blank" >gal</a>ArgumentException(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> StringBuilder().append("c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue:").append(c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue).append(" Please check if the format satisf<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>d."<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;).toString(),e); }

}

@OverrIDe
<span >public<span > Integer[] calculaterange(String beginValue,String endValue) {
<span >try<span > {
<span >int<span > startPartition,endPartition;
Calendar partitionTime =<span > Calendar.getInstance();
SimpleDateFormat format = <span >new<span > SimpleDateFormat(dateFormat);
partitionTime.setTime(format.parse(beginValue));
startPartition = ((partitionTime.get(Calendar.YEAR) -<span > beginDate.get(Calendar.YEAR))
12 +<span > partitionTime.get(Calendar.MONTH)
-<span > beginDate.get(Calendar.MONTH));
partitionTime.setTime(format.parse(endValue));
endPartition = ((partitionTime.get(Calendar.YEAR) -<span > beginDate.get(Calendar.YEAR))
12 +<span > partitionTime.get(Calendar.MONTH)
-<span > beginDate.get(Calendar.MONTH));

     <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a></span><Integer> <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a> = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Array<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a><><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;while</span> (startPartition <=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; endPartition) {         Integer nodeValue </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; reCal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>tePartition(startPartition);         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (C<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>lections.frequency(<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>,nodeValue) < 1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)             <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.add(nodeValue);         startPartition</span>++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     }     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> size =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.size();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span> (<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.toArray(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Integer[size])); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (ParseException e) {     LOGGER.error(</span>"error"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;,e);     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Integer[0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;]; }

}

@OverrIDe
<span >public <span >int<span > getPartitionNum() {
<span >int nPartition = <span >this<span >.nPartition;
<span >return<span > nPartition;
}

<span >public <span >voID<span > setsBeginDate(String sBeginDate) {
<span >this.sBeginDate =<span > sBeginDate;
}

<span >public <span >voID<span > setDateFormat(String dateFormat) {
<span >this.dateFormat =<span > dateFormat;
}

<span >public <span >voID<span > setsEndDate(String sEndDate) {
<span >this.sEndDate =<span > sEndDate;
}

}

6. 匹配求模分片

prefixLengthcharat(i)

在rule.xml里面的配置:

ID partitionbyprefixpattern 3 6

有下面这种类型的数据

+

201801 01   10001

columns6

对应代码:

<span >import<span > java.io.BufferedReader;
<span >import
<span > java.io.inputStream;
<span >import
<span > java.io.inputStreamReader;
<span >import
<span > java.util.HashSet;
<span >import
<span > java.util.linkedList;
<span >import
<span > java.util.Set;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;
<span >import<span > io.mycat.route.function.AutopartitionByLong.LongRange;

<span >/**<span >

partition by Prefix length,can be used in String partition

<span >@author<span > hexiaobin
<span >*/
<span >public <span >class PartitionByPrefixPattern <span >extends AbstractPartitionAlgorithm <span >implements<span > RuleAlgorithm {
<span >private <span >static <span >final <span >int PARTITION_LENGTH = 1024<span >;
<span >private <span >int patternValue = PARTITION_LENGTH;<span >//<span > 分区长度,取模数值(默认为1024)
<span >private <span >int prefixLength;<span >//<span > 字符前几位进行ASCII码取和
<span >private<span > String mapfile;
<span >private<span > LongRange[] longRongs;

@OverrIDe
<span >public <span >voID<span > init() {

 initia<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ze();

}

<span >public <span >voID<span > setMapfile(String mapfile) {
<span >this.mapfile =<span > mapfile;
}

<span >public <span >voID setPatternValue(<span >int<span > patternValue) {
<span >this.patternValue =<span > patternValue;
}

<span >public <span >voID setPrefixLength(<span >int<span > prefixLength) {
<span >this.prefixLength =<span > prefixLength;
}

@OverrIDe
<span >public<span > Integer calculate(String columnValue) {
<span >try<span > {
<span >int Length =<span > Integer.valueOf(prefixLength);

     Length </span>= c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue.length() < Length ?<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue.length() : Length;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> sum = 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i = 0; i < Length; i++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {         sum </span>= sum +<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue.ch<a href="https://www.jb51.cc/tag/ara/" target="_blank" >ara</a>t(i);     }     Integer rst </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span> (LongRange longRang : <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;.longRongs) {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> hash = sum %<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; patternValue;         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (hash <= longRang.valueEnd &amp;&amp; hash >=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; longRang.valueStart) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; longRang.nodeIndx;         }     }     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; rst; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (NumberFormatException e){     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Ille<a href="https://www.jb51.cc/tag/gal/" target="_blank" >gal</a>ArgumentException(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> StringBuilder().append("c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue:").append(c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue).append(" Please e<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>minate any quote and non number within it."<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;).toString(),e); }

}

@OverrIDe
<span >public <span >int<span > getPartitionNum() {
<span >//<span > int nPartition = this.longRongs.length;
<span >/*<span >

fix #1284 这里的统计应该统计Range的nodeIndex的distinct总数
<span >*/
<span >
Set
distNodeIDxSet = <span >new
HashSet<span >();
<span >for
<span >(LongRange range : longRongs) {
distNodeIDxSet.add(range.nodeIndx);
}
<span >int
nPartition =<span > distNodeIDxSet.size();
<span >return
<span > nPartition;
}

<span >private <span >voID<span > initialize() {
BufferedReader in = <span >null<span >;
<span >try<span > {
<span >//<span > fileinputStream fin = new fileinputStream(new file(fileMapPath));
inputStream fin = <span >this<span >.getClass().getClassLoader()
.getResourceAsstream(mapfile);
<span >if (fin == <span >null<span >) {
<span >throw <span >new RuntimeException("can't find class resource file "
+<span > mapfile);
}
in = <span >new BufferedReader(<span >new<span > inputStreamReader(fin));
linkedList longRangeList = <span >new linkedList<span >();

     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span> (String <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span>; (<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne = in.read<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne()) != <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;) {         <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.trim();         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.startsWith("#") || <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.startsWith("//"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;continue</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> ind = <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.indexOf('='<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (ind < 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;) {             Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>" warn: bad <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne int " + map<a href="https://m.jb51.cc/tag/file/" target="_blank" >file</a> + " :"                     +<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne);             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;continue</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }             String pa<a href="https://www.jb51.cc/tag/irs/" target="_blank" >irs</a>[] </span>= <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne.substring(0,longEnd));     }     longRongs </span>= longRange<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.toArray(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; LongRange[longRange<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>             .size()]); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (e <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;instanceof</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; RuntimeException) {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (RuntimeException) e;     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; RuntimeException(e);     } } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;finally</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;try</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {         in.close();     } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (Exception e2) {     } }

}

<span >static <span >class<span > LongRange {
<span >public <span >final <span >int<span > nodeIndx;
<span >public <span >final <span >long<span > valueStart;
<span >public <span >final <span >long<span > valueEnd;

 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> LongRange(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> nodeIndx,<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; valueEnd) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;super</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.nodeIndx =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; nodeIndx;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.valueStart =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; valueStart;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span>.valueEnd =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; valueEnd; }

}
}

7. 冷热数据分片

根据日期查询日志数据冷热数据分布 ,最近 n 个月的到实时交易库查询,超过 n 个月的按照 m 天分片。

在rule.xml里面的配置:

create_time sharding-by-hotdate

<span ><<span >function <span >name<span >="sharding-by-hotdate"<span > class<span >="org.opencloudb.route.function.PartitionByHotDate"<span >>
<span ><<span >property <span >name<span >="dateFormat"<span >>yyyy-MM-dd<span ></<span >property<span >> <span >
<span ><<span >property <span >name<span >="sLastDay"<span >>30<span ></<span >property<span >> <span >
<span ><<span >property <span >name<span >="sPartionDay"<span >>30<span ></<span >property<span >> <span >
<span ></<span >function<span >>

对应代码:

<span >import<span > java.text.ParseException;
<span >import
<span > java.text.SimpleDateFormat;
<span >import
<span > java.util.Calendar;

<span >import<span > org.slf4j.Logger;
<span >import<span > org.slf4j.LoggerFactory;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;

<span >/**<span >

根据日期查询日志数据 冷热数据分布 ,最近n个月的到实时交易库查询,超过n个月的按照m天分片

<span >@author<span > sw

<tableRule name="sharding-by-date">

create_time sharding-by-hotdate
PartitionByHotDate AbstractPartitionAlgorithm Logger LOGGER = LoggerFactory.getLogger(PartitionByHotDate.<span >private<span > String dateFormat;
<span >private
<span > String sLastDay;
<span >private
<span > String sPartionDay;

<span >private <span >long<span > sLastTime;
<span >private <span >long<span > partionTime;
<span >private ThreadLocal<span > formatter;

<span >private <span >long<span > beginDate;

<span >private <span >static <span >final <span >long oneDay = 86400000<span >;

@OverrIDe
<span >public <span >voID<span > init() {
<span >try<span > {
formatter = <span >new ThreadLocal<span >() {
@OverrIDe
<span >protected<span > SimpleDateFormat initialValue() {
<span >return <span >new<span > SimpleDateFormat(dateFormat);
}
};
sLastTime =<span > Integer.valueOf(sLastDay);
partionTime = Integer.parseInt(sPartionDay) *<span > oneDay;
} <span >catch<span > (Exception e) {
<span >throw <span >new<span > java.lang.IllegalArgumentException(e);
}
}

@OverrIDe
<span >public<span > Integer calculate(String columnValue) {
Integer targetPartition = -1<span >;
<span >try<span > {
<span >long targetTime =<span > formatter.get().parse(columnValue).getTime();
Calendar Now =<span > Calendar.getInstance();
<span >long NowTime =<span > Now.getTimeInMillis();

     beginDate </span>= <a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a>Time - sLastTime *<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; oneDay;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> diffDays = (<a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a>Time - targetTime) / (1000 * 60 * 60 * 24) + 1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(diffDays-sLastTime <= 0 || diffDays<0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; ){         targetPartition </span>= 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     }</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;{         targetPartition </span>= (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span>) ((beginDate - targetTime) / partionTime) + 1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     }     LOGGER.de<a href="https://m.jb51.cc/tag/BUG/" target="_blank" >BUG</a>(</span>"PartitionByHotDate cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te for " + c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue + " return " +<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; targetPartition);     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; targetPartition; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (ParseException e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Ille<a href="https://www.jb51.cc/tag/gal/" target="_blank" >gal</a>ArgumentException(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> StringBuilder().append("c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue:").append(c<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>umnValue).append(" Please check if the format satisf<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>d."<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;).toString(),String endValue)  { Integer[] targetPartition </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;try</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> startTime =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; formatter.get().parse(beginValue).getTime();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> endTime =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; formatter.get().parse(endValue).getTime();     Calendar <a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a> </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Calendar.getInstance();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> <a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a>Time =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a>.getTimeInMil<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>s();     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>mitDate = <a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a>Time - sLastTime *<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; oneDay;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;long</span> diffDays = (<a href="https://www.jb51.cc/tag/Now/" target="_blank" >Now</a>Time - startTime) / (1000 * 60 * 60 * 24) + 1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(diffDays-sLastTime <= 0 || diffDays<0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; ){         Integer [] re </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Integer[1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;];         re[</span>0] = 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         targetPartition </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; re ;     }</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;{         Integer [] re </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         Integer begin </span>= 0,end = 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         end </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;.cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(beginValue);         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;bo<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>ean</span> has<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>mit = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;false</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(endTime-<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>mitDate > 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;){             endTime </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; <a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>mitDate;             has<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>mit </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;true</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;         }         begin </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;this</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;.cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(formatter.get().format(endTime));         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(begin == <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span> || end == <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;){             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; re;         }         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span> (end >=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; begin) {             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> len = end-begin+1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;(has<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>mit){                 re </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Integer[len+1<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;];                 re[</span>0] = 0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;                 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i =0;i<len;i++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;){                     re[i</span>+1]=begin+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i;                 }             }</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;{                 re </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Integer[len];                 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i=0;i<len;i++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;){                     re[i]</span>=begin+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i;                 }             }             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; re;         }</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;{             </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; re;         }     } } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;catch</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; (ParseException e) {     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;throw</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Ille<a href="https://www.jb51.cc/tag/gal/" target="_blank" >gal</a>ArgumentException(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> StringBuilder().append("endValue:").append(endValue).append(" Please check if the format satisf<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>d."<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;).toString(),e); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; targetPartition;

}

<span >public <span >voID<span > setsPartionDay(String sPartionDay) {
<span >this.sPartionDay =<span > sPartionDay;
}
<span >public <span >voID<span > setDateFormat(String dateFormat) {
<span >this.dateFormat =<span > dateFormat;
}
<span >public<span > String getsLastDay() {
<span >return<span > sLastDay;
}
<span >public <span >voID<span > setsLastDay(String sLastDay) {
<span >this.sLastDay =<span > sLastDay;
}
}

8. 一致性哈希分片

1)首先求出MysqL服务器(节点)的哈希值,并将其配置到0~2^32的圆(continuum)上。

2)为每台MysqL服务器物理节点虚拟出多个虚拟节点,并计算hash值映射到相同的圆上。

3)然后从数据映射到的MysqL服务器虚拟节点的位置开始顺时针查找,将数据保存到找到的第一个MysqL服务器上。如果超过232仍然找不到服务器,就会保存到第一台MysqL服务器上。

 

在rule.xml里面的配置:

ID murmur 0 2 160 节点的权重,没有指定权重的节点默认是1。以propertIEs文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西

对应代码:

<span >import<span > java.io.BufferedReader;
<span >import
<span > java.io.ByteArrayinputStream;
<span >import
<span > java.io.ByteArrayOutputStream;
<span >import
<span > java.io.file;
<span >import
<span > java.io.fileinputStream;
<span >import
<span > java.io.fileNotFoundException;
<span >import
<span > java.io.fileOutputStream;
<span >import
<span > java.io.IOException;
<span >import
<span > java.io.inputStream;
<span >import
<span > java.io.inputStreamReader;
<span >import
<span > java.io.OutputStream;
<span >import
<span > java.nio.charset.Charset;
<span >import
<span > java.util.ArrayList;
<span >import
<span > java.util.HashMap;
<span >import
<span > java.util.List;
<span >import
<span > java.util.Map;
<span >import
<span > java.util.PropertIEs;
<span >import
<span > java.util.sortedMap;
<span >import
<span > java.util.TreeMap;

<span >import<span > com.Google.common.hash.HashFunction;
<span >import<span > com.Google.common.hash.Hashing;

<span >import<span > io.mycat.config.model.rule.RuleAlgorithm;
<span >import<span > io.mycat.util.exception.MurmurHashException;

<span >/**<span >

consistancy hash,murmur hash

implemented by Guava

<span >@author<span > wuzhih

<span >*/
<span >public <span >class PartitionByMurmurHash <span >extends AbstractPartitionAlgorithm <span >implements<span > RuleAlgorithm {
<span >private <span >static <span >final <span >int DEFAulT_VIRTUAL_BUCKET_TIMES=160<span >;
<span >private <span >static <span >final <span >int DEFAulT_WEIGHT=1<span >;
<span >private <span >static <span >final Charset DEFAulT_CHARSET=Charset.forname("UTF-8"<span >);

<span >private <span >int<span > seed;
<span >private <span >int<span > count;
<span >private <span >int virtualBucketTimes=<span >DEFAulT_VIRTUAL_BUCKET_TIMES;
<span >private Map<Integer,Integer> weightmap=<span >new HashMap<><span >();
<span >//<span > private String bucketMapPath;

<span >private<span > HashFunction hash;

<span >private SortedMap<Integer,Integer><span > bucketMap;
@OverrIDe
<span >public <span >voID<span > init() {
<span >try<span >{
bucketMap=<span >new TreeMap<><span >();
<span >//<span > boolean serializableBucketMap=bucketMapPath!=null && bucketMapPath.length()>0;
<span >//<span > if(serializableBucketMap){
<span >//<span > file bucketMapfile=new file(bucketMapPath);
<span >//<span > if(bucketMapFile.exists() && bucketMapFile.length()>0){
<span >//<span > loadBucketMapfile();
<span >//<span > return;
<span >//<span > }
<span >//<span > }
<span > generateBucketMap();
<span >//<span > if(serializableBucketMap){
<span >//<span > storeBucketMap();
<span >//<span > }
}<span >catch<span >(Exception e){
<span >throw <span >new<span > MurmurHashException(e);
}
}

<span >private <span >voID<span > generateBucketMap(){
hash=Hashing.murmur3_32(seed);<span >//<span >计算一致性哈希的对象
<span >for(<span >int i=0;i<count;i++){<span >//<span >构造一致性哈希环,用TreeMap表示
StringBuilder hashname=<span >new StringBuilder("SHARD-"<span >).append(i);
<span >for(<span >int n=0,shard=virtualBucketTimes*getWeight(i);n<shard;n++<span >){
bucketMap.put(hash.hashUnencodedChars(hashname.append("-NODE-"<span >).append(n)).asInt(),i);
}
}
weightmap=<span >null<span >;
}
<span >//<span > private voID storeBucketMap() throws IOException{
<span >//<span > try(OutputStream store=new fileOutputStream(bucketMapPath)){
<span >//<span > PropertIEs props=new PropertIEs();
<span >//<span > for(Map.Entry entry:bucketMap.entrySet()){
<span >//<span > props.setProperty(entry.getKey().toString(),entry.getValue().toString());
<span >//<span > }
<span >//<span > props.store(store,null);
<span >//<span > }
<span >//<span > }
<span >//<span > private voID loadBucketMapfile() throws fileNotFoundException,IOException{
<span >//<span > try(inputStream in=new fileinputStream(bucketMapPath)){
<span >//<span > PropertIEs props=new PropertIEs();
<span >//<span > props.load(in);
<span >//<span > for(Map.Entry entry:props.entrySet()){
<span >//<span > bucketMap.put(Integer.parseInt(entry.getKey().toString()),Integer.parseInt(entry.getValue().toString()));
<span >//<span > }
<span >//<span > }
<span >//<span > }
<span >/**<span >

得到桶的权重,桶就是实际存储数据的DB实例从0开始的桶编号为key,权重为值,权重默认为1。键值必须都是整数
<span >@param
<span > bucket
<span >@return

<span >*/

<span >private
<span >int
getWeight(<span >int
<span > bucket){
Integer w
=<span >weightmap.get(bucket);
<span >if
(w==<span >null
<span >){
w
=<span >DEFAulT_WEIGHT;
}
<span >return
<span > w;
}
<span >/**
<span >创建murmur_hash对象的种子,默认0
<span >@param
<span > seed
<span >*/

<span >public
<span >voID
setSeed(<span >int
<span > seed){
<span >this
.seed=<span >seed;
}
<span >/**
<span >节点的数量
<span >@param
<span > count
<span >*/

<span >public
<span >voID
setCount(<span >int
<span > count) {
<span >this
.count =<span > count;
}
<span >/**
<span >虚拟节点倍数,virtualBucketTimes*count就是虚拟结点数量
<span >@param
<span > virtualBucketTimes
<span >*/

<span >public
<span >voID
setVirtualBucketTimes(<span >int
<span > virtualBucketTimes){
<span >this
.virtualBucketTimes=<span >virtualBucketTimes;
}
<span >/**
<span >节点的权重,没有指定权重的节点默认是1。以propertIEs文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替
<span >@param
<span > weightmapPath
<span >@throws
<span > IOException
<span >@throws

<span >*/

<span >public
<span >voID
setWeightmapfile(String weightmapPath) <span >throws
<span > IOException{
PropertIEs props=<span >new<span > PropertIEs();
<span >try(BufferedReader reader=<span >new BufferedReader(<span >new inputStreamReader(<span >this<span >.getClass().getClassLoader().getResourceAsstream(weightmapPath),DEFAulT_CHARSET))){
props.load(reader);
<span >for<span >(Map.Entry entry:props.entrySet()){
<span >int weight=<span >Integer.parseInt(entry.getValue().toString());
weightmap.put(Integer.parseInt(entry.getKey().toString()),weight>0?weight:1<span >);
}
}
}
<span >//<span > /*
<span >//<span >
保存一致性hash的虚拟节点文件路径。
<span >//<span > 如果这个文件不存在或是空文件就按照指定的count,weightmapfile等构造新的MurmurHash数据结构并保存到这个路径的文件里。
<span >//<span >
如果这个文件已存在且不是空文件就加载这个文件里的内容作为MurmurHash数据结构,此时其它参数都忽略。
<span >//<span > 除第一次以外在之后增加节点时可以直接修改这个文件,不过不推荐这么做。如果节点数量变化了,推荐删除这个文件。
<span >//<span >
可以不指定这个路径,不指定路径时不会保存murmur hash
<span >//<span > @param bucketMapPath
<span >//<span >
/
<span >//<span > public voID setBucketMapPath(String bucketMapPath){
<span >//<span > this.bucketMapPath=bucketMapPath;
<span >//<span > }
<span > @OverrIDe
<span >public<span > Integer calculate(String columnValue) {
SortedMap<Integer,Integer> tail =<span > bucketMap.tailMap(hash.hashUnencodedChars(columnValue).asInt());
<span >if<span > (tail.isEmpty()) {
<span >return<span > bucketMap.get(bucketMap.firstKey());
}
<span >return<span > tail.get(tail.firstKey());
}

@OverrIDe
<span >public <span >int<span > getPartitionNum() {
<span >int nPartition = <span >this<span >.count;
<span >return<span > nPartition;
}

<span >private <span >static <span >voID hashtest() <span >throws<span > IOException{
PartitionByMurmurHash hash=<span >new<span > PartitionByMurmurHash();
hash.count=10;<span >//<span >分片数
<span > hash.init();

 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span>[] bucket=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;[hash.count]; Map</span><Integer,<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a><Integer>> hashed=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> HashMap<><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;(); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> total=1000_0000;<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;数据量</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> c=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i=100_0000;i<total+100_0000;i++){<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;假设分片键从100万开始</span>     c++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> h=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;hash.cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(Integer.toString(i));     bucket[h]</span>++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a></span><Integer> <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;hashed.get(h);     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;if</span>(<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>==<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;){         <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a></span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> Array<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a><><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;();         hashed.put(h,<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>);     }     <a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>.add(i); } Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(c</span>+"   "+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;total); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span> d=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; c</span>=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> <a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>"index    bucket   ratio"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; i:bucket){     d</span>+=i/(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)total;     c</span>+=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i;     Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x</span>+++"  "+i+"   "+(i/(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)total)); } Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(d</span>+"  "+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;c); Propert<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>s props</span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; Propert<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>s(); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;(Map.Entry entry:hash.bucketMap.entrySet()){     props.setProperty(entry.getKey().toString(),entry.getValue().toString()); } ByteArrayOutputStream out</span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; ByteArrayOutputStream(); props.store(out,</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;n<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>l</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;); props.clear(); props.load(</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; ByteArray<a href="https://m.jb51.cc/tag/input/" target="_blank" >input</a>Stream(out.toByteArray())); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(props); Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>"****************************************************"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;);

<span >//<span > rehashTest(hashed.get(0));
<span > }
<span >private <span >static <span >voID rehashTest(List<span > partition){
PartitionByMurmurHash hash=<span >new<span > PartitionByMurmurHash();
hash.count=12;<span >//<span >分片数
<span > hash.init();

 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span>[] bucket=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;new</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;[hash.count]; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> total=partition.size();<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;数据量</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> c=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> i:partition){<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000"&gt;假设分片键从100万开始</span>     c++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;;     </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> h=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;hash.cal<a href="https://www.jb51.cc/tag/cula/" target="_blank" >cula</a>te(Integer.toString(i));     bucket[h]</span>++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; } Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(c</span>+"   "+<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;total); c</span>=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span> <a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x=0<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;; Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(</span>"index    bucket   ratio"<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;for</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt; i:bucket){     c</span>+=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;i;     Sy<a href="https://www.jb51.cc/tag/stem/" target="_blank" >stem</a>.out.println(<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>x</span>+++"  "+i+"   "+(i/(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff"&gt;double</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"&gt;)total)); }

}
<span >public <span >static <span >voID main(String[] args) <span >throws<span > IOException {
hashtest();
}
}

总结

以上是内存溢出为你收集整理的Mysql系列六:(Mycat分片路由原理、Mycat常用分片规则及对应源码介绍)全部内容,希望文章能够帮你解决Mysql系列六:(Mycat分片路由原理、Mycat常用分片规则及对应源码介绍)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1152510.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)