Spark筆記

  • 2020 年 1 月 19 日
  • 筆記

Spark筆記

1.數據結構方式

RDD是Spark處理數據的數據結構,可以通過兩種方式載入數據創建RDD

  • 從程式中parallelize一種現有的數據:如Array
  • 從外部讀取文件:CSV,Hive等

2.RDD操作類型

2.1 RDD的計算方式是lazy載入,即用的時候再計算。

2.2 如果一個變數需要經常使用,可以持久化persist

2.3 封裝函數有多種方式:

  • 封裝靜態方法,創建object
  • 封裝方法以及變數參數等等,創建class

2.3 常用轉換方法

Transformation

Meaning

map(func)

Return a new distributed dataset formed by passing each element of the source through a function func.

filter(func)

Return a new dataset formed by selecting those elements of the source on which funcreturns true.

flatMap(func)

Similar to map, but each input item can be mapped to 0 or more output items (so func should return a Seq rather than a single item).

mapPartitions(func)

Similar to map, but runs separately on each partition (block) of the RDD, so func must be of type Iterator => Iterator when running on an RDD of type T.

mapPartitionsWithIndex(func)

Similar to mapPartitions, but also provides func with an integer value representing the index of the partition, so func must be of type (Int, Iterator) => Iterator when running on an RDD of type T.

sample(withReplacement, fraction, seed)

Sample a fraction fraction of the data, with or without replacement, using a given random number generator seed.

union(otherDataset)

Return a new dataset that contains the union of the elements in the source dataset and the argument.

intersection(otherDataset)

Return a new RDD that contains the intersection of elements in the source dataset and the argument.

distinct([numPartitions]))

Return a new dataset that contains the distinct elements of the source dataset.

groupByKey([numPartitions])

When called on a dataset of (K, V) pairs, returns a dataset of (K, Iterable) pairs. Note: If you are grouping in order to perform an aggregation (such as a sum or average) over each key, using reduceByKey or aggregateByKey will yield much better performance. Note: By default, the level of parallelism in the output depends on the number of partitions of the parent RDD. You can pass an optional numPartitions argument to set a different number of tasks.

reduceByKey(func, [numPartitions])

When called on a dataset of (K, V) pairs, returns a dataset of (K, V) pairs where the values for each key are aggregated using the given reduce function func, which must be of type (V,V) => V. Like in groupByKey, the number of reduce tasks is configurable through an optional second argument.

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

When called on a dataset of (K, V) pairs, returns a dataset of (K, U) pairs where the values for each key are aggregated using the given combine functions and a neutral 「zero」 value. Allows an aggregated value type that is different than the input value type, while avoiding unnecessary allocations. Like in groupByKey, the number of reduce tasks is configurable through an optional second argument.

sortByKey([ascending], [numPartitions])

When called on a dataset of (K, V) pairs where K implements Ordered, returns a dataset of (K, V) pairs sorted by keys in ascending or descending order, as specified in the boolean ascending argument.

join(otherDataset, [numPartitions])

When called on datasets of type (K, V) and (K, W), returns a dataset of (K, (V, W)) pairs with all pairs of elements for each key. Outer joins are supported through leftOuterJoin, rightOuterJoin, and fullOuterJoin.

cogroup(otherDataset, [numPartitions])

When called on datasets of type (K, V) and (K, W), returns a dataset of (K, (Iterable, Iterable)) tuples. This operation is also called groupWith.

cartesian(otherDataset)

When called on datasets of types T and U, returns a dataset of (T, U) pairs (all pairs of elements).

pipe(command, [envVars])

Pipe each partition of the RDD through a shell command, e.g. a Perl or bash script. RDD elements are written to the process』s stdin and lines output to its stdout are returned as an RDD of strings.

coalesce(numPartitions)

Decrease the number of partitions in the RDD to numPartitions. Useful for running operations more efficiently after filtering down a large dataset.

repartition(numPartitions)

Reshuffle the data in the RDD randomly to create either more or fewer partitions and balance it across them. This always shuffles all data over the network.

repartitionAndSortWithinPartitions(partitioner)

Repartition the RDD according to the given partitioner and, within each resulting partition, sort records by their keys. This is more efficient than calling repartition and then sorting within each partition because it can push the sorting down into the shuffle machinery.

3.創建DataFrame的三種方式

  • 使用toDF函數
  • 使用createDataFrame函數
  • 通過文件直接創建

4.scala的vector和spark包中vector不一樣

5.Spark優化:(美團Spark)

基礎版:https://tech.meituan.com/2016/04/29/spark-tuning-basic.html

高級版:https://tech.meituan.com/2016/05/12/spark-tuning-pro.html

6.Spark保留運行環境(用於查錯)

1

conf.spark.yarn.preserve.staging.files=true

7.寬依賴和窄依賴

  • 窄依賴:指父RDD的每個分區只被一個子RDD分區使用,子RDD分區通常只對應常數個父RDD分區。(map、filter、union操作)。
  • 寬依賴:指父RDD的每個分區都有可能被多個子RDD分區使用,子RDD分區通常對應父RDD所有分區。(groupByKey、partitionBy等操作)
  • 比較:寬依賴通常對應著shuffle操作,需要在運行的過程中將同一個RDD分區傳入到不同的RDD分區中,中間可能涉及多個節點之間數據的傳輸。

8.ORC格式和PARQUET格式文件對比

impala暫時不支援orc格式的表查詢

9.left anti join(某個欄位過濾用)

  • left semi join —> exists
  • left anti join —> not exists

10.Shuffle過程數據傾斜

和Hive中類似,數據的傾斜都發生在shuffle過程中,下面以hive的shuffle進行總結。發生傾斜的根本原因在於,shuffle之後,key的分布不均勻,使得大量的key集中在某個reduce節點,導致此節點過於「忙碌」,在其他節點都處理完之後,任務的結整需要等待此節點處理完,使得整個任務被此節點堵塞。 要解決此問題,主要可以分為兩大塊:

  • 一是盡量不shuffle;
  • 二是shuffle之後,在reduce節點上的key分布盡量均勻。

方案總結如下:


解決方案:MapJoin,添加隨機前綴,使用列桶表

  • mapjoin

123

-- mapjoin配置set hive.auto.convert.join = true;set hive.mapjoin.smalltable.filesize=25000000;

  • 手動分割成兩部分進行join

123456789101112

select t1.* from t1 join t2 on t1.key=t2.key拆成以下SQL:select t1.* from t1 join t2 on t1.key=t2.keywhere t1.key=Aunion all select t1.*from t1 join t2 on t1.key=t2.keywhere t1.key<>A

  • 當小表不是很小,不太方便用mapjoin,大表添加N中隨機前綴,小表膨脹N倍數據
  • 使用Skewed Table 或者 List Bucketing Table

Tags: