spark入门到精通

1、对于spark object类型的类,直接拿来用就好了,不用new
2、rdd join

val list1 = List(1, 2)
val list2 = List(2, 3)
val t1 =sc.parallelize(list1).map(x => ("kkkk", x))
val t2 = sc.parallelize(list2).map(x => ("kkkk", x))
// 两个rdd中,同一个key的value放到一个元组中。即u为(kkkk,(Some(1),Some(2)))
val u = t1.fullOuterJoin(t2)		

3、一个节点上可以有多个executor进程
4、报错:java.net.BindException: Address already in use: Service ‘sparkDriver’ failed after 16 retries!
每一个Spark任务都会起一个Driver端口,即SparkUI,默认为4040,如果被占用则随机选取端口重试,默认会重试16次。16次重试都失败后,会放弃任务的运行。使用jps命令查看当前节点上提交的任务数量,如果当前节点的任务数超过了16个,就会造成这样的错误。
解决办法:使用spark-submit提交任务时,在命令行中添加:
–conf spark.port.maxRetries=100*,将100改为1,可以复现此BUG
5、spark中的collect(收集)操作是将远程数据通过网络传输到driver端本地,如果数据量特别大的话,可能会造成driver端的内存溢出。所以对于数据量小的rdd可以用collect,数据量大的就不要用了
7、spark报错:java.lang.StackOverflowError
这是由于栈空间不足,调大执行时的栈空间:
–conf spark.executor.extraJavaOptions=-Xss4096k 特别注意,不能加引号
8、spark写hive的方式

  • rdd.saveAsTextFile(“hive表对应的hdfs路径”)
    hiveContext.sql(“alter table test.test add if not exists partition(day=‘2019-05-27’, hour=‘10’)”)
  • 直接用spark sql or hive sql
    insert overwrite table test.test partition(day=‘2021-12-01’, hour=10) select * from …

10、spark处理大数据时,记得加try catch, 否则因为一条记录有问题报错,整个程序就会停止
11、rdd01 = resultRdd.repartition(10) 假如resultRdd有20个分区,那么执行repartition的task会有20个,而不是10个。rdd01会有10个分区,rdd01后续操作会有10个task
12、分区字段,由string修改为int ,在存储和使用的性能比string 要好
13、spark sql写hive

  • 1)定义schema
    //可以将所有字段内容拼接成一个string,然后在写sparksql语句的时候对这个string进行split。也可以直接在这里定义多个字段
    case class nginxitem(sdkdata: String)
    val schema = StructType(Array(StructField(“sdkdata”,DataTypes.StringType)))
  • 2)将rdd先转换成rowRDD, 然后按照schema进行转换
    val df = hiveContext.createDataFrame(log_rdd.map(Row(_)), schema)
  • 3)insert overwrite table xxx partition(day=‘xxx’) select split(sdkdata,’\t’)[0] call_id…from …

14、rdd.repartition可以防止数据倾斜,另外在将rdd保存到hdfs之前,对rdd重分区,这样可以自定义输出的hdfs的文件数,可防止生成小文件
15、spark累加器在driver端声明,在transform里面使用,最后用rdd的action操作触发计算后,在driver端取其值(使用value方法)
使用Accumulator时,为保证准确性,有几种方式:

  • transform中执行的累加器更新,只使用一次action操作。
  • transform中执行的累加器更新,被使用多次时,则使用cache或persist操作切断依赖。
累加器的错误用法:多个action导致累加器翻倍
	val accum= sc.accumulator(0, "Error Accumulator")
	val data = sc.parallelize(1 to 10)
	//用accumulator统计偶数出现的次数,同时偶数返回0,奇数返回1
	val newData = data.map{
   x => {
   
	  if(x%2 == 0){
   
		accum += 1
		  0
		}else 1
	}}
	//使用action操作触发执行
	newData.count
	//此时accum的值为5,是我们要的结果
	accum.value
	//继续操作,查看刚才变动的数据,foreach也是action操作
	newData.foreach(println)
	//上个步骤没有进行累计器操作,可是累加器此时的结果已经是10了
	//这并不是我们想要的结果
	accum.value

