Spark 开发原则

news/2024/5/20 1:29:58 标签: spark, 大数据, java, 分布式, hdfs

Spark 开发原则

  • 坐享其成
  • 要省要拖
  • 跳出单机思维

应用开发原则 :

  • 坐享其成 : 利用 Spark SQL 优化
  • 能省则省、能拖则拖 : 节省数据量 , 拖后 Shuffle
  • 跳出单机思维 : 避免无谓的分布式遍历

坐享其成

设置好配置项,享受 Spark SQL 的性能优势,如钨丝计划、AQE、SQL functions

钨丝计划:

  • Tungsten 自定义了紧凑的二进制格式的数据结构,避免了 Java 对象序列化与反序列化的计算开销
  • Tungsten 利用 Java Unsafe API 开辟堆外(Off Heap Memory)内存来管理对象。对内存占用的估算更精确,不用反复垃圾回收
  • Tungsten 用全阶段代码生成(Whol Stage Code Generation)取代火山迭代模型,减少虚函数调用和降低内存访问频率,还提升 CPU 利用率

AQE :

  • 自动分区合并 : 自动检测小数据分区,并进行自动合并
  • 数据倾斜 : 发现倾斜的数据分片,会自动加盐处理,并对另一张表进行复制
  • Join 策略调整 : 动态调整 Join ,转换为 Broadcast Join

要省要拖

  • 省 : 数据处理量,只有节省数据量 , 就节省计算负载,就有更快的处理速度
  • 拖 : Shuffle ,当计算步骤越靠后,处理的数据量越少,Shuffle 越晚,落盘/分发就越少,就有更高的执行效率

实现步骤 :

  • 尽量把节省数据扫描量和 数据处理量往前推
  • 尽量消除 Shuffle,省去数据落盘与分发的开销
  • 消除不了 Shuffle,就把 Shuffle 往后拖
val dates: List[String] = List("2020-01-01", "2020-01-02", "2020-01-03")
val rootPath: String = _

//读取日志文件,去重、并展开userInterestList
def createDF(rootPath: String, date: String): DataFrame = {
  val path: String = rootPath + date
  val df = spark.read.parquet(path)
    .distinct
    .withColumn("userInterest", explode(col("userInterestList")))
  df
} 

//提取字段、过滤,再次去重,把多天的结果用union合并
val distinctItems: DataFrame = dates.map {
  case date: String =>
    val df: DataFrame = createDF(rootPath, date)
  		.select("userId", "itemId", "userInterest", "accessFreq")
      .filter("accessFreq in ('High', 'Medium'))")
      .distinct
  	df
}.reduce(_ union _)

优化 :

  • 减少数据访问量的操作 (filter、select) 往前推
  • 引入 Shuffle 的 distinct 拖到最后面
val dates: List[String] = List("2020-01-01", "2020-01-02", "2020-01-03")

val rootPath: String = _
val filePaths: List[String] = dates.map(rootPath + _)

/**
一次性调度所有文件
先进行过滤和列剪枝
然后再展开userInterestList
最后统一去重
*/
val distinctItems = spark.read.parquet(filePaths: _*)
  .filter("accessFreq in ('High', 'Medium'))")
  .select("userId", "itemId", "userInterestList")
  .withColumn("userInterest", explode(col("userInterestList")))
  .select("userId", "itemId", "userInterest")
  .distinct

跳出单机思维

在右表用 map ,在 map 内实例化 Util 类获取哈希算法,拼接 Join keys 进行哈希运算

import java.security.MessageDigest

class Util {
  val md5: MessageDigest = MessageDigest.getInstance("MD5")
  val sha256: MessageDigest = _ //其他哈希算法
} 

val df: DataFrame = _

val ds: Dataset[Row] = df.map {
  case row: Row =>
    val util = new Util()
  
    val s: String = row.getString(0) + row.getString(1) + row.getString(2)
    val hashKey: String = util.md5.digest(s.getBytes).map("%02X".format(_)).mkString
  
    (hashKey, row.getInt(3))
}

优化 :

  • 实例化的动作放 map 外面
val ds: Dataset[Row] = df.mapPartitions(iterator => {
  val util = new Util()
  
  val res = iterator.map {
    case row => {
      val s: String = row.getString(0) + row.getString(1) + row.getString(2)
      val hashKey: String = util.md5.digest(s.getBytes).map("%02X".format(_)).mkString
      
      (hashKey, row.getInt(3)) 
  	}
  }
  
  res
})

http://www.niftyadmin.cn/n/126940.html

相关文章

Maven项目的创建

目录 1.创建java项目 1.1 新建项目​编辑 2 创建web项目 2.1 新建项目 2.2 启动项目 2.2.1 修改jdk的版本 2.2.2 设置单元测试的版本 2.2.3 删除pluginManagement标签 2.2.4添加web部署插件 2.2.5 启动项目 1.创建java项目 1.1 新建项目 创建resources目录 利用maven…

Maven依赖的基本概念

目录 1.依赖的基本配置 2.依赖范围 3.传递性依赖 1.依赖的基本配置 根元素project下的dependencies可以包含多个 dependence元素,以声明多个依赖。每个依赖都应该包含以下元素: 1. groupId, artifactId, version : 依赖的基本坐标, 对于任…

华为OD机试真题Python实现【需要广播的服务器数量】真题+解题思路+代码(20222023)

需要广播的服务器数量 题目 服务器连接方式包括直接相连,间接连接。 A和B直接连接,B和C直接连接,则A和C间接连接。 直接连接和间接连接都可以发送广播。 给出一个N*N数组,代表N个服务器,matrix[i][j] == 1, 则代表i和j直接连接;不等于 1 时,代表i和j不直接连接。 mat…

华为OD机试真题Python实现【连续子串】真题+解题思路+代码(20222023)

连续子串 题目 给你两个字符串t和p 要求从t中找到一个和p相同的连续子串 并输出该子串第一个字符的下标 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇总 ## 输入 输入文件包括两行 分别表示字符串 t 和 p 保证t的长度不小于p 且t的长度不…

KUKA U盘备份系统

KUKA U盘备份系统 原创 March Cai Cass 机器人 2022-03-10 12:39 首先想做系统备份,需要KUKA 官方的U盘,需要设置如下 双击KUKA U盘里的Recovery.exe 打开如右上图,点开专家设置 设置好需要的功能 返回主菜单组选择 配置界面,…

stdin, stdout, stderr

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结前言 在通常情况下,Linux/UNIX每个程序在开始运行的时刻,都会打开3…

省选模拟测试23 T1直径

题目大意 给你一个数kkk&#xff0c;请你构造一棵节点数量小于等于5000的直径数量为kkk的树。 我们定义这棵树的直径为&#xff0c;所有满足1≤i<j≤n1\leq i<j\leq n1≤i<j≤n的(i,j)(i,j)(i,j)中&#xff0c;dis(i,j)dis(i,j)dis(i,j)最大的。如果有多个这样的(i,…

华为OD机试真题Python实现【黑板上色】真题+解题思路+代码(20222023)

题目 疫情过后希望小学终于又重新开学了,3 年 2 班开学第一天的任务是将后面的黑板报重新制作, 黑板上已经写上了N个正整数,同学们需要给这每个数分别上一种颜色, 为了让黑板报既美观又有学习意义,老师要求同种颜色的所有数都可以被这个颜色中最小的那个数整除, 现在帮小…