Spark:The Definitive Guide--读书小结(一)

前言

大概花了一个月(2020-09~2020-10)左右的时间,看完了整本书。笔者毕业后,主要从事机器学习、数据挖掘方向的相关工作。由于Spark作为目前主流的分布式计算引擎,个人也一直在用Spark进行相关的数据分析与建模工作。通读全书,感觉比较适合入门级学习,主要介绍了Spark 2.0相关API及Spark生态。涵盖Spark SQL、Struct Streaming、GraphX、MLlib等内容。对初学者而言是一本不错的书籍。

数据、源码链接: https://github.com/databricks/Spark-The-Definitive-Guide.

第Ⅰ部分 大数据与Spark概述

Spark是加州伯克利分校AMP实验室开发的通用内存计算框架,Spark主要包括Spark SQL(数据分析)、Struct Streaming(流计算)、ML(机器学习)、GraphX(图计算)等组件。使得Spark成为大数据一站式处理平台,在企业项目中得到广泛应用。目前Spark已经进入3.0时代,速度较2.0版本有较大的提升。在可预见的未来,Spark任将是企业进行大数据分析的基石。在这里插入图片描述

第Ⅱ部分 结构化API–DataFrame、SQL和Dataset

结构化API是处理各种数据类型的工具,可处理非结构化的日志文件、半结构化的CSV文件、以及高度结构化的Parquet文件。结构化API主要指以下三种核心分布式集合类型的API:Dataset类型、DataFrame类型、SQL表和视图。

Dataset和DataFrame的比较:
DataFrame是一个分布式的类型为Row的对象集合,Dataset可以使用Java/Scala类定义DataFrame中的每条记录。DataFrame可以看作是Dataset中对象为Row时的特例。Row类型是Spark用于支持内存计算而优化的数据格式。Dataset在编译时检查类型是否符合规范,而DataFrame在运行时检查类型是否与Schema中指定的一致。但Dataset与DataFrame的操作几乎完全一样。
在这里插入图片描述
DataFrame的转Dataset:

case class Flight(DEST_COUNTRY_NAME:String,ORIGIN_COUNTRY_NAME:String,count:BigInt)
val flightDF = spark.read.parquet("fileName")
val flights = flights.as[Flight]

RDD、DataFrame、Dataset演变:
在这里插入图片描述
DataFrame与RDD相比,更像是传统的二维表,除了记录了表数据,还记录了数据的结构信息:
在这里插入图片描述目前基于RDD的API已经进入了维护阶段,基于DataFrame与Dataset的API今后将成为Spark的核心API。

Spark结构化API执行过程:

  1. 编写DataFrame、Dataset、SQL代码,
  2. 如果代码能有效执行,Spark将其转化为一个逻辑执行计划(Logical Plan)
  3. Spark将此逻辑计划转化成一个物理执行计划(Physical Plan),检查可行的优化策略,并在此检查过程中进行优化
  4. Spark将生成的不同的物理执行计划,通过代价模型进行比较分析,最终在Spark集群上执行代价最小的物理执行计划(RDD操作)

详细过程见图解:
在这里插入图片描述

结构化操作介绍

本文基于伯克利开发的databricks进行操作演示(类似于python 的Jupyter Notebook),仅介绍部分操作,常见的操作不再赘述。数据目录结构如下:

在这里插入图片描述

  1. SQL表达式、DataFrame执行效率:
    SQL表达式与DataFrame API代码在执行前会编译成相同的底层逻辑树,这意味着SQL表达式与DataFrame的性能是一样的。个人更倾向于使用DatFrame API。
  2. select、selectExpr:
    select 函数与selectExpr函数支持在DataFrame上使用类SQL查询,可用其操作DataFrame列。selectExpr可以看作是select(expr(…))操作的简化版。其中" * "包含所有原始表中的列。
    在这里插入图片描述

