Spark课程总结

一、

1、spark是什么
spark是针对于大规模数据处理的统一分析引擎,它是基于内存计算框架,计算速度非常之快,但是它仅仅只是涉及到计算,并没有涉及到数据的存储,后期需要使用spark对接外部的数据源,比如hdfs。

2、spark四大特性
速度快
job的输出结果可以保存在内存
spark任务以线程的方式运行在进程中

易用性
可以快速去编写spark程序通过 java/scala/python/R/SQL等不同语言

通用性
一个==生态系统==,包含了很多模块,
sparksql:通过sql去开发spark程序做一些离线分析
sparkStreaming:主要是用来解决公司有实时计算的这种场景
Mlib:它封装了一些机器学习的算法库
Graphx:图计算

兼容性
spark程序就是一个计算逻辑程序,这个任务要运行就需要计算资源(内存、cpu、磁盘),
哪里可以给当前这个任务提供计算资源,就可以把spark程序提交到哪里去运行
standAlone(后期使用较多)
它是spark自带的独立运行模式,整个任务的资源分配由spark集群的老大Master负责
yarn(后期使用较多)
可以把spark程序提交到yarn中运行,整个任务的资源分配由yarn中的老大ResourceManager负责
mesos
它也是apache开源的一个类似于yarn的资源调度平台

3、简述spark与mapreduce的区别?
spark处理速度为什么比mapreduce要快

基于内存与磁盘
(1)mapreduce任务后期再计算的时候,每一个job的输出结果会落地到磁盘,后续有其他的job需要依赖于前面job的输出结果,这个时候就需要进行大量的磁盘io操作。性能就比较低。
(2)spark任务后期再计算的时候,job的输出结果可以保存在内存中,后续有其他的job需要依赖于前面job的输出结果,这个时候就直接从内存中获取得到,避免了磁盘io操作,性能比较高
对于spark程序和mapreduce程序都会产生shuffle阶段,在shuffle阶段中它们产生的数据都会落地到磁盘。

进程与线程
(1)mapreduce任务以进程的方式运行在yarn集群中,比如程序中有100个MapTask,一个task就需要一个进程,这些task要运行就需要开启100个进程。
(2)spark任务以线程的方式运行在进程中,比如程序中有100个MapTask,后期一个task就对应一个线程,这里就不在是进程,这些task需要运行,
这里可以极端一点:只需要开启1个进程,在这个进程中启动100个线程就可以了。进程中可以启动很多个线程,而开启一个进程与开启一个线程需要的时间和调度代价是不一样。 开启一个进程需要的时间远远大于开启一个线程。

二、
1、rdd的概念
RDD(Resilient Distributed Dataset)叫做弹性 分布式 数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合.
Dataset: 就是一个集合,存储很多数据.
Distributed:它内部的元素进行了分布式存储,方便于后期进行分布式计算.
Resilient: 表示弹性,rdd的数据是可以保存在内存或者是磁盘中.

2、rdd的五大属性
(1)A list of partitions

一个分区列表,数据集的基本组成单位。
(2)A function for computing each split

一个计算每个分区的函数
(3)A list of dependencies on other RDDs

一个rdd会依赖于其他多个rdd
通过lineage血统记录下rdd与rdd之间的依赖关系
好处
就在于后期某个rdd的部分分区数据丢失的时候,可以通过血统进行重新计算恢复得到
这也是spark任务自身的一个容错机制
(4)Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)

(可选项)一个Partitioner,即RDD的分区函数
(5)Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)

一个列表,存储每个Partition的优先位置(可选项)

3、rdd的创建方式
1、通过已经存在的scala集合去构建

2、加载外部的数据源去构建

3、从已经存在的rdd进行转换生成一个新的rdd

4、rdd的算子操作分类

1、transformation(转换)
根据已经存在的rdd转换生成一个新的rdd, 它是延迟加载,它不会立即执行
map / flatMap / reduceByKey 等

2、action (动作)
它会真正触发任务的运行,将rdd的计算的结果数据返回给Driver端,或者是保存结果数据到外部存储介质中
collect / saveAsTextFile 等

