溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在Spark中使用RDD

發(fā)布時間:2021-01-28 09:47:41 來源:億速云 閱讀:193 作者:Leah 欄目:編程語言

如何在Spark中使用RDD?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

1. Spark中的RDD

  • Resilient Distributed Datasets(彈性分布式數(shù)據(jù)集)

  • Spark中的最基本的抽象

  • 有了RDD的存在我們就可以像操作本地集合一樣操作分布式的數(shù)據(jù)

  • 包含所有元素的分區(qū)的集合

  • RDD包含了很多的分區(qū)

  • 2. RDD中的彈性
     

  • RDD中的數(shù)據(jù)是可大可小的

  • RDD的數(shù)據(jù)默認(rèn)情況下存放在內(nèi)存中的,但是在內(nèi)存資源不足時,Spark會自動將RDD數(shù)據(jù)寫入磁盤

  • RDD有自動容錯功能,當(dāng)其中一個RDD中的分區(qū)的數(shù)據(jù)丟失,或者當(dāng)前節(jié)點(diǎn)故障時,rdd會根據(jù)依賴關(guān)系重新計(jì)算該分區(qū)的數(shù)據(jù)

3. RDD在Spark中的作用

迭代式計(jì)算

其主要實(shí)現(xiàn)思想就是RDD,把所有計(jì)算的數(shù)據(jù)保存在分布式的內(nèi)存中。迭代計(jì)算通常情況下都是對同一個數(shù)據(jù)集做反復(fù)的迭代計(jì)算,數(shù)據(jù)在內(nèi)存中將大大提升IO操作。這也是Spark涉及的核心:內(nèi)存計(jì)算

交互式計(jì)算

因?yàn)镾park是用scala語言實(shí)現(xiàn)的,Spark和scala能夠緊密的集成,所以Spark可以完美的運(yùn)用scala的解釋器,使得其中的scala可以向操作本地集合對象一樣輕松操作分布式數(shù)據(jù)集

4. Spark中的名詞解釋

  • ClusterManager :在Standalone模式中即為Master(主節(jié)點(diǎn)),控制整個集群,監(jiān)控Worker。在YARN模式中為資源管理器

  • Worker:從節(jié)點(diǎn),負(fù)責(zé)控制計(jì)算節(jié)點(diǎn),啟動Executor。在YARN模式中為NodeManager,負(fù)責(zé)計(jì)算節(jié)點(diǎn)的控制。

  • Driver 運(yùn)行Application的main()函數(shù)并創(chuàng)建SparkContext

  • Executor (CoarseGrainedExecutorBackend)在worker node上執(zhí)行任務(wù)的組件、用于啟動線程池運(yùn)行任務(wù)。每個Application擁有獨(dú)立的一組Executors

  • SparkContext :整個應(yīng)用的上下文,控制應(yīng)用的生命周期

  • RDD :Spark中的最基本的數(shù)據(jù)抽象

  • DAG Scheduler : 根據(jù)DAG(有向無環(huán)圖)切分stage,并且生成task,以taskset的形式返回

  • Task Schedual: 調(diào)度task,把task交給executor

  • Stage: 一個Spark作業(yè)一般包含一到多個Stage。

  • Task :一個Stage包含一到多個Task,通過多個Task實(shí)現(xiàn)并行運(yùn)行的功能

  • Transformations :轉(zhuǎn)換操作,Transformation是lazy的,不會馬上執(zhí)行,只有當(dāng)調(diào)用action時才會執(zhí)行

  • Actions : 動作

  • SparkEnv : 線程級別的上下文,存儲運(yùn)行時的重要組件的引用

5. 創(chuàng)建RDD的兩種方式

通過并行化集合創(chuàng)建RDD(用于測試)

val list = List("java c++ java","java java java c++")
val rdd = sc.parallelize(list)

通過加載hdfs中的數(shù)據(jù)創(chuàng)建RDD(生產(chǎn)環(huán)境)

val rdd = sc.textFile("hdfs://uplooking01:8020/sparktest/")

6. IDEA開發(fā)Spark

6.1 pom依賴

