此文已由作者张镐薪授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

意思就是,开头为北京的范围在A0000000~A9999999的根据后面的哈希值对5取模平均分布在0,1,2,3,4分片节点上。开头为北京的范围在B0000000以上的根据后面的哈希值对5取模平均分布在5,6,7,8,9分片节点上。开头为上海的范围在00000000~10000000的根据后面的哈希值对2取模平均分布在10,11分片节点上,剩下的开头为上海的,对6取模平均分布在10,11,12,13,14,15上。  这样,在发现某个开头的分片不够用时,可以随时改变分片规则,只要不删除之前的分片规则,就不影响以前数据的访问。在完成数据迁移后,可以删除之前的规则。 实现方法就是采用hashmap存储这些对应关系:

/**
* 首先实现不带范围约定的复合规则,即配置文件中为:
* 北京=0,1,2,3,4
* 上海=10,11
*/public class PartitionByRouteHash extends AbstractPartitionAlgorithm implements RuleAlgorithm {    protected String routeFile;    private Map<String, List<Integer>> routeNodeMap;    protected static final String DEFAULT_NODE = "DEFAULT_NODE";    protected int keyStartIndex;    protected int keyEndIndex;    protected int valueStartIndex;    protected int valueEndIndex;    public void setKeyStartIndex(int keyStartIndex) {        this.keyStartIndex = keyStartIndex;}    public void setKeyEndIndex(int keyEndIndex) {        this.keyEndIndex = keyEndIndex;}    public void setValueStartIndex(int valueStartIndex) {        this.valueStartIndex = valueStartIndex;}    public void setValueEndIndex(int valueEndIndex) {        this.valueEndIndex = valueEndIndex;}    public void setRouteFile(String routeFile) {        this.routeFile = routeFile;}@Override    public void init() {initialize();}@Override    public Integer calculate(String columnValue) {String key = columnValue.substring(keyStartIndex,keyEndIndex);String value = columnValue.substring(valueStartIndex,valueEndIndex);List<Integer> nodes = routeNodeMap.get(key);        if(nodes == null)nodes = routeNodeMap.get(DEFAULT_NODE);BigInteger bigNum = new BigInteger(""+value.hashCode());        return nodes.get((bigNum.mod(BigInteger.valueOf(nodes.size()))).intValue());}    /*** 读取文件,创建哈希表保存对应关系*/private void initialize() {BufferedReader in = null;        try {            // FileInputStream fin = new FileInputStream(new File(fileMapPath));InputStream fin = this.getClass().getClassLoader().getResourceAsStream(routeFile);            if (fin == null) {                throw new RuntimeException("can't find class resource file "+ routeFile);}            in = new BufferedReader(new InputStreamReader(fin));routeNodeMap = new HashMap<String, List<Integer>>();            for (String line = null; (line = in.readLine()) != null;) {line = line.trim();                if (line.startsWith("#") || line.startsWith("//"))                    continue;                int ind = line.indexOf('=');                if (ind < 0)                    continue;                try {String key = line.substring(0, ind).trim();String value = line.substring(ind+1).trim();String []nodes = value.split(",");List<Integer> values = new ArrayList<Integer>();                    for(int i = 0 ; i< nodes.length ; i++){values.add(Integer.parseInt(nodes[i].trim()));}routeNodeMap.put(key,values);} catch (Exception e) {System.out.println("something wrong in the route hash configuration!");}}} catch (Exception e) {            if (e instanceof RuntimeException) {                throw (RuntimeException) e;} else {                throw new RuntimeException(e);}} finally {            try {                in.close();} catch (Exception e2) {}}}
}
/**
* 实现范围约定的复合规则
*/public class PartitionByScalableRouteHash extends PartitionByRouteHash {    private Map<String,Map<String[],List<Integer>>> routeNodeMap;@Override    public void init() {initialize();}@Override    public Integer calculate(String columnValue) {String key = columnValue.substring(keyStartIndex,keyEndIndex);String value = columnValue.substring(valueStartIndex,valueEndIndex);Map<String[],List<Integer>> scaleMap = routeNodeMap.get(key);        if(scaleMap==null){scaleMap = routeNodeMap.get(this.DEFAULT_NODE);}String []ranges = new String[1];        for(String []range:scaleMap.keySet()){            if(range[0].equals(this.DEFAULT_NODE))                continue;            if(range[0].compareTo(value)<0&&range[1].compareTo(value)>0)ranges = range;}        if(ranges.length==1) {            for(String []range:scaleMap.keySet()){                if(range[0].equals(this.DEFAULT_NODE)){ranges = range;                    break;}}}List<Integer> nodes = scaleMap.get(ranges);BigInteger bigNum = new BigInteger(""+value.hashCode());        return nodes.get((bigNum.mod(BigInteger.valueOf(nodes.size()))).intValue());}    private void initialize(){BufferedReader in = null;        try {            // FileInputStream fin = new FileInputStream(new File(fileMapPath));InputStream fin = this.getClass().getClassLoader().getResourceAsStream(routeFile);            if (fin == null) {                throw new RuntimeException("can't find class resource file "+ routeFile);}            in = new BufferedReader(new InputStreamReader(fin));routeNodeMap = new HashMap<String, Map<String[], List<Integer>>>();            for (String line = null; (line = in.readLine()) != null;) {line = line.trim();                if (line.startsWith("#") || line.startsWith("//"))                    continue;                int lb = line.indexOf('('),rb = line.indexOf(')'),mb = line.indexOf(':');                int ind = line.indexOf('=');                if((lb!=-1&&rb!=-1&&mb!=-1)&&(mb<lb||mb>rb||lb>rb||rb>ind)){                    throw new RuntimeException("Wrong format! Error use of (),:,=!");}                if (ind < 0)                    continue;                try {String key = line.substring(0, lb<0?ind:lb).trim();Map<String[],List<Integer>> scaleMap = routeNodeMap.get(key);                    if(scaleMap == null){scaleMap = new HashMap<String[],List<Integer>>();routeNodeMap.put(key,scaleMap);}String[] valueRange = new String[2];                    if(lb!=-1&&rb!=-1&&mb!=-1) {String minValue = line.substring(lb + 1, mb).trim();String maxValue = line.substring(mb + 1, rb).trim();                        if (minValue.length() != maxValue.length() || minValue.compareTo(maxValue) >= 0) {                            throw new RuntimeException("Wrong value range! ");}valueRange[0] = minValue;valueRange[1] = maxValue;}                    else {valueRange[0] = this.DEFAULT_NODE;}String value = line.substring(ind+1).trim();String []nodes = value.split(",");List<Integer> node = new ArrayList<Integer>();                    for(int i = 0 ; i< nodes.length ; i++){node.add(Integer.parseInt(nodes[i].trim()));}scaleMap.put(valueRange,node);} catch (Exception e) {System.out.println("something wrong in the route hash configuration!");}}} catch (Exception e) {            if (e instanceof RuntimeException) {                throw (RuntimeException) e;} else {                throw new RuntimeException(e);}} finally {            try {                in.close();} catch (Exception e2) {}}}}

之后如果想用这个规则,在rule.xml中添加如下配置即可:

<tableRule name="scalable-route-hash"><rule><columns>order_id</columns><algorithm>scalable-route-hash</algorithm></rule></tableRule><function name="scalable-route-hash" class="org.opencloudb.route.function.PartitionByRouteHash"><property name="routeFile">scalable-route-hash.txt</property><property name="keyStartIndex">0</property><property name="keyEndIndex">5</property><property name="valueStartIndex">5</property><property name="valueEndIndex">11</property></function>

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击。

相关文章:
【推荐】 AndroidView的事件分发
【推荐】 Dubbo与HadoopRPC的区别
【推荐】 npm和package.json那些不为常人所知的小秘密

转载于:https://www.cnblogs.com/zyfd/p/9888771.html

MyCat - 使用篇(5)相关推荐

  1. MyCat - 使用篇(1)

    数据库路由中间件MyCat - 使用篇(1) 基本概念 直接介绍概念太枯燥了,还是拿个和背景篇相似的例子介绍  业务场景:客户完成下单,快递员接受并更新运单状态,客户可以随时查看运单状态的任务.一票快 ...

  2. MyCat入门篇-什么是MyCat

    前置文章:MyCat入门篇-什么是MyCat 文章目录 发展历史 功能介绍 读写分离 垂直拆分 水平拆分 MyCat是什么?这个概念可大可小,作为使用者,我的理解是这样的: MyCat是一款开源的数据 ...

  3. 数据库路由中间件MyCat - 使用篇(1)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 基本概念 直接介绍概念太枯燥了,还是拿个和背景篇相似的例子介绍 业务场景:客户完成下单,快递员接受并更新运单 ...

  4. 数据库路由中间件MyCat - 源代码篇(15)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. public static void handle(String stmt, ServerConnectio ...

  5. 数据库路由中间件MyCat - 使用篇(2)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 基本概念 3. 分片 3.1 分片节点(dataNode) 表被水平切分后,每个分片表所在的数据库就是一个分 ...

  6. 数据库路由中间件MyCat - 源代码篇(7)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 3. 连接模块 3.4 FrontendConnection前端连接 构造方法: public Fronte ...

  7. 数据库路由中间件MyCat - 源代码篇(17)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 调用processInsert(sc,schema,sqlType,origSQL,tableName,pr ...

  8. 因为喜欢“对抗”,这位安全首席架构师一年为网易云节省上千万

    欢迎访问网易云社区,了解更多网易技术产品运营经验. 尽管鼻梁被碰坍陷,牙齿被撞裂,"伤痕累累"的沈明星依然喜欢对抗运动,他从骨子里觉得:"男人就应该拼一点,偶尔争强好斗下 ...

  9. 网易云首席安全架构师谈安全新形势:DDoS两三天,游戏玩家数从几万降到几百

    欢迎访问网易云社区,了解更多网易技术产品运营经验. 安全是一个永恒的话题,在业务不断云化.攻击越来越复杂的当下,互联网安全呈现了出什么样的严峻形势?对这些形势,网易云又是如何应对的? 网易云首席安全架 ...

  10. mysql sharding 开源_轻量级Mysql Sharding中间件——Shark

    MyCat - 背景篇(1) 数据库路由中间件MyCat - 背景篇(1) SQL与NoSQL 目前,对于互联网海量数据的存储以及处理,按使用场景,分为OLTP(联机事务处理,比如即时交易,强调快速响 ...

最新文章

  1. (转载)Linux usbtouchscreen驱动分析
  2. 一文读懂Faster RCNN
  3. 利用T-SQL语句创建数据表
  4. 数字图像处理经典论文汇总
  5. java 反射解析xml_java反射获取xml元素
  6. python元类单例_python面向对象和元类的理解
  7. C语言学习笔记---字符串对比函数strspn()和strcspn()函数
  8. Struts xml中Action的method与路径的三种匹配方法
  9. 远程桌面无法复制粘贴问题
  10. 红队常用的防守策略.
  11. “矢量网络分析仪”检测同轴电缆的驻波比(SWR)
  12. java 注解报错_java-注解篇Annotation
  13. ImportError: No module named osgeo解决办法
  14. 最长不含重复字符的字符串
  15. Java-mysql:常用SQL语句及数据库的相关操作
  16. python看网络电视
  17. requests模拟登录微信公众平台手机扫码确认
  18. 智能电灯代码_智能电灯开关与智能电灯泡:您应该购买哪个?
  19. iphone 重用机制
  20. 维护华为服务器的好工具KVM

热门文章

  1. linux解析器错误权限不够,实例解析Linux下目录的权限
  2. 服务器迁移虚拟化实施方案,服务器虚拟化项目P2V实施及迁移方案v8(31页)DOC
  3. 读写分离_摸手教程基于ShardingSphereJDBC的MySQL读写分离
  4. 浙大计算机学院 数字媒体处理与企业智能计算实验室在哪个校区,浙大计算机学院各大实验室介绍.pdf...
  5. 【HDU1251+POJ2001+POJ3630】单词前缀问题整理
  6. $2a开头的是什么加密方式_为什么非对称加密比对称加密慢?
  7. Charles Https 请求 SSL乱码问题 charles unreadable
  8. 二叉树的层序遍历 二叉树
  9. JZ29 最小的K个数 剑指Offer 40
  10. python程序运行原理