枚举分片容错性动态扩展

枚举分片之前的《mycat字符串枚举分片示例》中已经介绍过。

使用这种分片策略之后碰到了一个问题:
场景:
使用连锁店的店铺编号枚举分片(第1至第100分布店分在第一个分片,第101至第250分店),全国的连锁店会不断增加。在还没有来得及往配置文件中配置新的店铺编号时,新店铺的数据无法插入到mycat中(mycat会抛出异常can't find datanode for sharding column:SHOP_NO val:SHOP1002 ),而且店铺可能今天加一个新店,明天再加一个新店,难道维护人员每天来给你修改这个枚举店铺编号的配置文件?


解决办法:
不识别的枚举值,路由到一个默认的节点,这样,mycat将新店铺的数据全部插入到默认节点。当不识别的店铺编号达到一定的数量后,比如新增了1000个店铺后,新增一个数据节点,将默认节点上的那1000个店铺的数据整体迁移到新节点上。枚举分片的迁移非常容易,两个命令搞定:
1、默认节点的mysql服务器上执行导出:

mysqldump -uroot -p123456 databasename shop --where=" shop_no in ('shop1001','shop1002'.....,'shop2000') " > /data/shop.sql


2、新节点的mysql服务器上执行导入:

mysql -uroot -p123456 databasename <  /data/shop.sql


修改的代码:
为了支持该方案,对org.opencloudb.route.function.PartitionByFileMap类做修改,增加一个属性

defaultNode,如下:

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

defaultNode的默认值为-1表示不配置默认节点,如果要配置默认节点,需要从配置文件配置defaultNode的值,一般是从rule.xml中配置: 


    partition-by-shop_no-enum.txt
    1
    0 

private void initialize() 方法根据defaultNode的值往map中增加defaultNode:

//设置默认节点
if(defaultNode >= 0) {
    app2Partition.put(DEFAULT_NODE, defaultNode);
}

public Integer calculate(String columnValue) 方法:

Integer pid = app2Partition.get(value);
if (pid != null) {
    rst = pid;
} else {
    rst =app2Partition.get(DEFAULT_NODE);
}
return rst;

你可能感兴趣的:(开发技巧经验分享,分片,枚举分片,动态扩容)