admin管理员组文章数量:1596344
关于分片算法 AutoPartitionByLong,rule.xml 的配置为:
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
<property name="defaultNode">2</property>
</function>
init的实现逻辑如下:
public void init() {
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)
.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) {
}
}
}
可以看出,该段代码主要是完成 mapFile 配置文件的解析,读取节点索引与数值范围的映射关系,用于在 calculate 方法执行时计算dataNode节点。根据代码,可以看出该文件配置需要严格按照如下模板:
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
calculate方法实现为:
public Integer calculate(String 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);
}
}
通过代码可以看出,计算节点根据autopartition-long.txt 的解析结果,遍历得出columnValue应该存储在哪个节点。如果遍历结束没有找到匹配的节点,即数据超过范围,此时将使用defaultNode存储,如果没有配置defaultNode,该值初始值为 -1 ,则会返回 rst,即返回null。那么根据会抛出异常信息“can't find any valid datanode”,如下:
Integer nodeIndex = algorithm.calculate(pair.colValue);
if(nodeIndex == null) {
String msg = "can't find any valid datanode :" + tableConfig.getName() + " -> "
+ tableConfig.getPartitionColumn() + " -> " + pair.colValue;
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
总结:
1、如果数据在配置的范围内,存储在配置的节点中;
2、如果数据超出范围,且配置defaultNode,则存储在defaultNode中;
3、如果超出范围,且没有配置defaultNode,则抛出异常;
本文标签: 算法分片MyCatAutoPartitionByLong
版权声明:本文标题:Mycat 分片算法 AutoPartitionByLong 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1728256285a1151053.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论