Mycat 分片算法 PartitionByHotDate

该算法根据时间分片,热数据存储在索引为 0 的dataNode中,其余数据根据sPartionDay进行分片存储,用户可配置属性 dataFormat、 sLastDay、 sPartionDay。

  • dataFormat: 时间解析格式;
  • sLastDay:热数据范围,如该值配置为10,则表示从现在往前推10天的数据为热点数据。将存储在第一个dataNode中,需要   注意的是如果插入数据晚于当前时间,如当前2019-03-12,columnValue为 2019-04-15,该数据也是写入第一个dataNode。
  • sPartionDay:当不是热数据时的分片间隔天数。
     

如下配置:

<function name="partition-by-hot-date" class="io.mycat.route.function.PartitionByHotDate">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sLastDay">10</property>
    <property name="sPartionDay">10</property>
</function>

当sPartionDay值为10,sLastDay值为10,当前时间是2019-03-12,则分片结果如下 :

  • 2019-03-03 (包括)以后的数据,存储在第一个dataNode;
  • 2019-02-21(包括)~ 2019-03-02,存储在第二个dataNode;
  • 2019-02-11(包括)~2019-02-20,存储在第三个dataNode;
    依次类推,如果时间太过久远,计算出来的dataNode索引超出了用户配置的dataNode个数,则抛出异常
    “SQLNonTransientException: Can't find a valid data node for specified node index”

PartitionByHotDate的init 和 calculate 方法如下:
 

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

/**
 * 涉及变量说明:
 * sLastTime:设置多少天以内的数据是热数据,如该属性配置为10,则表示10天内的数据为热数据,存储在dataNode = 0 的节点中,超过 10 天的进行分片存储
 * sPartionDay: 设置多少天数据存储在一个分片中。
 * oneDay: 一天的毫秒数 1000 * 60 * 60 * 24
 * partionTime: init 方法中初始化 Integer.parseInt(sPartionDay) * oneDay,表示多少天的数据是一个分片。
 */
@Override
public Integer calculate(String columnValue)  {
    Integer targetPartition = -1;
    try {
        long targetTime = formatter.get().parse(columnValue).getTime();
        Calendar now = Calendar.getInstance();
        long nowTime = now.getTimeInMillis();
        
        beginDate = nowTime - sLastTime * oneDay;
        
        long diffDays = (nowTime - targetTime) / (1000 * 60 * 60 * 24) + 1;
        if(diffDays-sLastTime <= 0 || diffDays<0 ){
            targetPartition = 0;
        }else{
            targetPartition = (int) ((beginDate - targetTime) / partionTime) + 1;
        }
        
        LOGGER.debug("PartitionByHotDate calculate for " + columnValue + " return " + targetPartition);
        return targetPartition;
    } catch (ParseException e) {
        throw new IllegalArgumentException(new StringBuilder().append("columnValue:").append(columnValue).append(" Please check if the format satisfied.").toString(),e);
    }
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wyr2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值