mysql diffdays_Mysql系列六:Mycat常用分片规则介绍和对应源码

一、Mycat常用分片规则

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

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

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

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

下面基于源码来介绍Mycat的常用分片规则, 源码地址

二、Mycat常用分片规则介绍

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

id

func1

1,1,2,3,1

128,128,128,128,128

1. 自动范围分片

在rule.xml里面的配置:

id

rang-long

autopartition-long.txt

说明:

有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;

@Override

public void init() {

initialize();

}

public void setMapFile(String mapFile) {

this.mapFile = mapFile;

}

@Override

public 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.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);

}

}

@Override

public Integer[] calculateRange(String beginValue, String endValue) {

return AbstractPartitionAlgorithm.calculateSequenceRange(this, beginValue, endValue);

}

@Override

public int getPartitionNum() {

// int nPartition = longRongs.length;

/*

* fix #1284 这里的统计应该统计Range的nodeIndex的distinct总数

*/

Set distNodeIdxSet = new HashSet();

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 longRangeList = new LinkedList();

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)

.trim());

longRangeList

.add(new LongRange(nodeId, longStart, longEnd));

}

longRongs = longRangeList.toArray(new LongRange[longRangeList

.size()]);

} catch (Exception e) {

if (e instanceof RuntimeException) {

throw (RuntimeException) e;

} else {

throw new RuntimeException(e);

}

} finally {

try {

in.close();

} catch (Exception e2) {

}

}

}

public int getDefaultNode() {

return defaultNode;

}

public void setDefaultNode(int defaultNode) {

this.defaultNode = defaultNode;

}

static class LongRange {

public final int nodeIndx;

public final long valueStart;

public final long valueEnd;

public LongRange(int nodeIndx, long valueStart, long valueEnd) {

super();

this.nodeIndx = nodeIndx;

this.valueStart = valueStart;

this.valueEnd = valueEnd;

}

}

}

View Code

2. 枚举分片

把数据分类存储

在rule.xml里面的配置:

sharding_id

hash-int

partition-hash-int.txt

0

说明: 找不到分片时设置容错规则,把数据插入到默认分片 0 里面

对应代码:

package io.mycat.route.function;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Map;

import java.util.Set;

import io.mycat.config.model.rule.RuleAlgorithm;

/**

*

* @author mycat

*/

public class PartitionByFileMap extends AbstractPartitionAlgorithm implements RuleAlgorithm {

private String mapFile;

private Map app2Partition;

/**

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

*/

private int type;

/**

* 默认节点在map中的key

*/

private static final String DEFAULT_NODE = "DEFAULT_NODE";

/**

* 默认节点:小于0表示不设置默认节点,大于等于0表示设置默认节点

*

* 默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点

* 如果不配置默认节点(defaultNode值小于0表示不配置默认节点),碰到

* 不识别的枚举值就会报错,

* like this:can't find datanode for sharding column:column_name val:ffffffff

*/

private int defaultNode = -1;

@Override

public void init() {

initialize();

}

public void setMapFile(String mapFile) {

this.mapFile = mapFile;

}

public void setType(int type) {

this.type = type;

}

public void setDefaultNode(int defaultNode) {

this.defaultNode = defaultNode;

}

@Override

public Integer calculate(String columnValue) {

try {

Object value = columnValue;

if (type == 0) {

value = Integer.valueOf(columnValue);

}

Integer rst = null;

Integer pid = app2Partition.get(value);

if (pid != null) {

rst = pid;

} else {

rst = app2Partition.get(DEFAULT_NODE);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值