spark自定义累加器

package lcy.spark.sharedVariables.accumulators;
 
import org.apache.spark.SparkContext;
import org.apache.spark.api.java.function.MapFunction;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Encoders;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.util.AccumulatorV2;
 
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
 
/**
 * 自定义累加器
 * */
public class CustomAccumulatorDemo {
 
    // 需要注意的是累加操作不能依赖顺序,比如类似于StringAccumulator这种则会得到错误的结果
    public static class BigIntegerAccumulator extends AccumulatorV2<BigInteger, BigInteger> {
 
        private BigInteger num = BigInteger.ZERO;
 
        public BigIntegerAccumulator() {
        }
 
        public BigIntegerAccumulator(BigInteger num) {
            this.num = new BigInteger(num.toString());
        }
 
        @Override
        public boolean isZero() {
            return num.compareTo(BigInteger.ZERO) == 0;
        }
 
        @Override
        public AccumulatorV2<BigInteger, BigInteger> copy() {
            return new BigIntegerAccumulator(num);
        }
 
        @Override
        public void reset() {
            num = BigInteger.ZERO;
        }
 
        @Override
        public void add(BigInteger num) {
            this.num = this.num.add(num);
        }
 
        @Override
        public void merge(AccumulatorV2<BigInteger, BigInteger> other) {
            num = num.add(other.value());
        }
 
        @Override
        public BigInteger value() {
            return num;
        }
    }
 
    public static void main(String[] args) {
 
        SparkSession spark = SparkSession.builder().master("local[*]").getOrCreate();
        SparkContext sc = spark.sparkContext();
 
        // 直接new自定义的累加器
        BigIntegerAccumulator bigIntegerAccumulator = new BigIntegerAccumulator();
        // 然后在SparkContext上注册一下
        sc.register(bigIntegerAccumulator, "bigIntegerAccumulator");
 
        List<BigInteger> numList = Arrays.asList(new BigInteger("9999999999999999999999"), new BigInteger("9999999999999999999999"), new BigInteger("9999999999999999999999"));
        Dataset<BigInteger> num = spark.createDataset(numList, Encoders.kryo(BigInteger.class));
        Dataset<BigInteger> num2 = num.map((MapFunction<BigInteger, BigInteger>) x -> {
            bigIntegerAccumulator.add(x);
            return x;
        }, Encoders.kryo(BigInteger.class));
 
        num2.count();
        System.out.println("bigIntegerAccumulator: " + bigIntegerAccumulator.value());
 
    }
 
}

注意:

  • 在driver获取累加器的值用bigIntegerAccumulator.value

  • 在executor获取累加器的值用bigIntegerAccumulator

  • 累加器不会改变我们RDD的Lazy的特性,之后再Action之后完成计算和更新。

  • 但是假如出现两个Action公用一个转化操作,如map,在map里面进行累加器累加,那么每次action都会累加,造成某些我们不需要的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spark内置了Long和Double类型的累加器。 经过一系列的transform操作构成了DAG,需要通过一个action操作来触发累加器的计算。在action操作之前调用累加器的value方法来查看其数值是没有任何变化的。 累加器可以用于在过滤RDD时进行计数,并最后计算剩下整数的和。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Spark定义累加器的使用实例详解](https://download.csdn.net/download/weixin_38612304/14092212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Spark累加器(Accumulator)使用详解](https://blog.csdn.net/zhaojianting/article/details/80228093)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Spark2.10中使用累加器、注意点以及实现自定义累加器](https://blog.csdn.net/u013468917/article/details/70617085)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小手追梦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值