Spark3.x——入门基础(相关知识理解篇)

Spark3.X

需要scala2.12,基于内存的快速、通用、可扩展的大数据分析计算引擎

14年成为Apache顶级项目

采用内存的计算策略,两次MR中间结果不会落盘而是在内存中

一次性的数据计算:各类的框架在处理数据的时候,会从存储的设备中读取数据,进行逻辑操作,然后将处理的结果重新存储到某种介质中

spark是有其生态的存在,包含:core、sql、streaming、MLlib、GraphX

Spark Core

运行环境

模式说明
Local本地模式,idea内并不是本地环境,而是spark-shell模式
StandLone独立部署模式,需修改slave、env文件
Yarnyarn模式,分为client和cluster
举例:将spark3.x的tar包上传linux,解压进入bin目录

1 运行spark-shell(本地模式),进行简单的wc
sc.textFile("/disk3/spark-3.0.0-bin-hadoop3.2/data/word.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect

2 用spark-submit方式
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master local[2] \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10

3 用standlone方式
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://localhost:7077 \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10
spark-submit相关参数解释举例
–class程序入口,包含主函数的类
–master运行的环境local[*]、spark://localhost:7077、Yarn
–executor-memory 2G每个executor可用内存为2G
–total-executor-cores 2所有executor可用cpu核数为2个
application-jarjar包(带位置),hdfs(hdfs:// )、本地文件(file:// )
application-arguments需要传入的参数

历史服务

很显然在运行任务结束后,4040也页面就无法访问到,所以需要配置历史服务器

# 注意:需要先启动 hadoop 集群,HDFS 上的 directory 目录需要提前存在。
# 修改spark-default.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://xxx1:8020/directory

# 修改spark-env.sh文件
export SPARK_HISTORY_OPTS="
-Dspark.history.ui.port=18080 #WEB UI 访问的端口号为 18080
-Dspark.history.fs.logDirectory=hdfs://xxx1:8020/directory #指定历史服务器日志存储路径
-Dspark.history.retainedApplications=30" #指定保存 Application 历史记录的个数,如果超过这个值,旧的应用程序信息将被删除,这个是内存中的应用数,而不是页面上显示的应用数

配置高可用

采用zookeeper

# 关闭spark集群

# 启动zk

# 修改spark-env文件
注释如下内容:
#SPARK_MASTER_HOST=xxx1
#SPARK_MASTER_PORT=7077
添加如下内容:
#Master 监控页面默认访问端口为 8080,但是可能会和 Zookeeper 冲突,所以改成 8989,也可以自定义,访问 UI 监控页面时请注意
SPARK_MASTER_WEBUI_PORT=8989
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER 
-Dspark.deploy.zookeeper.url=xxx1,xxx2,xxx3
-Dspark.deploy.zookeeper.dir=/spark"

# 分发集群,启动spark集群

# 提交任务,需要改变master
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://xxx1:7077,xxx2:7077 \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10

Yarn模式

# 修改spark-env.sh文件
export JAVA_HOME=xxxxxx
YARN_CONF_DIR=xxxx/etc/hadoop

# spark目录内提交
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10

运行架构

计算端

driver:并没有实际的名词叫做driver,而他是作为一种驱动类存在,驱使着整个应用运行的程序

executor:是集群worker中的一个jvm进程,具体运行具体的任务Task,彼此之前相互独立,生命周期只局限于整个应用的运行,即使有executor节点发生故障,spark应用也会继续进行,会将出错节点任务调度到其他executor节点上;作为执行器,它负责将运行结果返回给driver,它自身包含块管理器(BlockManager)为用户程序中需要缓存的rdd进行内存支持,所以rdd是直接缓存在executor进程内,因而可充分利用缓存数据计算

资源端

当我们运行standlone模式的时候会出现两个进程master和worker,master负责资源的调度和分配,并监控集群,而work就是由master分配资源对数据进行并行的处理和计算

如果单纯让资源和计算直接交互不就使得耦合性很高,所以采用了AM(ApplicationMaster),从而整体的效果计算计算端—>AM—>资源端

核心概念

硬件资源配置

名词解释
–num-executorsexecutor的数目
–executor-memory每个executor的内存大小
–executor-cores每个executor的cpu核数

并行度

Parallelism:多任务并行操作,分布式计算采用的就是并行

DAG

有向无环图:并不是真正的存在此图形,而是spark程序直接映射成数据流的高级抽象模型,更加易于理解

核心编程

相关数据结构

名词解释
RDD弹性分布式数据集
累加器共享写变量
广播变量共享读变量

RDD可以形象理解成是一个计算单元,就是要计算的每个步骤中的其中一个小步骤,我们可以拿word count举例

# 1 进入textfile内
  def textFile(
  ...
  {
    ...
    hadoopFile(path,classOf[TextInputFormat],classOf[LongWritable], classOf[Text],minPartitions).map(pair =>pair._2.toString).setName(path)
  }
)
  
# 进入hadoopFile内
  def hadoopFile[K, V]{
  ...
    new HadoopRDD(
      this,
      confBroadcast,
      Some(setInputPathsFunc),
      inputFormatClass,
      keyClass,
      valueClass,
      minPartitions).setName(path)
  }
  
# 发现HadoopRDD

# 2 进入flatMap内
  def flatMap {
    ...
    new MapPartitionsRDD[U, T](this, (_, _, iter) => iter.flatMap(cleanF))
  }
  
# 发现MapPartitionsRDD
......
......

每一个计算的方法都是由RDD组成,RDD数据处理的方式类似于java IO操作,装饰者模式,在io操作中不管是字符流还是字节流都是缓冲流存在,但是在rdd内没有缓冲这一操作,都是流式处理,中间不存储数据

RDD

特点

弹性的、不可变的、可分区的、元素可并行计算的

弹性

存储的弹性(磁盘、内存):内存不够需要落盘

容错:数据丢失自动恢复,每一个步骤的计算都会记录位置

计算:计算出错,重试的机制

分片:可以根据需要重新分区

分布式

数据集:RDD只是封装了计算的逻辑,并不保存数据

数据抽象:RDD是一个抽象类,需要子类具体实现

不可变:RDD封装了计算逻辑,不可改变,要想改变结构只能通过其他RDD改变(其他计算逻辑)

可分区、分区计算

五大属性
 *  - A list of partitions
 *  - A function for computing each split
 *  - A list of dependencies on other RDDs
 *  - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
 *  - Optionally, a list of preferred locations to compute each split on (e.g. block locations for
 *    an HDFS file)
 
# 1 分区列表
# 2 每个分区有计算的函数
# 3 RDD之间有依赖关系
# 4 分区器:怎么分区的,按什么规则
# 5 首选位置:task发给哪一个executor去执行,移动数据不如移动计算
并行度和分区
# 可以手动指定分区数目,后面接的2就是两个分区
val rdd: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4), 2)

