什么是序列化和序列化?

  • 序列化是什么
    1. 序列化的作用就是可以将对象的内容变成二进制, 存入文件中保存
    2. 反序列化指的是将保存下来的二进制对象数据恢复成对象
  • 序列化对对象的要求
    1. 对象必须实现 Serializable 接口
    2. 对象中的所有属性必须都要可以被序列化, 如果出现无法被序列化的属性, 则序列化失败
  • 限制
    1. 对象被序列化后, 生成的二进制文件中, 包含了很多环境信息, 如对象头, 对象中的属性字段等, 所以内容相对较大
    2. 因为数据量大, 所以序列化和反序列化的过程比较慢
  • 序列化的应用场景
    1. 持久化对象数据
    2. 网络中不能传输 Java 对象, 只能将其序列化后传输二进制数据

Spark 中的序列化和反序列化的应用场景

  • Task 分发

Task 是一个对象, 想在网络中传输对象就必须要先序列化

  • RDD 缓存

    val rdd1 = rdd.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
    rdd1.cache
    rdd1.collect
    
    • RDD 中处理的是对象, 例如说字符串, Person 对象等
    • 如果缓存 RDD 中的数据, 就需要缓存这些对象
    • 对象是不能存在文件中的, 必须要将对象序列化后, 将二进制数据存入文件
  • 广播变量

  • 广播变量会分发到不同的机器上, 这个过程中需要使用网络, 对象在网络中传输就必须先被序列化

  • Shuffle 过程

  • Shuffle 过程是由 ReducerMapper 中拉取数据, 这里面涉及到两个需要序列化对象的原因

    • RDD 中的数据对象需要在 Mapper 端落盘缓存, 等待拉取
    • MapperReducer 要传输数据对象
  • Spark StreamingReceiver

  • Spark Streaming 中获取数据的组件叫做 Receiver, 获取到的数据也是对象形式, 在获取到以后需要落盘暂存, 就需要对数据对象进行序列化

  • 算子引用外部对象

    class userserializable(i: Int)rdd.map(i => new Unserializable(i)).collect.foreach(println)
    
    • Map 算子的函数中, 传入了一个 Unserializable 的对象
    • Map 算子的函数是会在整个集群中运行的, 那 Unserializable 对象就需要跟随 Map 算子的函数被传输到不同的节点上
    • 如果 Unserializable 不能被序列化, 则会报错

RDD 的序列化

  • RDD 的序列化

    RDD 的序列化只能使用 Java 序列化器, 或者 Kryo 序列化器

  • 为什么?

    RDD 中存放的是数据对象, 要保留所有的数据就必须要对对象的元信息进行保存, 例如对象头之类的 保存一整个对象, 内存占用和效率会比较低一些

  • Kryo 是什么

    KryoSpark 引入的一个外部的序列化工具, 可以增快 RDD 的运行速度 因为 Kryo 序列化后的对象更小, 序列化和反序列化的速度非常快 在 RDD 中使用 Kryo 的过程如下

  val conf = new SparkConf().setMaster("local[2]").setAppName("KyroTest")conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")conf.registerKryoClasses(Array(classOf[Person]))val sc = new SparkContext(conf)rdd.map(arr => Person(arr(0), arr(1), arr(2)))

DataFrameDataset 中的序列化

历史的问题

RDD 中无法感知数据的组成, 无法感知数据结构, 只能以对象的形式处理数据

DataFrameDataset 的特点

  • DataFrameDataset 是为结构化数据优化的

  • DataFrameDataset 中, 数据和数据的 Schema 是分开存储的

    spark.read.csv("...").where($"name" =!= "").groupBy($"name").map(row: Row => row).show()
    
  • DataFrame 中没有数据对象这个概念, 所有的数据都以行的形式存在于 Row 对象中, Row 中记录了每行数据的结构, 包括列名, 类型等

Dataset 中上层可以提供有类型的 API, 用以操作数据, 但是在内部, 无论是什么类型的数据对象 Dataset 都使用一个叫做 InternalRow 的类型的对象存储数据

val dataset: Dataset[Person] = spark.read.csv(...).as[Person]

总结

  1. 当需要将对象缓存下来的时候, 或者在网络中传输的时候, 要把对象转成二进制, 在使用的时候再将二进制转为对象, 这个过程叫做序列化和反序列化
  2. Spark 中有很多场景需要存储对象, 或者在网络中传输对象
    1. Task 分发的时候, 需要将任务序列化, 分发到不同的 Executor 中执行
    2. 缓存 RDD 的时候, 需要保存 RDD 中的数据
    3. 广播变量的时候, 需要将变量序列化, 在集群中广播
    4. RDDShuffle 过程中 MapReducer 之间需要交换数据
    5. 算子中如果引入了外部的变量, 这个外部的变量也需要被序列化
  3. RDD 因为不保留数据的元信息, 所以必须要序列化整个对象, 常见的方式是 Java 的序列化器, 和 Kyro 序列化器
  4. DatasetDataFrame 中保留数据的元信息, 所以可以不再使用 Java 的序列化器和 Kyro 序列化器, 使用 Spark 特有的序列化协议, 生成 UnsafeInternalRow 用以保存数据, 这样不仅能减少数据量, 也能减少序列化和反序列化的开销, 其速度大概能达到 RDD 的序列化的 20 倍左右

