spark概述和少部分算子之入门

一、spark概述

在这里插入图片描述
1.Spark 的安装与部署
Spark 的安装部署方式有以下几种模式:
 Standalone
 YARN
 Mesos
 Amazon EC2()Spark Standalone 伪分布的部署

配置文件:conf/spark-env.sh
 export JAVA_HOME=/root/training/jdk1.7.0_75
 export SPARK_MASTER_HOST=spark81
 export SPARK_MASTER_PORT=7077

下面的可以不写,默认
 export SPARK_WORKER_CORES=1
 export SPARK_WORKER_MEMORY=1024
)Spark Standalone 全分布的部署

配置文件:conf/spark-env.sh
 export JAVA_HOME=/root/training/jdk1.7.0_75
 export SPARK_MASTER_HOST=spark82
 export SPARK_MASTER_PORT=7077

下面的可以不写,默认
 export SPARK_WORKER_CORES=1
 export SPARK_WORKER_MEMORY=1024

配置文件:conf/slave
 spark83
 spark84
在这里插入图片描述
3、Spark HA 的实现
)基于文件系统的单点恢复
主要用于开发或测试环境。当 spark 提供目录保存 spark Application 和 worker 的
注册信息,并将他们的恢复状态写入该目录中,这时,一旦 Master 发生故障,就可以
通过重新启动 Master 进程(sbin/start-master.sh),恢复已运行的 spark Application 和
worker 的注册信息。
基于文件系统的单点恢复,主要是在 spark-en.sh 里对 SPARK_DAEMON_JAVA_OPTS设置
配置参数
参考值
spark.deploy.recoveryMode
设置为 FILESYSTEM 开启单点恢复功能,默认值:NONE
spark.deploy.recoveryDirectory Spark 保存恢复状态的目录
在这里插入图片描述
参考:
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=FILESYSTEM
-Dspark.deploy.recoveryDirectory=/root/training/spark-2.1.0-bin-hadoop2.
4/recovery"
测试:
1、在 spark82 上启动 Spark 集群
2、在 spark83 上启动 spark shell
MASTER=spark://spark82:7077 spark-shell
3、在 spark82 上停止 master
stop-master.sh
4、观察 spark83 上的输出:
在这里插入图片描述
5、在 spark82 上重启 master
start-master.sh
)基于 Zookeeper 的 Standby Masters
ZooKeeper 提供了一个 Leader Election 机制,利用这个机制可以保证虽然集群
存在多个 Master,但是只有一个是 Active 的,其他的都是 Standby。当 Active 的
Master 出现故障时,另外的一个 Standby Master 会被选举出来。由于集群的信息,
包括 Worker, Driver 和 Application 的信息都已经持久化到 ZooKeeper,因此在切
换的过程中只会影响新 Job 的提交,对于正在进行的 Job 没有任何的影响。加入
ZooKeeper 的集群整体架构如下图所示。
在这里插入图片描述
参考:export
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER
-Dspark.deploy.zookeeper.url=spark82:2181,spark83:2181,spark84:2181
-Dspark.deploy.zookeeper.dir=/spark"