5、RDD常见的算子操作说明
重点需要掌握
map / mapPartitions foreach / foreachPartition算子区别操作?

1) map / mapPartitions (transformation算子)
map:用于遍历RDD,将函数f应用于每一个元素,返回新的RDD
mapPartitions:用于遍历操作RDD中的每一个分区,返回生成一个新的RDD。
如果在映射的过程中,需要频繁创建额外的对象,使用mapPartitions要比map高效。
比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。

2) foreach / foreachPartition (action算子)
foreach: 用于遍历RDD, 将函数f应用于每一个元素,无返回值。

foreachPartition: 用于遍历操作RDD中的每一个分区,无返回值。:

一般使用mapPartitions或者foreachPartition算子比map和foreach更加高效,推荐使用。

3) coalesce/ repartition 算子
coalesce: 合并分区/减少分区 默认不shuffle
默认 coalesce 不能扩大分区数量。除非添加true的参数,或者使用repartition。
repartition: 重新分区, 有shuffle
repartition(numPartitions)其本质是调用了coalesce(numPartitions,true)方法, 第二个参数默认是true,表示会产生shuffle。
适用场景:
1、如果要shuffle,都用 repartition
2、不需要shuffle,仅仅是做分区的合并,coalesce
3、repartition常用于扩大分区。

三、

1、RDD的依赖关系
RDD和它依赖的父RDD的关系有两种不同的类型: 窄依赖(narrow dependency)和宽依赖(wide dependency)

窄依赖
窄依赖指的是每一个父RDD的Partition, 最多被子RDD的一个Partition使用,
所有的窄依赖不会产生shuffle: map/flatMap/filter/union等
总结:窄依赖我们形象的比喻为独生子女
宽依赖
宽依赖指的是多个子RDD的Partition, 会依赖同一个父RDD的Partition,
所有的宽依赖会产生shuffle: reduceByKey/sortByKey/groupBy/groupByKey/join等等
总结:宽依赖我们形象的比喻为超生

join分为宽依赖和窄依赖,如果RDD有相同的partitioner,那么将不会引起shuffle,这种join是窄依赖,反之就是宽依赖
Lineage(即血统)
RDD只支持粗粒度转换, 即只记录单个块上执行的单个操作。
将创建RDD的一系列Lineage(即血统)记录下来,以便恢复丢失的分区
RDD的Lineage会记录RDD的元数据信息和转换行为,lineage保存了RDD的依赖关系,当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
2、RDD的缓存机制

1、什么是rdd的缓存机制、好处是什么?
可以把一个rdd的数据缓存起来,后续有其他的job需要用到该rdd的结果数据,可以直接从缓存中获取得到,避免了重复计算。缓存是加快后续对该数据的访问操作。

2、如何对rdd设置缓存? cache和persist方法的区别是什么?
RDD通过persist方法或cache方法可以将前面的计算结果缓存。
但是并不是这两个方法被调用时立即缓存,而是触发后面的action时,该RDD将会被缓存在计算节点的内存中,并供后面重用。

3、什么时候设置缓存?
1、某个rdd的数据后期被使用了多次
公共rdd进行持久化,避免后续需要,再次重新计算,提升效率。
2、rdd的数据来之不易时
为了获取得到一个rdd的结果数据,经过了大量的算子操作或者是计算逻辑比较复杂
3、如何清除缓存?
1、自动清除 :一个application应用程序结束之后,对应的缓存数据也就自动清除

2、手动清除 :调用rdd的unpersist方法

四、

1、sparksql简介

Spark SQL is Apache Spark’s module for working with structured data.

SparkSQL是apache Spark用来处理结构化数据的一个模块

大数据技术宏观上进行分类:
 
(1)数据存储
	HDFS  HBASE
	
(2)数据计算
	   a. 离线计算
	   		MR 、Hive 、RDD(spark-core)、sparksql
	   b. 实时计算
	        sparkStreaming 、Flink
 

2、sparksql特性
1、易整合
将SQL查询与Spark程序无缝混合
可以使用不同的语言进行代码开发(java、scala、python、R)

