spark自定义Accumulator高级应用(JAVA)

来源:互联网 发布:扇贝听力没有mac版 编辑:程序博客网 时间:2024/05/16 09:49
public class SessionAggrStatAccumulator implements AccumulatorParam<String> {    private static final long serialVersionUID = 6311074555136039130L;    /**     * zero方法,其实主要用于数据的初始化     * 那么,我们这里,就返回一个值,就是初始化中,所有范围区间的数量,都是0     * 各个范围区间的统计数量的拼接,还是采用一如既往的key=value|key=value的连接串的格式     */    public String zero(String initialValue) {        return Constants.SESSION_COUNT + "=0|"                + Constants.TIME_PERIOD_1s_3s + "=0|"                + Constants.TIME_PERIOD_4s_6s + "=0|"                + Constants.TIME_PERIOD_7s_9s + "=0|"                + Constants.TIME_PERIOD_10s_30s + "=0|"                + Constants.TIME_PERIOD_30s_60s + "=0|"                + Constants.TIME_PERIOD_1m_3m + "=0|"                + Constants.TIME_PERIOD_3m_10m + "=0|"                + Constants.TIME_PERIOD_10m_30m + "=0|"                + Constants.TIME_PERIOD_30m + "=0|"                + Constants.STEP_PERIOD_1_3 + "=0|"                + Constants.STEP_PERIOD_4_6 + "=0|"                + Constants.STEP_PERIOD_7_9 + "=0|"                + Constants.STEP_PERIOD_10_30 + "=0|"                + Constants.STEP_PERIOD_30_60 + "=0|"                + Constants.STEP_PERIOD_60 + "=0";    }    /**     * addInPlaceaddAccumulator     * 可以理解为是一样的     *     * 这两个方法,其实主要就是实现,v1可能就是我们初始化的那个连接串     * v2,就是我们在遍历session的时候,判断出某个session对应的区间,然后会用Constants.TIME_PERIOD_1s_3s     * 所以,我们,要做的事情就是     * v1中,找到v2对应的value,累加1,然后再更新回连接串里面去     *     */    public String addAccumulator(String v1, String v2) {        return add(v1,v2);    }    public String addInPlace(String v1, String v2) {        return add(v1,v2);    }    /**     * session统计计算逻辑     * @param v1 连接串     * @param v2 范围区间     * @return 更新以后的连接串     */    private String add(String v1, String v2){        // 校验:v1为空的话,直接返回v2        if(StringUtils.isEmpty(v1)) {            return v2;        }        // 使用StringUtils工具类,从v1中,提取v2对应的值,并累加1        String oldValue = StringUtils.getFieldFromConcatString(v1, "\\|", v2);        if(oldValue != null) {            // 将范围区间原有的值,累加1            int newValue = Integer.valueOf(oldValue) + 1;            // 使用StringUtils工具类,将v1中,v2对应的值,设置成新的累加后的值            return StringUtils.setFieldInConcatString(v1, "\\|", v2, String.valueOf(newValue));        }        return v1;    }

}

工具类:

/** * 字符串工具类 * @author Administrator * */public class StringUtils {   /**    * 判断字符串是否为空    * @param str 字符串    * @return 是否为空    */   public static boolean isEmpty(String str) {      return str == null || "".equals(str);   }      /**    * 判断字符串是否不为空    * @param str 字符串    * @return 是否不为空    */   public static boolean isNotEmpty(String str) {      return str != null && !"".equals(str);   }      /**    * 截断字符串两侧的逗号    * @param str 字符串    * @return 字符串    */   public static String trimComma(String str) {      if(str.startsWith(",")) {         str = str.substring(1);      }      if(str.endsWith(",")) {         str = str.substring(0, str.length() - 1);      }      return str;   }      /**    * 补全两位数字    * @param str    * @return    */   public static String fulfuill(String str) {      if(str.length() == 2) {         return str;      } else {         return "0" + str;      }   }      /**    * 从拼接的字符串中提取字段    * @param str 字符串    * @param delimiter 分隔符     * @param field 字段    * @return 字段值    */   public static String getFieldFromConcatString(String str,          String delimiter, String field) {      try {         String[] fields = str.split(delimiter);         for(String concatField : fields) {            // searchKeywords=|clickCategoryIds=1,2,3            if(concatField.split("=").length == 2) {               String fieldName = concatField.split("=")[0];               String fieldValue = concatField.split("=")[1];               if(fieldName.equals(field)) {                  return fieldValue;               }            }         }      } catch (Exception e) {         e.printStackTrace();      }      return null;   }      /**    * 从拼接的字符串中给字段设置值    * @param str 字符串    * @param delimiter 分隔符     * @param field 字段名    * @param newFieldValue 新的field    * @return 字段值    */   public static String setFieldInConcatString(String str,          String delimiter, String field, String newFieldValue) {      String[] fields = str.split(delimiter);            for(int i = 0; i < fields.length; i++) {         String fieldName = fields[i].split("=")[0];         if(fieldName.equals(field)) {            String concatField = fieldName + "=" + newFieldValue;            fields[i] = concatField;            break;         }      }            StringBuffer buffer = new StringBuffer("");      for(int i = 0; i < fields.length; i++) {         buffer.append(fields[i]);         if(i < fields.length - 1) {            buffer.append("|");           }      }            return buffer.toString();   }   }

测试类:

public class AccumuletorTest {    public static void main(String[] args) {        // 构建Spark上下文        SparkConf conf = new SparkConf()                .setAppName("AccumuletorTest")                .setMaster("local");        JavaSparkContext sc = new JavaSparkContext(conf);        final Accumulator<String> sessionAggrStatAccumulator = sc.accumulator(                "", new SessionAggrStatAccumulator());        List<Long> seq= new ArrayList<Long>();        for (int i = 0; i < 1000; i++) {            seq.add(Long.valueOf((int) (Math.random() * 1000)));        }        JavaRDD<Long> rdd=sc.parallelize(seq);        //必须用RDD执行        rdd.foreach(new VoidFunction<Long>() {            public void call(Long aLong) throws Exception {                sessionAggrStatAccumulator.add(Constants.SESSION_COUNT);                calculateVisitLength(aLong);                calculateStepLength(aLong);            }            /**             * 计算访问时长范围             * @param visitLength             */            private void calculateVisitLength(long visitLength) {                if (visitLength >= 1 && visitLength <= 3) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_1s_3s);                } else if (visitLength >= 4 && visitLength <= 6) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_4s_6s);                } else if (visitLength >= 7 && visitLength <= 9) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_7s_9s);                } else if (visitLength >= 10 && visitLength <= 30) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_10s_30s);                } else if (visitLength > 30 && visitLength <= 60) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_30s_60s);                } else if (visitLength > 60 && visitLength <= 180) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_1m_3m);                } else if (visitLength > 180 && visitLength <= 600) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_3m_10m);                } else if (visitLength > 600 && visitLength <= 1800) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_10m_30m);                } else if (visitLength > 1800) {                    sessionAggrStatAccumulator.add(Constants.TIME_PERIOD_30m);                }            }            /**             * 计算访问步长范围             * @param stepLength             */            private  void calculateStepLength(long stepLength) {                if (stepLength >= 1 && stepLength <= 3) {                    sessionAggrStatAccumulator.add(Constants.STEP_PERIOD_1_3);                } else if (stepLength >= 4 && stepLength <= 6) {                    sessionAggrStatAccumulator.add(Constants.STEP_PERIOD_4_6);                } else if (stepLength >= 7 && stepLength <= 9) {                    sessionAggrStatAccumulator.add(Constants.STEP_PERIOD_7_9);                } else if (stepLength >= 10 && stepLength <= 30) {                    sessionAggrStatAccumulator.add(Constants.STEP_PERIOD_10_30);                } else if (stepLength > 30 && stepLength <= 60) {                    sessionAggrStatAccumulator.add(Constants.STEP_PERIOD_30_60);                } else if (stepLength > 60) {                    sessionAggrStatAccumulator.add(Constants.STEP_PERIOD_60);                }            }        });        System.out.println("accumuletor2:"+sessionAggrStatAccumulator.value());    }}

1 1
原创粉丝点击