Spark序列化入门相关推荐

  1. Spark序列化简介

    参考文章:Spark序列化 spark之kryo 序列化 Spark序列化入门 1. 什么是序列化和序列化? 序列化是什么 序列化的作用就是可以将对象的内容变成二进制, 存入文件中保存 反序列化指的是 ...

  2. spark streaming 入门例子

    spark streaming 入门例子: spark shell import org.apache.spark._ import org.apache.spark.streaming._sc.ge ...

  3. Spark快速入门指南 – Spark安装与基础使用

    本文转载自Spark快速入门指南 – Spark安装与基础使用 Apache Spark 是一个新兴的大数据处理通用引擎,提供了分布式的内存抽象.Spark 正如其名,最大的特点就是快(Lightni ...

  4. Spark SQL入门:创建SparkSession时import spark.implicits._ 报错: error: value implicits is not a member of...

    Spark SQL入门:创建SparkSession时import spark.implicits._ 报错: error: value implicits is not a member of... ...

  5. spark SQL入门指南《读书笔记》

    文章目录 spark SQL入门指南 第一章 初识 spark mysql 1.1 Spark的诞生 和SparkSQL是什么? 1.2 Spark SQL能做什么? 第2章 Spark安装.编程环境 ...

  6. Spark大数据开发学习:Spark基础入门

    在诸多的大数据技术框架当中,Spark可以说是占据了非常重要的地位,继Hadoop之后,基于实时数据处理需求的不断上升,Spark开始占据越来越大的市场份额,而Spark,也成为大数据的必学知识点.今 ...

  7. Spark Shell入门教程

    教程目录 0x00 教程内容 0x01 Spark Shell 操作 1. 启动与关闭 Spark Shell 2. 使用 Spark Shell 进行 Scala 编程 0x02 测试词频统计案例 ...

  8. [Spark]PySpark入门学习教程---介绍(1)

    一 安装指引 (91条消息) [Hadoop] mac搭建hadoop3.X 伪分布模式_小墨鱼的专栏-CSDN博客https://zengwenqi.blog.csdn.net/article/de ...

  9. spark从入门到精通spark内存管理详解- 堆内堆外内存管理

    前言 Spark作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解Spark内存管理的基本原理,有助于更好地开发Spark应用程序和进行性能调优.本文将详细介绍两部 ...

最新文章

  1. Linux09-网络配置
  2. Linux常用编辑器使用:vi、vim、nano、gedit
  3. Cow Digit Game(博弈论:sg函数)
  4. 用友2020校招java笔试题_用友Java类笔试题大全
  5. 调试某游戏副本中的加亮提示信息思路
  6. 深度学习的实用层面 —— 1.9 正则化输入
  7. Computed property “value1“ was assigned to but it has no setter.
  8. http协议-响应和请求
  9. 2012年5月16日,Google发布“知识图谱(Knowledge Graph)”
  10. gem5源码解读se.py以及simulate.py(一)
  11. I2S协议-一篇文章带你了解
  12. linux网络测速qerf,www.cpg.com.ph
  13. word如何设置页眉横线的磅数
  14. 128G的U盘格式化后只有300M,如何恢复成128G
  15. Trivy是CD流水线上面向容器的脆弱性扫描器
  16. 愉快的学习就从翻译开始吧_0-Time Series Forecasting with the Long Short-Term Memory Network in Python
  17. VS 无法启动程序(系统找不到指定路径)的解决方法
  18. [王鼎杰] 法国为什么是五常之一
  19. python进阶学习--PyCharm使用
  20. EJB 3 术语汇编

热门文章

  1. python统计字符串中字母个数字母无视大小写_python判断字符串是字母 数字 大小写(转载)...
  2. kali 创建php可执行文件_Kali安装wordpress
  3. 微信支付:nginx配置 网页授权域名 用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。
  4. Java基础教程【第四章:Java流程控制】
  5. Java基础教程【第一章:Java概述】
  6. Python求梅森尼数
  7. 模拟生产者-消费者问题和读者-写者问题
  8. cesium 基于在vue框架写功能
  9. cesium 加载科技感
  10. 已知原函数和导函数的关系_根据函数表达式该如何求函数值