2、统一的数据源访问
以相同的方式连接到任何数据源

3、兼容hive
sparksql兼容hivesql

4、标准的数据库连接
支持标准的数据库连接JDBC或者ODBC

3、DataFrame简介
在Spark中,DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库的二维表格
DataFrame带有Schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型,但底层做了更多的优化

4、DataFrame和RDD对比
RDD可以把它内部元素看成是一个java对象
DataFrame可以把内部是一个Row对象,它表示一行一行的数据

RDD
优点

1、编译时类型安全
开发会进行类型检查,在编译的时候及时发现错误

2、具有面向对象编程的风格
缺点

1、构建大量的java对象,占用了大量heap堆空间,导致频繁的GC
2、数据的序列化和反序列性能开销很大
DataFrame
DataFrame引入了schema元信息和off-heap(堆外内存)
优点

DataFrame引入了schema元信息,解决了rdd数据的序列化和反序列性能开销很大这个缺点。
DataFrame引入了off-heap,解决了rdd构建大量的java对象 占用了大量heap堆空间,导致频繁的GC这个缺点。
缺点

1、编译时类型不安全
2、不在具有面向对象编程的风格
5、DataFrame常用的操作
1、DSL风格语法 : spark自身提供了一套Api

/加载数据
val rdd1=sc.textFile("/person.txt").map(x=>x.split(" "))
//定义一个样例类
case class Person(id:String,name:String,age:Int)
//把rdd与样例类进行关联
val personRDD=rdd1.map(x=>Person(x(0),x(1),x(2).toInt))
//把rdd转换成DataFrame
val personDF=personRDD.toDF
 
//打印schema信息
personDF.printSchema
 
//展示数据
personDF.show
 
//查询指定的字段
personDF.select("name").show
personDF.select($"name").show
personDF.select(col("name").show
                
//实现age+1
 personDF.select($"name",$"age",$"age"+1)).show   
 
//实现age大于30过滤
 personDF.filter($"age" > 30).show
  
 //按照age分组统计次数
 personDF.groupBy("age").count.show 
   
//按照age分组统计次数降序
 personDF.groupBy("age").count().sort($"count".desc)show 

2、SQL风格语法

  • 把dataFrame注册成一张表,通过sparkSession.sql(sql语句)操作该表数据
//DataFrame注册成表
personDF.createTempView("person")
 
//使用SparkSession调用sql方法统计查询
spark.sql("select * from person").show
spark.sql("select name from person").show
spark.sql("select name,age from person").show
spark.sql("select * from person where age >30").show
spark.sql("select count(*) from person where age >30").show
spark.sql("select age,count(*) from person group by age").show
spark.sql("select age,count(*) as count from person group by age").show
spark.sql("select * from person order by age desc").show

6、通过IDEA开发程序实现把RDD转换DataFrame
1、利用反射机制
事先可以确定DataFrame的schema信息
定义一个样例类,样例类中的属性,通过反射之后生成DataFrame的schema信息
2、通过StructType动态指定schema信息
事先不确定DataFrame的schema信息,在开发代码的过程中动态指定
其本质调用底层方法

 //1、构建SparkSession对象
    val spark: SparkSession = SparkSession.builder().appName("StructTypeSchema").master("local[2]").getOrCreate()
 
    //2、获取sparkContext对象
    val sc: SparkContext = spark.sparkContext
    sc.setLogLevel("warn")
 
    //3、读取文件数据
    val data: RDD[Array[String]] = sc.textFile("E:\\person.txt").map(x=>x.split(" "))
 
    //4、将rdd与Row对象进行关联
    val rowRDD: RDD[Row] = data.map(x=>Row(x(0),x(1),x(2).toInt))
 
    //5、指定dataFrame的schema信息   
    //这里指定的字段个数和类型必须要跟Row对象保持一致
    val schema=StructType(
        StructField("id",StringType)::
        StructField("name",StringType)::
        StructField("age",IntegerType)::Nil
    )
 
    val dataFrame: DataFrame = spark.createDataFrame(rowRDD,schema)
    dataFrame.printSchema()
    dataFrame.show()
 
    dataFrame.createTempView("user")
    spark.sql("select * from user").show()
 
 
    spark.stop()
 
  }

