Mycat 分片算法 PartitionByHotDate

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

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

如下配置:


    yyyy-MM-dd
    10
    10

当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() {
            @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);
    }
}

 

 

你可能感兴趣的:(源码,数据库中间件(Mycat))