spark 并行计算 前n项和

      在单线程计算中前n项和计算一直没有障碍,随着数据量的膨胀,单线程计算已经无法满足数据计算。计算逐渐被迁移到spark或者hadoop集群上并行计算,但是无论spark还是hadoop并行计算前n项和一直是一个痛点,只能做到每个结点或者容器上的前N项和,却无法做到计算全局前N项和。

     现提供一种解决方案,希望大家多多指正。计算过程需要两次便利全部数据。第一次遍历计算每个容器中数据加和结果,并返回paritition的id和容器中数据家和。第二次遍历才计算前Nx项和的家和。现有java版本实现,如需要scala版本或者python版本实现请私信本人。

public void sum(){
        SparkConf conf = new SparkConf().setMaster("local").setAppName("temp");
        JavaSparkContext ctx  = new JavaSparkContext(conf);
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        JavaRDD<Integer> soureceRdd = ctx.parallelize(list,4).cache();
        List<Tuple2<Integer, Integer>> partitionSub = soureceRdd.mapPartitionsWithIndex(new Function2<Integer, Iterator<Integer>, Iterator<Tuple2<Integer, Integer>>>() {
            private static final long serialVersionUID = 1L;
            @Override
            public Iterator<Tuple2<Integer, Integer>> call(Integer partitionId, Iterator<Integer> v2) throws Exception {
                Integer result = 0;
                while(v2.hasNext()){
                    result += v2.next();
                }
                return Arrays.asList(new Tuple2<Integer, Integer>(partitionId,result)).iterator();
            }
        }, true).collect();
        Map<Integer, Integer> paritionSum = this.sumPriPartition(partitionSub);
        JavaRDD<Integer> x = soureceRdd.mapPartitionsWithIndex(new Function2<Integer, Iterator<Integer>, Iterator<Integer>>() {
            private static final long serialVersionUID = 1L;
            @Override
            public Iterator<Integer> call(Integer v1, Iterator<Integer> v2) throws Exception {
                List<Integer> result = new CopyOnWriteArrayList<Integer>();
                Integer proPartitionSum = paritionSum.get(v1); 
                while(v2.hasNext()){
                    proPartitionSum+=v2.next();
                    result.add(proPartitionSum);
                }
                return result.iterator();
            }
        }, true);
    }
    /*结果<partitionId,当前partition之前所有partition数据和>*/
    public Map<Integer, Integer> sumPriPartition(List<Tuple2<Integer, Integer>> list){
        Map<Integer, Integer>  map = new HashMap<Integer, Integer>();
        Integer caluer = 0;
        for(Tuple2<Integer, Integer> tuple: list){
            Integer partitionId = tuple._1;
            map.put(partitionId, caluer);
            caluer+=tuple._2;
        }
        return map;
    }



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值