五、

1、sparksql操作hivesql

  • 主要是理解sparksql的四大特性中的
    • 第三点 sparksql兼容hivesql
      • .enableHiveSupport() //-----开启对hive的支持
def main(args: Array[String]): Unit = {
    //1、构建SparkSession对象
    val spark: SparkSession = SparkSession.builder()
      .appName("HiveSupport")
      .master("local[2]")
      .enableHiveSupport() //-----开启对hive的支持
      .getOrCreate()
      
    //2、直接使用sparkSession去操作hivesql语句
 
      //2.1 创建一张hive表
       spark.sql("create table people(id string,name string,age int) row format delimited fields terminated by ','")
 
      //2.2 加载数据到hive表中
       spark.sql("load data local inpath './data/kaikeba.txt' into table people ")
 
      //2.3 查询
      spark.sql("select * from people").show()
 
    spark.stop()
  }
}
  • 2、sparksql操作jdbc数据源

  • 1、sparksql通过 JDBC加载mysql表的数据
  • 2、sparksql处理完成的数据,保存到mysql表中
//todo:通过sparksql把结果数据写入到mysql表中
object Data2Mysql {
  def main(args: Array[String]): Unit = {
    //1、创建SparkSession
    val spark: SparkSession = SparkSession
                                .builder()
                                .appName("Data2Mysql")
                                .master("local[2]")
                                .getOrCreate()
    //2、读取mysql表中数据
        //2.1 定义url连接
        val url="jdbc:mysql://node03:3306/spark"
        //2.2 定义表名
        val table="user"
        //2.3 定义属性
        val properties=new Properties()
        properties.setProperty("user","root")
        properties.setProperty("password","123456")
 
    val mysqlDF: DataFrame = spark.read.jdbc(url,table,properties)
 
    //把dataFrame注册成一张表
      mysqlDF.createTempView("user")
 
    //通过sparkSession调用sql方法
      //需要统计经度和维度出现的人口总数大于1000的记录 保存到mysql表中
      val result: DataFrame = spark.sql("select * from user where age > 30")
 
    //保存结果数据到mysql表中
         result.write.mode("append").jdbc(url,"kaikeba",properties)
//result.write.mode(args(0)).jdbc(url,args(1),properties       
    //mode:指定数据的插入模式
        //overwrite: 表示覆盖,如果表不存在,事先帮我们创建
        //append   :表示追加, 如果表不存在,事先帮我们创建
        //ignore   :表示忽略,如果表事先存在,就不进行任何操作
        //error    :如果表事先存在就报错(默认选项)
 
    //关闭
     spark.stop()
  }
}
 

打包—提交到集群

spark-submit \
--master spark://node01:7077 \
--class com.kaikeba.sql.Data2Mysql \
--executor-memory 1g \
--total-executor-cores 4 \
--driver-class-path /home/hadoop/mysql-connector-java-5.1.38.jar \
--jars /home/hadoop/mysql-connector-java-5.1.38.jar \
spark_class02-1.0-SNAPSHOT.jar \
append  kaikeba
  •  3、sparksql中自定义函数

  • 自定义udf函数
  • 核心代码
def main(args: Array[String]): Unit = {
    //1、创建SparkSession
    val sparkSession: SparkSession = SparkSession.builder().appName("SparkSQLFunction").master("local[2]").getOrCreate()
 
    //2、构建数据源生成DataFrame
    val dataFrame: DataFrame = sparkSession.read.text("E:\\data\\test_udf_data.txt")
 
    //3、注册成表
    dataFrame.createTempView("t_udf")
 
 
    //4、实现自定义的UDF函数
 
        //小写转大写
        sparkSession.udf.register("low2Up",new UDF1[String,String]() {
          override def call(t1: String): String = {
            t1.toUpperCase
          }
        },StringType)
 
        //大写转小写
        sparkSession.udf.register("up2low",(x:String)=>x.toLowerCase)
 
 
    //4、把数据文件中的单词统一转换成大小写
    sparkSession.sql("select  value from t_udf").show()
    sparkSession.sql("select  low2Up(value) from t_udf").show()
    sparkSession.sql("select  up2low(value) from t_udf").show()
 
    sparkSession.stop()
 
  }

