Spark 性能调优 序列化之使用kryo trouble shooting常见序列化错误

44 篇文章 1 订阅

Kryo与Spark内部默认序列化机制优缺点

默认优点
默认情况下,Spark内部使用java的序列化机制,ObjectOutputStream/ObjectInputStream
对象输入输出流机制,来进行序列化,这种默认序列化机制的好处在于,处理起来比较方便,不需要我们自己手动做什么事情,只是,在算子里使用到的变量,必须是实现Serializable接口的,可序列化即可。

默认缺点
默认序列机制的效率不高,序列化的速度相对比较慢,序列化以后的数据,占用的内存空间还是比较大
kryo机制
spark支持使用kryo序列化机制,Kryo序列化机制,比默认的java序列化机制,速度要快,序列化后的数据要更小,大概是java序列化机制的1/10

kryo序列化如何使用

// 构建Spark上下文
		SparkConf conf = new SparkConf()
				.setAppName(Constants.SPARK_APP_NAME_SESSION)
				.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
				.registerKryoClasses(new Class[]{
						CategorySortKey.class,
						IntList.class});

首先第一步,在SparkConf中设置一个属性,spark.serializer, org.apache.spark.serializer.kryoSerializer类
Kryo之所以没有被作为默认的序列化类库的原因,主要因为kryo要求,如果达到最佳性能的话,一定要注册自定义类(比如,算子函数中使用到了外部自定义类型的对象变量这时,就必须注册类,否则kryo达不到最佳性能)

第二步,注册使用到的,需要通过kryo序列化的,一些自定义类,SparkConf.registerKryoClassed()

哪些地方需要使用Kryo

有三个地方

  1. 算子函数中使用到外部变量
    算子函数使用外部变量,使用kryo以后,优化网络传输性能,可以优化集群中内存占用和消耗
  2. 持久化RDD时进行序列化,StorageLevel.MEMORY_ONLY_SER
    优化内存占用和消耗;持久化RDD占用的内存越少,task执行的时候,创建的对象,就不至于频繁的占满内存,频繁发生GC.
  3. shuffle
    优化网络传输性能

在这里插入图片描述

什么样序列化错误?

client模式提交spark作业,观察本地打印的log,如果出现了类似于Serializable、Serialize等等相关的错误log,那应该就是序列化错误。

  1. 第一种,算子函数里用到了外部自定义类型的变量,那么此时自定义类型必须实现Implements Serializable接口 不然会出错
  2. 自定义类型,作为rdd类型的元素,那么自定义类型也必须可序列化 不然会出错

以上两种情况 比如 自定义排序对象就需要实现序列化

//第四步,自定义二次排序key
		//第五步,将数据映射成<CategorySortKey,info>格式的RDD,然后进行二次排序
		JavaPairRDD<CategorySortKey, String> sortKey2countRDD = categoryid2countRDD.mapToPair(new PairFunction<Tuple2<Long, String>, CategorySortKey, String>() {

			private static final long serialVersionUID = -8624622546415913486L;

			@Override
			public Tuple2<CategorySortKey, String> call(Tuple2<Long, String> longStringTuple2) throws Exception {
				String countInfo = longStringTuple2._2();
				long clickCount = Long.valueOf(StringUtils.getFieldFromConcatString(
						countInfo, "\\|", Constants.FIELD_CLICK_COUNT));
				long orderCount = Long.valueOf(StringUtils.getFieldFromConcatString(
						countInfo, "\\|", Constants.FIELD_ORDER_COUNT));
				long payCount = Long.valueOf(StringUtils.getFieldFromConcatString(
						countInfo, "\\|", Constants.FIELD_PAY_COUNT));
				CategorySortKey sortKey = new CategorySortKey(clickCount,
						orderCount, payCount);

				return new Tuple2<CategorySortKey, String>(sortKey, countInfo);
			}
		});

		JavaPairRDD<CategorySortKey, String> sortedCategoryCountRDD =
				sortKey2countRDD.sortByKey(false);//降序 拿取topn

  1. 不满足以上两种请情况,去使用第三方的,不支持序化的类型
Connection conn = 

studentsRDD.foreach(new VoidFunction() {
 
public void call(Row row) throws Exception {
  conn.....
}

});

Connection是不支持序列化的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值