spark之kryo序列化及其使用

spark之kryo 序列化

1.定义:把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的反序列化。
通俗地说序列化就是把内存(jvm)中一个对象的状态通过网络传输,或者保存到磁盘上,反序列化与之相反。

2.spark中的序列化那么对象以何种形式进行传输性能更好呢?在spark2.0+版本的官方文档中提到:spark默认提供了两个序列化库:Java自身的序列化和Kryo序列化官网的解释是:java序列化灵活,但是速度缓慢。Kryo序列化速度更快且更紧凑,但是支持的类型较少。而且spark现在已经默认RDD在shuffle的时候对简单类型使用了Kryo序列化。

3.如何使用kryo 序列化spark中已经包含了kryo库,使用kryo只需要注册即可。

Spark 中使用 Kryo序列化

步骤
Spark 中使用 Kryo 序列化主要经过两个步骤
1.声明使用 kryo 序列化
2.注册序列化类

1.声明使用 kryo 序列化
可以在程序中指定,例如

val conf = new SparkConfconf  .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")

另一种方式,可以在 spark-submit 通过

--conf spark.serializer=org.apache.spark.serializer.KryoSerializer

2.注册序列化类
这里有两种方式
1.传递classes数组
2.在指定类中,通过kyro注册

1.传递classes数组
private[udf] case class User(id: Int, name: String, city: String)
 val conf = new SparkConf()    
 conf
 .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")      
 // .set("spark.kryo.registrationRequired", "true")     
方法一      
 .set("spark.kryo.registrator", "com.spark.test.offline.udf.MyKryoRegistrator")      
方法二  //注册自定义类交给KryoSerializer序列化处理类进行序列化      
 .registerKryoClasses(Array(classOf[com.spark.test.offline.udf.User]        
 //, classOf[scala.collection.mutable.WrappedArray.ofRef[_]] 
 ))

中文切词案例:

import com.huaban.analysis.jieba.{JiebaSegmenter, SegToken}
import com.huaban.analysis.jieba.JiebaSegmenter.SegMode
import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.sql.functions._
object JiebaSeg {
  def main(args: Array[String]): Unit = {
    //    定义结巴分词类的序列化
    val conf = new SparkConf()
        //注册自定义类交给KryoSerializer序列化处理类进行序列化
      .registerKryoClasses(Array(classOf[JiebaSegmenter]))
      //设置优化参数
      .set("spark.rpc.message.maxSize","800")
    //    建立sparkSession,并传入定义好的Conf
    val spark = SparkSession
      .builder()
      .appName("Jieba UDF")
      .enableHiveSupport()
      .config(conf)
      .getOrCreate()

    // 定义结巴分词的方法,传入的是DataFrame,输出也是DataFrame多一列seg(分好词的一列)
    def jieba_seg(df:DataFrame,colname:String): DataFrame ={
//   定义类的实例化
      val segmenter = new JiebaSegmenter()
      //使用广播变量进行序列化(广播变量只能读,不能修改,类似分发)
      val seg = spark.sparkContext.broadcast(segmenter)
      val jieba_udf = udf{(sentence:String)=>
//        通过value获取到一段中文
        val segV = seg.value
        segV.process(sentence.toString,SegMode.INDEX)
          .toArray().map(_.asInstanceOf[SegToken].word)
          .filter(_.length>1).mkString(" ")
      }
      df.withColumn("seg",jieba_udf(col(colname)))
    }

    val df =spark.sql("select content,label from badou.new_no_seg limit 300")
    val df_seg = jieba_seg(df,"content")
    df_seg.show()
//    saveAsTable 直接存储到对应的hive表
    df_seg.write.mode("overwrite").saveAsTable("badou.news_jieba")

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值