4、sparksql整合hive
步骤

1、需要把hive安装目录下的配置文件hive-site.xml, 拷贝到每一个spark安装目录下对应的conf文件夹中
2、需要一个连接mysql驱动的jar包,拷贝到spark安装目录下对应的jars文件夹中
3、可以使用spark-sql脚本 后期执行sql相关的任务
使用方式

spark-sql \
--master spark://node01:7077 \
--executor-memory 1g \
--total-executor-cores 4 \
--conf spark.sql.warehouse.dir=hdfs://node01:8020/user/hive/warehouse 
  • 应用场景
#!/bin/sh
#定义sparksql提交脚本的头信息
SUBMITINFO="spark-sql --master spark://node01:7077 --executor-memory 1g --total-executor-cores 4 --conf spark.sql.warehouse.dir=hdfs://node01:8020/user/hive/warehouse" 
#定义一个sql语句
SQL="select * from default.hive_source;" 
#执行sql语句   类似于 hive -e sql语句
echo "$SUBMITINFO" 
echo "$SQL"
$SUBMITINFO -e "$SQL"

  • 42
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个Spark课程设计: 题目:基于Spark的电影推荐系统设计与实现 设计目标: 构建一个基于Spark的电影推荐系统,实现对用户喜好的预测,为用户推荐个性化的电影列表。主要包括以下功能: 1. 数据清洗和预处理:使用Spark对电影数据进行清洗和预处理,包括数据去重、缺失值填充、数据格式转换等。 2. 基于协同过滤的推荐算法:使用Spark中的协同过滤算法,分别实现基于用户和基于物品的推荐算法,并对推荐结果进行评估和优化。 3. 基于内容的推荐算法:使用Spark对电影内容进行分析和处理,提取出电影的类别、导演、演员等特征,并结合用户历史评分数据,实现基于内容的推荐算法。 4. 基于深度学习的推荐算法:使用Spark的深度学习库,设计并实现基于神经网络的推荐算法,提升推荐效果。 5. 数据可视化展示:使用Spark的可视化工具,将推荐结果以图表的形式展示出来,方便用户查看和比较。 实现步骤: 1. 数据清洗和预处理:使用Spark对电影数据进行清洗和预处理,包括数据去重、缺失值填充、数据格式转换等。 2. 基于协同过滤的推荐算法:使用Spark中的协同过滤算法,分别实现基于用户和基于物品的推荐算法,并对推荐结果进行评估和优化。 3. 基于内容的推荐算法:使用Spark对电影内容进行分析和处理,提取出电影的类别、导演、演员等特征,并结合用户历史评分数据,实现基于内容的推荐算法。 4. 基于深度学习的推荐算法:使用Spark的深度学习库,设计并实现基于神经网络的推荐算法,提升推荐效果。 5. 数据可视化展示:使用Spark的可视化工具,将推荐结果以图表的形式展示出来,方便用户查看和比较。 评估指标: 1. 推荐准确度:使用均方根误差(RMSE)或平均绝对误差(MAE)等评估指标,对推荐结果进行评估。 2. 推荐覆盖率:使用推荐系统的覆盖率作为评估指标,评估推荐系统的覆盖面和推荐多样性。 3. 推荐新颖性:使用新颖性评估指标,评估推荐系统对新用户和新物品的推荐效果。 4. 推荐实时性:使用响应时间和并发处理能力等指标,评估推荐系统的实时性和并发性能。 总结: 通过本次课程设计,学生将掌握Spark的基本操作和常用算法,了解推荐系统的原理和应用,培养数据分析和建模能力,并具备大数据处理和分析的能力。同时,通过对推荐系统的评估和优化,学生能够深入理解推荐系统的实现方法和关键技术,为今后从事数据分析和机器学习相关工作打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值