spark aggregate()函数解决java.io.NotSerializableException问题

在使用练习spark  aggregate()函数时出现的问题。

其中aggregate()函数的作用是:aggregate()函数返回值类型不必与所操作的RDD类型相同。使用aggregate()时,需要提供我们期待返回的类型的初始值。然后通过一个函数把RDD中的元素合并起来放入累加器。考虑到每个节点是在本地进行累加的,最终,还需要提供第二个函数来将累加器两两合并。

public class Text implements Serializable {

//声明变量

    public int total;

    public int num;

//构造类

    public Text(int total,int num){

           this.total=total;
           this.num=num;

        }

//求平均数方法

    public double avg(){
        return total/(double)num;

    }

//call中求初始化类中的值;如果Text(0,0)则a.total = 0 ,a.num = 0;如果Text(1,1)则a.total = 1,a.num = 1

    static Function2<Text,Integer,Text> addAndCount=
        new Function2<Text, Integer, Text>() {
            public Text call(Text a, Integer x) throws Exception {
                a.total+=x;
                a.num+=1;
                return a;
            }

    };

//call中第一个类为第一个函数的返回值,第二个类为list的长度+初始化total;num的值等于list相加结果+初始化num

    static Function2<Text,Text,Text> combine=
        new Function2<Text, Text, Text>() {
            public Text call(Text a, Text b) throws Exception {
                a.total+=b.total;
                a.num+=b.num;

                return a;

                        //这里的a 对象的值为:total:list的长度+第一个函数的total+初始化total

                                                            num : num的值+第一个函数的num+初始化num

            }

     };

public void static main(String args []){

SparkConf conf = new SparkConf().setAppName("Spark").setMaster("local");

JavaSparkContext sc = new JavaSparkContext(conf);

//初始化类 Text(total,num)

    Text intial =new Text(0,0);//3.5 total : 1+2+3+4+5+6+0+0    num : list.size()+0+0

    Text intial1 =new Text(1,2);//2.3 total : 1+2+3+4+5+6+1+1 num : list.size()+2+2 

//将list或者set转换为RDD

    JavaRDD<Integer> rdd7 =sc.parallelize(Arrays.asList(1, 2, 3, 4, 5, 6));
    Text result7=rdd7.aggregate(intial,addAndCount,combine);

    System.out.println(result7.avg());

    sc.close();

//如果类没有实现Serializable 接口则会报错,实现就可以了。

    }

}


顺便普及一下Serializable 接口的作用:public interface Serializable类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

在我们自定义Text类中,需要实例化类 Text intial = Text(0,0);是报错,可见spark不能对其序列化。

所以当前类需要实现java.io.Serializable接口,那么spark就能使用java的ObjectOutStream来序列化当前类



发布了47 篇原创文章 · 获赞 10 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/fearlessnesszhang/article/details/80225473