SPARK三大數據結構

Spark 三大數據結構

	Spark 有三大數據結構 RDD、廣播變量、累加器。
	rdd 是彈性分佈式數據集。
	廣播變量: 分佈式只讀共享變量。
	累加器: 分佈式只寫共享變量。

Spark 累加器

默認累加器

package com.ypl.bigdata.spark

import java.util

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

object Spark_Cacluate {
    def main(args: Array[String]): Unit = {

      val config: SparkConf = new SparkConf().setMaster("local[*]").setAppName("rdd_serialble")

      // 創建 SPARK 上下文對象
      val sc = new SparkContext(config)
      val dataRDD: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4), 2)
      var sum:Int = 0
      // 使用累加器來共享變量,來累加數據
      // 創建累加器對象
      val accumulator: LongAccumulator = sc.longAccumulator
    
      // 創建自定義累加器
      // 註冊累加器
      //dataRDD.foreach(i=> sum=sum+i)
      val result = dataRDD.foreach {
        case i => {
          accumulator.add(i)
        }
      }
      println("sum = " + accumulator.value)
      sc.stop()
    }
}

自定義累加器

package com.ypl.bigdata.spark

import java.util

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

object Spark_Cacluate {
    def main(args: Array[String]): Unit = {

      val config: SparkConf = new SparkConf().setMaster("local[*]").setAppName("rdd_serialble")

      // 創建 SPARK 上下文對象
      val sc = new SparkContext(config)

      val dataRDD: RDD[String] = sc.makeRDD(List("hadoop","hive","hbase","spark","ypl"), 2)

      var sum:Int = 0

      // 使用累加器來共享變量,來累加數據

      // 創建累加器對象

      val accumulator: WordAccumulator = new WordAccumulator
      //註冊累加器
      sc.register(accumulator)

      dataRDD.foreach {
        case words => {
          accumulator.add(words)
        }

      }
      println("sum = " + accumulator.value)


      sc.stop()
    }
}

//聲明累加器
//1.繼承 AccumulatorV2
//2.實現抽象方法
//3.聲明累加器
//4、註冊累加器
class WordAccumulator() extends org.apache.spark.util.AccumulatorV2[String, util.ArrayList[String]] {

  val list = new util.ArrayList[String]()

  // 當前累加器是否爲初始化狀態
  override def isZero: Boolean ={
    list.isEmpty
  }
  // 複製累加器
  override def copy(): AccumulatorV2[String, util.ArrayList[String]] = {
    new WordAccumulator()
  }

  //重置累加器
  override def reset(): Unit = {
      list.clear()
  }
  // 向累加器中增加數據
  override def add(v: String): Unit = {
    if (v.contains("h")){
      list.add(v)
    }
  }
  // 將另外的數據合併到一起了
  override def merge(other: AccumulatorV2[String, util.ArrayList[String]]): Unit = {
    list.addAll(other.value)
  }
  override def value: util.ArrayList[String] = list
}

spark 廣播變量

廣播變量(調優策略)
廣播變量用來高效分發較大的對象。向所有工作節點發送一個較大的只讀值,以供一個或多個Spark操作使用。比如,如果你的應用需要向所有節點發送一個較大的只讀查詢表,甚至是機器學習算法中的一個很大的特徵向量,廣播變量用起來都很順手。 在多個並行操作中使用同一個變量,但是 Spark會爲每個任務分別發送。

scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))

broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]] = Broadcast(35)

scala> broadcastVar.value

res33: Array[Int] = Array(1, 2, 3)

使用廣播變量的過程如下:

(1)通過對一個類型T的對象調用SparkContext.broadcast創建出一個Broadcast[T]對象,任何可序列化的類型都可以這麼實現。

(2)通過value屬性訪問該對象的值(在。

(3)變量只會被髮到各個節點一次,應作爲只讀值處理(修改這個值不會影響到別的節點)。

package com.ypl.bigdata.spark

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

object Spark_Broadcast {
    def main(args: Array[String]): Unit = {
      val config: SparkConf = new SparkConf().setMaster("local[*]").setAppName("rdd_serialble")
      // 創建 SPARK 上下文對象
      val sc = new SparkContext(config)
      val rdd = sc.makeRDD(List((1,"a"),(2,"b"),(3,"c")))
      val rdd2 = sc.makeRDD(List((1,1),(2,2),(3,3)))
//
//      val joinRDD = rdd.join(rdd2)
//      /*
//      *
//      * (2,(b,2))
//        (1,(a,1))
//        (3,(c,3))
//      *
//      * */
//      joinRDD.foreach(println)
//
      // 使用廣播變量可以減少數據的傳輸  避免shuffle 過程,笛卡爾積現象
     val list = List((1,1),(2,2),(3,3))
     val broadcast: Broadcast[List[(Int, Int)]] = sc.broadcast(list)
     val resultRDD: RDD[(Int, (String, Any))] = rdd.map {
        case (key, value) => {
          var v2: Any = null
          for (t <- broadcast.value) {
            if (key == t._1) {
              v2 = t._2
            }
          }
          (key, (value, v2))
        }
      }
      resultRDD.foreach(println)
      sc.stop()
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章