另外:每个节点上,需要将以下两行注释掉
在这里插入图片描述
执行 Spark Demo 程序
1、执行 Spark Example 程序
)示例程序: S P A R K H O M E / e x a m p l e s / j a r s / s p a r k − e x a m p l e s 2 . 11 − 2.1.0. j a r ( ∗ ) 所 有 的 示 例 程 序 : SPARK_HOME/examples/jars/spark-examples_2.11-2.1.0.jar (*)所有的示例程序: SPARKHOME/examples/jars/sparkexamples2.112.1.0.jarEXAMPLE_HOME/examples/src/main
有 Java、Scala 等等等
)Demo:蒙特卡罗求 PI
命令:
spark-submit
–master
spark://spark81:7077
–class
org.apache.spark.examples.SparkPi examples/jars/spark-examples_2.11-2.1.0.jar 100
2、使用 Spark Shell
spark-shell 是 Spark 自带的交互式 Shell 程序,方便用户进行交互式编程,用户可
以在该命令行下用 scala 编写 spark 程序。
)启动 Spark Shell:spark-shell
也可以使用以下参数:
参数说明:
–master spark://spark81:7077 指定 Master 的地址
–executor-memory 2g 指定每个 worker 可用内存为 2G
–total-executor-cores 2 指定整个集群使用的 cup 核数为 2 个
例如:
spark-shell
–master
spark://spark81:7077
–executor-memory
2g
–total-executor-cores 2
)注意:
如果启动 spark shell 时没有指定 master 地址,但是也可以正常启动 spark shell
和执行 spark shell 中的程序,其实是启动了 spark 的 local 模式,该模式仅在本机
启动一个进程,没有与集群建立联系。
请注意 local 模式和集群模式的日志区别:
在这里插入图片描述
(*)在 Spark Shell 中编写 WordCount 程序程序如下:
sc.textFile(“hdfs://192.168.88.111:9000/data/data.txt”).flatMap(.split("
")).map((
,1)).reduceByKey(+).saveAsTextFile(“hdfs://192.168.88.111:9000/output/spark
/wc”)
说明:
 sc 是 SparkContext 对象,该对象时提交 spark 程序的入口
 textFile(“hdfs://192.168.88.111:9000/data/data.txt”)是 hdfs 中读取数据
 flatMap(.split(" "))先 map 在压平
 map((
,1))将单词和 1 构成元组
 reduceByKey(+)按照 key 进行 reduce,并将 value 累加
 saveAsTextFile(“hdfs://192.168.88.111:9000/output/spark/wc”) 将 结 果 写 入 到hdfs 中

二、IDEA实现WC

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>sparkfuxi</artifactId>
        <groupId>com.ccj.pxj</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sparkcore</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>2.2.1</version>
            <!--<scope>provided</scope>-->
        </dependency>
        <!-- 导入spark sql的依赖 -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.11</artifactId>
            <version>2.2.1</version>
            <!-- <scope>provided</scope>-->
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive_2.11</artifactId>
            <version>2.2.1</version>
            <!--
            <scope>provided</scope>
            -->
            <!-- 导入spark streaming的依赖-->


        </dependency>




        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>0.10.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.spark-project.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>1.2.1.spark2</version>
            <!--
            <scope>provided</scope>
            -->
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming_2.11</artifactId>
            <version>2.1.1</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>Test_Spark</finalName>
        <plugins>
            <!-- 设置项目编译版本-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!-- 用于编译scala代码到class -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass></mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
package com.ccj.pxj.wc

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object WCSparkCore {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setAppName("pxj").setMaster("local[4]")
    val sc: SparkContext = new SparkContext(sparkConf)
    val datas: RDD[String] = sc.textFile("data/wc.txt")
    val ss = datas.flatMap(_.split(",")).map((_, 1)).reduceByKey(_ + _).saveAsTextFile("data/wcOut.txt")
    sc.stop()
  }

}

三、sparkcore

3.1RDD

什么是 RDD?
RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是 Spark 中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD
具有数据流模型的特点:自动容错、位置感知性调度和可伸缩性。RDD 允许用户在执行多个查询时显式地将工作集缓存在内存中,后续的查询能够重用工作集,
这极大地提升了查询速度

3.2 RDD五大特征

一组分片(Partition),即数据集的基本组成单位。对于 RDD 来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建 RDD时指定 RDD 的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的 CPU Core 的数目。
一个计算每个分区的函数。Spark 中 RDD 的计算是以分片为单位的,每个 RDD都会实现 compute 函数以达到这个目的。compute 函数会对迭代器进行复合,不需要保存每次计算的结果。
 RDD 之间的依赖关系。RDD 的每次转换都会生成一个新的 RDD,所以 RDD 之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark 可以通过这个依赖关系重新计算丢失的分区数据,而不是对 RDD 的所有分区进行重新计算。
一个 Partitioner,即 RDD 的分片函数。当前 Spark 中实现了两种类型的分片函 数 , 一 个 是 基 于 哈 希 的 HashPartitioner , 另 外 一 个 是 基 于 范 围 的RangePartitioner。只有对于于 key-value 的 RDD,才会有 Partitioner,非 key-value的 RDD 的 Parititioner 的值是 None。Partitioner 函数不但决定了 RDD 本身的分片数量,也决定了 parent RDD Shuffle 输出时的分片数量。
一个列表,存储存取每个 Partition 的优先位置(preferred location)。对于一个 HDFS 文件来说,这个列表保存的就是每个 Partition 所在的块的位置。按照“移动数据不如移动计算”的理念,Spark 在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置

3.3 RDD创建

RDD 的创建方式
通过外部的数据文件创建,如 HDFS val rdd1 = sc.textFile(“hdfs://192.168.88.111:9000/data/data.txt”)
通过 sc.parallelize 进行创建val rdd1 = sc.parallelize(Array(1,2,3,4,5,6,7,8))
 RDD 的类型:Transformation 和 Action

3.4 RDD 的基本原理

在这里插入图片描述

四、算子

4.1 Transformation

RDD 中的所有转换都是延迟加载的,也就是说,它们并不会直接计算结果。相反的,它们只是记住这些应用到基础数据集(例如一个文件)上的转换动作。只有当发生一个要求返回结果给 Driver 的动作时,这些转换才会真正运行。这种设计让 Spark更加有效率地运行。
转换

含义

map(func)

返回一个新的 RDD,该 RDD 由每一个输入元素经过 func 函数转

换后组成

filter(func)

返回一个新的RDD,该RDD 由经过func 函数计算后返回值为true

的输入元素组成

flatMap(func)

类似于 map,但是每一个输入元素可以被映射为 0 或多个输出

元素(所以 func 应该返回一个序列,而不是单一元素)

mapPartitions(func)

类似于 map,但独立地在 RDD 的每一个分片上运行,因此在类

型为 T 的 RDD 上运行时,func 的函数类型必须是 Iterator[T] =>

Iterator[U]

mapPartitionsWithIndex(func)

类似于 mapPartitions,但 func 带有一个整数参数表示分片的索引值,因此在类型为 T 的 RDD 上运行时,func 的函数类型必须

是(Int, Interator[T]) => Iterator[U]

sample(withReplacement, fraction, seed)

根据fraction 指定的比例对数据进行采样,可以选择是否使用随

机数进行替换,seed 用于指定随机数生成器种子

union(otherDataset)

对源 RDD 和参数 RDD 求并集后返回一个新的 RDD

intersection(otherDataset)

对源 RDD 和参数 RDD 求交集后返回一个新的 RDD

distinct([numTasks]))

对源 RDD 进行去重后返回一个新的 RDD

groupByKey([numTasks])

在一个(K,V)的 RDD 上调用,返回一个(K, Iterator[V])的 RDD

reduceByKey(func, [numTasks])

在一个(K,V)的 RDD 上调用,返回一个(K,V)的 RDD,使用指定的reduce 函数,将相同 key 的值聚合到一起,与 groupByKey 类似,

reduce 任务的个数可以通过第二个可选的参数来设置

aggregateByKey(zeroValue)(seqOp,combOp,[numTasks])

sortByKey([ascending], [numTasks])

在一个(K,V)的 RDD 上调用,K 必须实现 Ordered 接口,返回一个

按照 key 进行排序的(K,V)的 RDD

sortBy(func,[ascending], [numTasks])

与 sortByKey 类似,但是更灵活

join(otherDataset, [numTasks])

在类型为(K,V)和(K,W)的 RDD 上调用,返回一个相同 key 对应的

所有元素对在一起的(K,(V,W))的 RDD

cogroup(otherDataset, [numTasks])

在 类 型 为 (K,V) 和 (K,W) 的 RDD 上 调 用 , 返 回 一 个

(K,(Iterable,Iterable))类型的 RDD

cartesian(otherDataset)

笛卡尔积

pipe(command, [envVars])

coalesce(numPartitions)

repartition(numPartitions)

repartitionAndSortWithinPartitions(partitioner)

Action算子

动作

含义

reduce(func)

通过 func 函数聚集 RDD 中的所有元素,这个功能必须是课交换且可并联的

collect()

在驱动程序中,以数组的形式返回数据集的所有元素

count()

返回 RDD 的元素个数

first()

返回 RDD 的第一个元素(类似于 take(1))

take(n)

返回一个由数据集的前 n 个元素组成的数组

takeSample(withReplacement,num, [seed])

返回一个数组,该数组由从数据集中随机采样的 num 个元素组成,可以选

择是否用随机数替换不足的部分,seed 用于指定随机数生成器种子

takeOrdered(n, [ordering])

saveAsTextFile(path)

将数据集的元素以 textfile 的形式保存到 HDFS 文件系统或者其他支持的文

件系统,对于每个元素,Spark 将会调用 toString 方法,将它装换为文件中

的文本

saveAsSequenceFile(path)

将数据集中的元素以 Hadoop sequencefile 的格式保存到指定的目录下,可

以使 HDFS 或者其他 Hadoop 支持的文件系统。

saveAsObjectFile(path)

countByKey()

针对(K,V)类型的 RDD,返回一个(K,Int)的 map,表示每一个 key 对应的元素

个数。

foreach(func)

在数据集的每一个元素上,运行函数 func 进行更新。

package com.ccj.pxj.core.zq

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}



