RDD关键性能考量之 序列化格式
《Spark快速大数据分析》
8.4.2 关键性能考量 序列化格式
当Spark需要通过网络传输数据,或是将数据写到磁盘上时,Spark需要把数据序列化为二进制格式。
序列化会在数据进行混洗操作时发生,此时有可能需要通过网络传输大量数据。
默认情况下,Spark会使用Java内建的序列化库。Spark也支持使用第三方序列化库Kryo,
可以提供比Java的序列化工具更短的序列化时间和更高压缩比的二进制表示,但不能直接序列化全部
类型的对象。几乎所有的应用都在迁移到Kryo后获得了更好的性能。
要使用Kryo序列化工具,需要设置spark.serializer为org.apache.spark.serializer.KryoSerializer。
为了获得最佳性能,还应该向Kryo注册想要序列化的类。注册类可以让Kryo避免把每个对象的完整的
类名写下来,成千上万条记录累计节省的空间相当可观。如果想强制要求这种注册,可以把
spark.kryo.registrationRequired设置为true,这样Kryo会在遇到未注册的类时抛出错误。
val conf = new SparkConf().setMaster("local").setAppName("testKryo") //使用Kryo序列化工具 conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") //严格要求注册类 conf.set("spark.kryo.registrationRequired", "true") conf.registerKryoClasses(Array(classOf[MyClass], classOf[MyOtherClass])) val sc = new SparkContext(conf)
不论是选用Kryo还是Java序列化,如果代码中引用到了一个没有扩展Java的Serializable接口的类,
你都会遇到NotSerializableException。在这种情况下,要查处引发问题的类是比较困难的,
因为用户代码会引用到许多不用的类。很多JVM都支持通过一个特别的选项来帮助
调试这一情况:"-Dsun.io.serialization.extended DebugInfo=true"。
可以通过设置spark-submit的--dirver-java-options和--executor-java-options标记来打开这个选项。
一旦找到了了有问题的类,最简单的解决方法是修改这个产生问题的类,需要采用一些高级的变通策略,
比如为这个类创建一个子类并实现Java的Externalizable接口,或者自定义Kryo的序列化行为。
posted on 2015-11-19 23:01 develooop 阅读(1251) 评论(0) 编辑 收藏 举报