# 这时调用另存文件的时候,就会保存两个文件===>两个分区
rdd.saveAsTextFile("output")

# 注意:默认的并行度是按照线程数
override def defaultParallelism(): Int =  scheduler.conf.getInt("spark.default.parallelism", totalCores)

集合作为数据源:数据是怎么被分区的?

# 源码
    def positions(length: Long, numSlices: Int): Iterator[(Int, Int)] = {
      (0 until numSlices).iterator.map { i =>
        val start = ((i * length) / numSlices).toInt
        val end = (((i + 1) * length) / numSlices).toInt
        (start, end)
      }
    }
    
# 采用的上述算法 数据总数目,分区数量 进行计算位置得出具体数据对应哪一个分区

单文件作为数据源:数据是怎么被分区的?

# 默认最小分区数是2,注意这里是默认最小,分区比2小就是不一定就是2
def defaultMinPartitions: Int = math.min(defaultParallelism, 2)

# 分区规则实现:
# 其实我们可以发现,spark是用了Hadoop中mapreduce读取文件方式
# 追溯FileInputFormat,其中有getSplits方法
# 该方法内有totalSize,这里要注意文件长度包含隐藏的字符(比如换行、回车)
totalSize += file.getLen();

# 每个分区存放几个字节
long goalSize = totalSize / (numSplits == 0 ? 1 : numSplits);

# 这里提及Hadoop中读取文件1.1概念,即剩余字节数大于上一个字节数的10%,产生新分区,否则不会产生新分区
# 因为当我们有7个字节文件,默认两个分区,但最后却是3个分区,就是因为7/2=3,还剩1个字节没地方放,又1>3*0.1,所以产生新分区,综上就是3个分区

# 继续解释
# 假设某个文件内容为1234567
# 按照上面理论,三个分区,三个文件,那要怎么读取?每个分区保存的是什么数据呢?

1、spark采用hadoop读文件,那应该是按行读取
2、数据读取应该是以偏移量作为单位

注意:上面计算是每个7/2=3,每个分区3个,按照偏移量排如下,偏移量范围是左开右闭
分区 偏移量范围
0   [0,3]
1   (3,6]
2   (6,7]