object RDDCoreDemo {
  def main(args: Array[String]): Unit = {
    /*

     * //过滤出大于等于十的元素 val rdd3 = rdd2.filter(_ >= 10)

     */
    val conf = new SparkConf().setAppName("pxj").setMaster("local[4]")
    val sc = new SparkContext(conf)
    val data = sc.parallelize(List(1,5,8,9,10,20))
    data.map(_ * 2).sortBy(x=>x,true).filter(x=>x>10).collect().foreach(println)
    print("-----------------------------------------------")
    //将 rdd1 里面的每一个元素先切分在压平
    val buffer1: Array[Array[String]] = sc.parallelize(Array("a b c ", "d e f ", "r t y ")).map(_.split(" ")).collect()
    for(r<-buffer1){
      for(l<-r){
        println(l.toArray.toBuffer)
      }
    }
    sc.parallelize(Array("a b c ", "d e f ", "r t y ")).flatMap(_.split(" ")).collect().foreach(println)
 println("-------------------------------------------------------------------------------------------------------------")
   // val rdd1 = sc.parallelize(List(5, 6, 4, 3)) val rdd2 = sc.parallelize(List(1, 2, 3, 4)) //求并集 val rdd3 = rdd1.union(rdd2) //求交集 val rdd4 = rdd1.intersection(rdd2) //去重 rdd3.distinct.collect rdd4.collect
   val rdd1 = sc.parallelize(1 to 10)
    val rdd2 = sc.parallelize(2 to 15)
    rdd1.union(rdd2).collect().foreach(print)//并集
    println("\t")
    rdd1.intersection(rdd2).collect().foreach(println)
   println("------------------------------------------------------")
    val rdd3 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2)))
    val rdd4 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
    val rdd5: RDD[(String, (Int, Int))] = rdd3.join(rdd4)
    rdd5.foreach(println)
    val rdd6: RDD[(String, Int)] = rdd3.union(rdd4)
    rdd6.groupByKey().foreach(println)
    println("-----------------------------------")
    rdd6.foreach(println)
    println("-------------------------------------------------------")
    val rdd7 = sc.parallelize(List(("tom", 1), ("tom", 2), ("jerry", 3), ("kitty", 2)))
    val rdd8 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
    val cogroup: RDD[(String, (Iterable[Int], Iterable[Int]))] = rdd7.cogroup(rdd8)
    println("-------------")
    cogroup.foreach(println)
    println("reduce 聚合")
    val sum: Int = sc.parallelize(1 to 10).reduce(_ + _)
    println(sum)
    println("----------------------------------------------------------------------------")
    val rdd9 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2), ("shuke", 1)))
    val rdd10 = sc.parallelize(List(("jerry", 2), ("tom", 3), ("shuke", 2), ("kitty", 5)))
    val rdd11: RDD[(String, Int)] = rdd9.union(rdd10)
    rdd11.reduceByKey(_+_).sortByKey(false)
    rdd11.map(t=>(t._2,t._1)).sortByKey(false).map(x=>(x._2,x._1)).foreach(println)
    println("---------------------------------------------------------------------")



    sc.stop()


  }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值