16、spark读取文件的多种方式

    1)读取本地文件:	sc.textFile(file:///usr/local/ljy.txt)
	2)读取hdfs文件:	sc.textFile(hdfs://usr/local/ljy.txt) 或者sc.textFile(/usr/local/ljy.txt)
	3)val fileRdd = sc.hadoopFile[LongWritable, Text, TextInputFormat](inputPath)			
	textFile 也是调用的 hadoopFile, hadoopFile比较灵活一些,比如可以指定压缩格式之类的
	4)spark读取多个hdfs文件	  
	sparkContext.textFile("hdfs://localhost:9000/test/log1, hdfs://localhost:9000/test/log2")

18、spark 参数调优之动态资源分配(Dynamic Resource Allocation)
使spark资源按需分配:高峰和低峰Spark Streaming要处理的数据量相差可能三倍以上,预分配资源会导致低峰的时候资源的大量浪费。
spark.dynamicAllocation.enabled:是否开启动态资源配置,根据工作负载来衡量是否应该增加或减少executor,默认false。
spark.dynamicAllocation.minExecutors: 动态分配最小executor个数,在启动时就申请好的,默认0。
spark.dynamicAllocation.maxExecutors 动态分配最大executor个数,默认infinity。
资源增加策略:application会在task因没有足够资源被挂起的时候去动态申请资源。
资源减少策略:当应用的executor空闲时间超过一定时间后,就会被回收。
19、spark读取hdfs文件形成的RDD的分区数和HDFS文件的split分片数一致,而分片数多数情况下和block数一致,分区数又和task数一致,注意,这里的task数是指运行rdd的总的task数,不是同一时间运行的task数。对于reduceByKey等shuffle后生成的子RDD,其Partition数量依如下顺序确定:1. 方法的第二个参数 > 2. spark.default.parallelism参数 。对于其他非shuffle生成的RDD则其依赖于父RDD的分区个数。除了上述情况,其他rdd的分区数和spark.default.parallelism参数一致。
特别注意:spark.default.parallelism并不是指同一时间并行运行的task(core)的个数,而是在生成执行计划时决定分区数的一个设置。同一时间运行的task数还是由我们设置的总core数决定。spark.default.parallelism一般设置为总core数的3倍,比如总core=100,如果spark.default.parallelism <= 100,那么rdd有<= 100个分区,当有10个运行较快的core跑完之后,他们就空闲了,造成了资源浪费。所以我们的目的是保证所有core都在运行
20、spark读取hdfs文件形成的RDD的分区数和HDFS文件的split分片数一致,而HDFS文件的split分片数与block大小相关。如果一共读取100个hdfs文件,每个文件都大于128M, 那么就会有200+个分区,如果每个文件都不大于128M,那么就只有100个分区
22、spark优化数据结构
(1)优先使用数组及字符串,而不是集合类。也就是:优先使用array,而不是ArrayList,LinkedList,HashMap
(2)避免使用多层嵌套的对象结构,如:public class teacher{private List students=new ArrayList()}。如果非要使用此类结构,可以使用json字符串来保存数据
(3)可以的话,尽量用int代替String。spark应用中,id不要使用常用的uuid,因为无法转换为int,使用自增的id即可
23、spark多个executor在同一台机器上,也可能一台机器只有一个executor
24、spark参数配置优先级:代码里面SparkConf > spark-submit 或 spark-shell >spark-defaults.conf
25、调度平台配置一个spark执行脚本,这个执行脚本可以分配到多台执行节点。那么脚本里面用到的工具应放到hdfs上,每次运行脚本的时候从hdfs下到执行节点本地。否则如果工具放到本地的话,需要每个节点都放一个
26、sparksql小文件优化: hiveContext.sql(“set mapred.reduce.tasks=” + par_num)
par_num的数量就是最后输出的文件个数
27、spark join只适用于二元元组,不适用于多元元组
28、sparkGC调优

  • 1)spark.executor.extraJavaOptions=-XX:+Use

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值