虽说这样理论排列,但并非如此,因为是按行,所以在读取刚开始的时候就知道一行数据,就会把一行数据放在一个分区文件,所以最后排列方式是,第一个文件为1234567,其他两个文件为空,其实这里可以想到贪婪的算法,既要考虑偏移量范围还要考虑一行,所以一行数据所在偏移量被读后,该行其他字节就会连着被读的偏移量

多文件作为数据源,分区以文件为单位进行分区

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spark 3.x与Spark 2.x的区别主要有以下几点: 1. 支持Python 3:Spark 3.x支持Python 3,而Spark 2.x只支持Python 2。 2. 更好的性能:Spark 3.x在性能方面有所提升,包括更快的查询速度和更高的并行度。 3. 更好的SQL支持:Spark 3.x引入了一些新的SQL功能,包括ANSI SQL支持、更好的窗口函数支持和更好的类型推断。 4. 更好的流处理支持:Spark 3.x引入了一些新的流处理功能,包括更好的状态管理和更好的容错性。 5. 更好的机器学习支持:Spark 3.x引入了一些新的机器学习功能,包括更好的特征工程支持和更好的模型解释性。 总的来说,Spark 3.x相对于Spark 2.x来说是一个更加成熟和功能更加丰富的版本。 ### 回答2: Spark 3.x与Spark 2.x有很多显著的不同之处。 首先,Spark 3.x通过引入新的API和更好的优化器提高了性能和可伸缩性。 其次,它更易于使用,使开发人员更容易使用Spark构建复杂的应用程序。以下是Spark 3.x与Spark 2.x的主要区别: 1.新的API: Spark 3.x引入了一些新的API,如Delta Lake、Kubernetes、Pandas UDF等。Delta Lake是一个开源数据湖解决方案,使数据管理、可靠性和性能变得更加容易。有了Kubernetes,Spark可以更好地与容器化环境集成。同时,Pandas UDF支持Python的Pandas库,可以处理大量的数据。 2.优化器的改进: Spark 3.x引入了新的优化器(称为Spark 3.0 Optimizer),可显著提高查询性能。这个优化器使用基于规则的优化技术和成本模型,通过优化查询来提高查询性能。 3.支持更多的数据源: Spark 3.x做了很多工作来改进数据源API。它提供了更广泛的数据源支持,包括Apache Kafka、Amazon S3、Google BigQuery等。 4.增强了机器学习功能: Spark 3.x提供了更多的基于机器学习的库和工具,包括Python的Pandas和Scikit-Learn库的元数据集成,支持PySpark的PythonML库等。 5.交互式查询支持: Spark 3.x引入了新的交互式查询API,这使得Spark变得更加友好。您可以使用Spark SQL进行查询,该工具支持批处理和流处理查询。 总之,Spark 3.x相比Spark 2.x更加强大和易于使用。它提供了更多的API、更好的优化器和更好的可扩展性。这些变化使得Spark在处理大数据方面更加卓越,让开发人员更轻松地构建复杂的应用程序。 ### 回答3: Apache Spark是一个快速、通用,基于内存的分布式计算系统,已成为大数据领域中最受欢迎的计算框架之一。Spark 3.x是Apache Spark计算框架的最新版本,相比于之前的版本有很多新的特性和功能,以下是Spark 3.x与Spark 2.x的主要区别。 1. Python API重构 Python是Apache Spark中最受欢迎的编程语言,但它在之前的版本中没有得到很好的支持。在Spark 3.x中,Python API被重构,在性能和易用性方面都有了大幅改善。 2. 完全支持SQL ANSI标准 Spark 3.x从核心到应用都支持SQL ANSI标准。这意味着,Spark 3.x支持更多的SQL函数和操作,并且更加符合SQL标准。 3. 兼容性增强 Spark 3.x不再依赖于Hadoop,这意味着它能够更好地与其他数据源进行集成。同时,它也支持Kubernetes和Docker的容器化部署方式。 4. AI支持增加 Spark 3.x引入了许多新的机器学习和深度学习算法,例如支持自动编码器和多标签分类器的模型,以及更好的分布式模型训练功能。 5. 其它特性 Spark 3.x还支持Delta Lake,这是一个可靠、高性能的事务性存储。同时,它还提供性能更好的Spark流式处理API和更好的结构化API,这些API在处理大规模结构化数据时更加高效。 总之,Spark 3.x相比于Spark 2.x在性能、兼容性、AI支持和其它特性方面都有很大的改进。无论是开发人员还是数据科学家,Spark 3.x都能够提供更好的用户体验和更高的数据处理效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友培

数据皆开源!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值