注意事项:混淆Column对象和字符串,编译报错。
在这里插入图片描述

  1. 字面量(literal):
    当需要增加一项常数列时,可采用字面量函数
    在这里插入图片描述

  2. 链式过滤
    一般为了书写方便,多个过滤条件通常会放在一个表达式中,尽管方式可行,但并不总是有效。因为Spark会同时执行所有过滤条件,不管过滤条件的先后顺序。不过我还是喜欢组合后一起过滤,除非表达式很长,才会拆分成链式过滤。
    在这里插入图片描述

  3. sample、randomSplit
    sample函数按一定比例从DataFrame中随机抽取,可以指定是否为放回采样。randomSplit随机切分数据集,机器学习中常用来划分训练集、测试集。
    在这里插入图片描述

  4. null值排序
    通过asc_nulls_first、desc_nulls_first指定排序后空值出现的位置
    在这里插入图片描述

  5. sortWithinPartitions
    出于性能优化的目的,最好在进行别的转换操作之前,先对每个分区进行内部排序。
    在这里插入图片描述

  6. describe、summary
    两者都是输出列的统计信息,summary可输出分位数信息
    在这里插入图片描述

  7. monotonically_increasing_id
    为每行添加一个唯一的ID,每个partition内的ID编号连续,分区编号不连续,partition1(0-100),partition2(150-200),partition3(400-500)…
    在这里插入图片描述

  8. regx_replace、translate
    两者都可以进行字符串替换
    在这里插入图片描述

  9. var agrs
    Spark 可以接受不定量参数,采用var args可以更加简单的处理contains的问题
    在这里插入图片描述

  10. na处理null值
    数值型填充时,应注意保持数据类型一致。
    在这里插入图片描述

  11. Struct结构体
    spark可以组合多列构成一个结构体
    在这里插入图片描述

  12. 数组列
    根据某字符串列可生成数组列,供后续explode拆分
    在这里插入图片描述

  13. explode
    列主要功能是拆分array_col列中的每个值为一行。同时可以对map_col拆分成key-value两列
    在这里插入图片描述在这里插入图片描述

  14. JSON字符串
    Spark可以采用get_json_object解JSON对象,to_json可转化成JSON对象
    在这里插入图片描述在这里插入图片描述

  15. UDF函数
    Spark最强大的功能之一就是自定义函数,UDF可以让用户编写自定义转化操作。UDF函数需要在Spark Driver端进行序列化,并将他通过网络传送到worker端。一般来说,避免使用UDF函数是一个很好的优化策略。因为他们强制将数据表示为JVM对象。应该尽可能的使用结构化API来执行操作。

  16. window函数
    使用window函数可以执行某些特殊的聚类操作。具体指在数据窗口上执行聚合操作。window通常结合rank和dense_rank函数使用。示例如下:
    在这里插入图片描述

  17. rollup、cube分组操作
    cube比rollup多了一组col1:null,col2:noNull具体见红色
    在这里插入图片描述在这里插入图片描述

  18. pivot
    根据某列中的不同行创建多个列,注意区分groupBy
    在这里插入图片描述

  19. left_semi、left_anti
    left_semi(左半连接),实际上并不包含右边DataFrame中的任何值,它只是查看左侧DataFrame的值是否存在于右侧DataFrame,如果存在则在连接结果中保留。

    left_anti(左反连接),它实际上并不包含右边DataFrame的任何值,只是查看该值左侧DataFrmae的值是否存在于右侧DataFrame,不存在则在连接结果中保留
    在这里插入图片描述
    在这里插入图片描述

  20. 复杂连接
    在这里插入图片描述

  21. shuffle join与broadcast join
    Spark以两种不同的方式采取集群间的通信问题,它要么执行all-to-all通信的shuffle join,要么执行broadcast join。当用一个大表连接另一个大表时,最终就是shuffle join。大表与小表间的连接,通常可以将小表广播出去,也就是将较小的DataFrame复制到集群上的所有节点中,听起来很耗时间,但可以避免all-to-all的join,但整体性能要好于all-to-all join。但如果广播的表太大,可能导致driver端节点奔溃。
    http://hbasefly.com/2017/03/19/sparksql-basic-join/

    大表 join 极小表
    在这里插入图片描述 大表 join 小表
    在这里插入图片描述
    大表 join 大表

在这里插入图片描述在这里插入图片描述

  1. 并行读写数据库
    设置numPartitions可以保证在读取和写入数据库时不会导致数据库过载
    在这里插入图片描述

  2. 查询下推
    谓词下推就是指将各个条件先应用到对应的数据上,而不是根据写入的顺序执行,这样就可以先过滤掉部分数据,降低join等一系列操作的数据量级,提高运算速度。谓词下推(predicate pushdown)属于逻辑优化。优化器可以将谓词过滤下推到数据源,从而使物理执行跳过无关数据。
    在这里插入图片描述在这里插入图片描述

  3. 滑动窗口分区.
    Spark repatition采用的分区方式是key 的hash分区,可以指定阈值,采用基于阈值范围的滑动窗口分区
    在这里插入图片描述

  4. gzip文件压缩(推荐采用gzip压缩格式的parquet)
    gzip相比snappy压缩率更高,df.write.option(“compression”,“gzip”).parquet(path)

  5. 数据划分、数据分桶、maxRecordsPerFile
    基于某列对DataFrame进行划分,这使得你在之后读取文件时,可以跳过大量不相关的数据。比如常见的按时间列进行划分,但当某列存在大量不同的数据时,将生成很多小文件。此时,可以考虑数据分桶。maxRecordsPerFile可以限制每个文件的最大记录数,当maxRecordsPerFile与分区数量发生冲突时,以maxRecordsPerFile为准。

    在这里插入图片描述
    在这里插入图片描述

第Ⅲ部分 低级API

链接: https://editor.csdn.net/md/?articleId=109321946//未写待续.

第Ⅳ部分 生产与应用

链接: https://editor.csdn.net/md/?articleId=109321946//未写待续.

第Ⅴ部分 流处理

链接: https://editor.csdn.net/md/?articleId=109321946//未写待续.

第Ⅵ部分 高级分析与机器学习

链接: https://editor.csdn.net/md/?articleId=109321946//未写待续.

第Ⅶ部分 生态系统

链接: https://editor.csdn.net/md/?articleId=109321946//未写待续.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值