<?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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.uplooking.bigdata</groupId>
  <artifactId>2018-11-08-spark</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <scala.version>2.11.8</scala.version>
    <spark.version>2.2.0</spark.version>
    <hadoop.version>2.7.5</hadoop.version>
  </properties>

  <dependencies>
    <!-- 導(dǎo)入scala的依賴 -->
    <dependency>
      <groupId>org.scala-lang</groupId>
      <artifactId>scala-library</artifactId>
      <version>${scala.version}</version>
    </dependency>

    <!-- 導(dǎo)入spark的依賴 -->
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-core_2.11</artifactId>
      <version>${spark.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-sql_2.11</artifactId>
      <version>${spark.version}</version>
    </dependency>
    <!-- 指定hadoop-client API的版本 -->
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>${hadoop.version}</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <!--編譯Scala-->
      <plugin>
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
        <version>3.2.2</version>
        <executions>
          <execution>
            <id>scala-compile-first</id>
            <phase>process-resources</phase>
            <goals>
              <goal>add-source</goal>
              <goal>compile</goal>
            </goals>
          </execution>
          <execution>
            <id>scala-test-compile</id>
            <phase>process-test-resources</phase>
            <goals>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <!--編譯Java-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <executions>
          <execution>
            <phase>compile</phase>
            <goals>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <!-- 打jar插件 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.4.3</version>
        <configuration>
          <createDependencyReducedPom>false</createDependencyReducedPom>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <filters>
                <filter>
                  <artifact>*:*</artifact>
                  <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                  </excludes>
                </filter>
              </filters>
            </configuration>
          </execution>
        </executions>
      </plugin>

    </plugins>
  </build>
</project>

6.2 編寫spark程序

val conf = new SparkConf()
conf.setAppName("Ops1")
val sc = new SparkContext(conf)
val rdd1: RDD[String] = sc.parallelize(List("java c+ java", "java java c++"))
val ret = rdd1.collect().toBuffer
println(ret)

6.3 打包

6.4 在Driver上運(yùn)行jar包

spark-submit --master spark://uplooking01:7077 --class com.uplooking.bigdata.spark01.Ops1 original-spark-1.0-SNAPSHOT.jar

7. 本地運(yùn)行Spark程序

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

import scala.collection.mutable

object Ops1 {
 def main(args: Array[String]): Unit = {
  val conf = new SparkConf()
  conf.setAppName("Ops1")
  conf.setMaster("local[4]")
  val sc = new SparkContext(conf)
  //一般不會指定最小分區(qū)數(shù)
  val rdd1 = sc.textFile("hdfs://uplooking01:8020/sparktest/")
  val rdd2: RDD[String] = rdd1.flatMap(line => line.split(" "))
  val rdd3: RDD[(String, Int)] = rdd2.map(word => (word, 1))
  val rdd4: RDD[(String, Int)] = rdd3.reduceByKey(_ + _)
  val ret: mutable.Buffer[(String, Int)] = rdd4.collect().toBuffer
  println(ret)
  println(rdd1.partitions.length)
 }
}

8. RDD中的分區(qū)數(shù)

并行化的方式指定分區(qū)數(shù)(一般會指定分區(qū)數(shù))

  • 默認(rèn)如果創(chuàng)建RDD時不指定分區(qū)數(shù),那么就會創(chuàng)建cpu核數(shù)個分區(qū)

  • 手動指定分區(qū)數(shù)

val rdd = sc.parallelize(List("java c+ java", "java java c++"), 2)

textFile的方式指定分區(qū)數(shù)

  • 默認(rèn)如果創(chuàng)建RDD時不指定最小分區(qū)數(shù),那么就會創(chuàng)建至少2個分區(qū)的RDD

  • 一般不會指定最小分區(qū)數(shù)

  • 不指定最小分區(qū)數(shù),有切片的數(shù)量個分區(qū)

9. Spark作業(yè)的運(yùn)行流程

  • 構(gòu)建DAG

  • 根據(jù)DAG切分Stage,每個Stage對應(yīng)一組相同計(jì)算邏輯不能計(jì)算數(shù)據(jù)的Task,以TastSet的形式返回

  • TaskSchedual調(diào)度task,把task發(fā)送到executor中去,用Runnable進(jìn)行包裝進(jìn)給線程池

  • Executor執(zhí)行task

關(guān)于如何在Spark中使用RDD問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI