java.io.NotSerializableException: org.apache.kafka.clients.consumer.ConsumerRecord

问题

如下代码报错 

JavaInputDStream<ConsumerRecord<Object, Object>> stream =
		  KafkaUtils.createDirectStream(
		    streamingContext,
		    LocationStrategies.PreferConsistent(),
		    ConsumerStrategies.Subscribe(topics, kafkaParams)
		  );
java.io.NotSerializableException: org.apache.kafka.clients.consumer.ConsumerRecord
Serialization stack:
	- object not serializable (class: org.apache.kafka.clients.consumer.ConsumerRecord, value: ConsumerRecord(topic = topic01, partition = 0, offset = 33074, CreateTime = -1, serialized key size = -1, serialized value size = 8, headers = RecordHeaders(headers = [], isReadOnly = false), key = null, value = aviation))
	- element of array (index: 0)
	- array (class [Lorg.apache.kafka.clients.consumer.ConsumerRecord;, size 11)
	at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
	at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:46)
	at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100)
	at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:383)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

 

解决方法

1、将ConsumerRecord类注册为使用Kyro序列化

		 SparkConf sparkConf = new SparkConf().setAppName("JavaFlumeEventCount")
				 .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
		 sparkConf.registerKryoClasses((Class<?>[]) Arrays.asList(ConsumerRecord.class).toArray());

 

知识补充

spark的两种常用序列化方式

序列化在分布式系统中扮演着重要的角色,优化Spark程序时,首当其冲的就是对序列化方式的优化。Spark为使用者提供两种序列化方式:

Java serialization: 默认的序列化方式。

Kryo serialization: 相较于 Java serialization 的方式,速度更快,空间占用更小,但并不支持所有的序列化格式,同时使用的时候需要注册class。spark-sql中默认使用的是kyro的序列化方式。

下文将会讲解kryo的使用方式并对比性能。

Kyro序列化步骤 

一、如果需要多个类都使用Kyro序列化,可以自定义一个注册类,同时进行多个类的注册,如下
    主要的使用过程就三步:
    1.设置序列化使用的库
        conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");  //使用Kryo序列化库
    2.在该库中注册用户定义的类型
        conf.set("spark.kryo.registrator", toKryoRegistrator.class.getName());       //在Kryo序列化库中注册自定义的类集合
    3.在自定义类中实现KryoRegistrator接口的registerClasses方法.要求自定义类实现Serializable,即下面的temp1、temp2类
        public static class toKryoRegistrator implements KryoRegistrator {
            public void registerClasses(Kryo kryo) {
                kryo.register(tmp1.class, new FieldSerializer(kryo, tmp1.class));  //在Kryo序列化库中注册自定义的类
                kryo.register(tmp2.class, new FieldSerializer(kryo, tmp2.class));  //在Kryo序列化库中注册自定义的类
            }
        }
        
二、如果只是注册一个类使用Kyro序列化,直接使用如下即可
    1.设置序列化使用的库
        conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");  //使用Kryo序列化库
    2.注册序列化类
        conf.registerKryoClasses((Class<?>[]) Arrays.asList(ConsumerRecord.class).toArray());

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fang·up·ad

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

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

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

打赏作者

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

抵扣说明:

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

余额充值