面試系列之《Spark》(持續更新...)

參考文檔及示例代碼均基于pyspark==3.1.2

  • 1.什么是RDD?
  • 2.job、stage、task如何劃分?
  • 3.什么是寬窄依賴?
  • 4.spark有哪幾種部署模式?
  • 5.spark中的算子分為哪些類型,舉例說明。
  • 6.cache、persist、checkpoint的區別,及各自的使用場景?
  • 7.廣播變量與累加器。
  • 8.reduceByKey與groupByKey的區別?
  • 9.spark數據傾斜及通用調優。
  • 10.map與flatMap區別?
  • 11.spark中的shuffle有哪幾種方式?

1.什么是RDD?

RDD,彈性分布式數據集(Resilient Distributed Datasets),即一個分布于多個節點機器上的數據集合。為開發人員提供編程抽象,具有只讀的特點。這里只讀的意思是,當對RDD中的數據修改時,并不修改原RDD,而是返回一個新的RDD。注意RDD本身并不保存數據,只是定義了一組計算規則。
RDD中的彈性體現在:
1)容錯性:包括基于血緣關系的容錯和自動失敗重試的容錯。

  • 血緣關系的容錯:RDD中一個分區的數據丟失,可以通過RDD間的血緣關系重新計算得到該分區的數據。單個節點的故障不影響其他節點的任務處理。
  • 自動失敗重試的容錯:包括task失敗重試和stage失敗重試,由spark自動支持。且stage失敗重試時只重試任務失敗的分區,而不是全部計算。

2)計算存儲方面:內存和磁盤空間的自動切換和管理。包括計算過程中RDD的存儲,及持久化時持久化級別的動態管理。

  • 計算過程中RDD的存儲:當內存使用完畢時自動溢寫磁盤,使得內存較小時也可以處理大數據量。
  • 持久化方面:開發者可以自定義選擇持久化級別,包括持久化內存,持久化磁盤,持久化內存磁盤相結合的方式。

3)計算過程中可動態調整分區(repartition、coalesce)。

2.job、stage、task如何劃分?

job:應用程序中每遇到一個action算子就會劃分為一個job。
stage:一個job任務中從后往前劃分,分區間每產生了shuffle也就是寬依賴則劃分為一個stage,stage的劃分體現了spark的pipeline思想,即數據在內存中盡可能的往后多計算,減少磁盤或者網絡IO。
task:RDD中一個分區對應一個task。

3.什么是寬窄依賴?

根據分區之間是否產生shuffle來確定。
寬依賴:上游一個分區的數據被打散到下游的多個分區,1:N
窄依賴:上游一個分區的數據全部進入到下游的一個分區,可以是1:1,也可以是N:1

4.spark有哪幾種部署模式?

1.Local:本地模式,運行在單個機器,一般用作測試環境。
2.Standalone:一個基于Master+Slaves的資源調度集群。spark任務提交給Master調度管理,是spark自帶的一個調度系統。
3.Yarn:spark客戶端直接連接yarn,不需要額外構建spark集群。有yarn-client和yarn-cluster兩種模式,主要區別在于:driver程序的運行節點。yarn-client時driver運行在本地提交任務的客戶端,yarn-cluster是driver運行在集群中隨機的任一節點。
4.Mesos:比較少用,不了解。
5.K8s:spark后續高版本新增支持。

5.spark中的算子分為哪些類型,舉例說明。

spark中算子類型分為兩類:
1)轉換算子(Transformation):惰性求值,需要action算子進行觸發才會執行。返回一個新的RDD。不負責數據存儲,只是定義了一個計算規則。

  • map:對RDD中的每個元素應用規則。
    filter:對RDD中的每個元素按規則過濾。
    groupByKey:將相同key的數據合并。
    glom:將RDD中的每個分區合并為一個列表。
    union:合并兩個RDD。
    simple:抽樣。
    注:關于持久化類算子,也有人叫控制算子(cache、persist、checkpoint),嚴格意義上也屬于轉換算子,需要動作算子才能觸發。

2)動作算子(Action):觸發spark任務執行,立即構建DAG有向無環圖,不返回RDD,返回RDD的結果或者沒有返回值。

  • collect:以數組形式獲取RDD中所有元素。
    count:獲取RDD中元素個數。
    first:獲取RDD中的第一個元素,等價于take(1)。
    take:通過指定參數n獲取RDD中前n個元素。
    top:通過指定參數n獲取RDD中排序后的前n個元素。

更多RDD相關API參考官方文檔:https://spark.apache.org/docs/3.1.2/api/python/reference/pyspark.html#rdd-apis

6.cache、persist、checkpoint的區別,及各自的使用場景?

共同點:1)都用來做持久化,避免多個action算子對同一個RDD的重復計算。2)都遵循spark的惰性執行策略,需要通過action算子觸發執行。
區別:

  • cache:僅持久化到內存,MEMORY_ONLY級別。等價于persist的默認持久化級別。
  • persist:默認持久化到內存(MEMORY_ONLY),但同時支持開發者自定義存儲級別,例如僅磁盤(DISK_ONLY),磁盤內存結合(MEMORY_AND_DISK)。
    更多的存儲級別設置及使用場景參考:https://spark.apache.org/docs/3.1.2/rdd-programming-guide.html#rdd-persistence
  • checkpoint:將數據持久化到節點指定路徑中(sc.setCheckpointDir方法設置),如果執行模式是cluster則檢查點路徑必須為HDFS路徑。該方法與上述兩種方法最大的不同點在于會截斷RDD的血緣關系,而上述兩種方法不會截斷血緣關系,只是起到了緩存數據避免重復計算的作用。checkpoint實際使用中有兩點需要注意:1)checkpoint之前不要觸發RDD的動作算子,否則會截斷血緣關系,導致checkpoint重新計算時找不到血緣鏈條從而保存不到數據。2)checkpoint前最好將需要保存的RDD通過cache或者persist緩存一下,避免RDD的重復計算。

7.廣播變量與累加器。

廣播變量和累加器是spark中提供的兩種共享變量,分別用來解決廣播通信和任務結果匯總的兩種業務場景問題。詳細參考官方文檔:https://spark.apache.org/docs/3.1.2/rdd-programming-guide.html#shared-variables

1)廣播變量

簡而言之,就是在每個集群節點中緩存一份driver端定義的公共變量,且該被廣播的變量在executor中只讀。
當不使用廣播變量的時候,spark任務中需要用到的公共變量會copy到每個task中,這種方式弊端一是重復存儲占用內存資源,二是增加了IO操作。而使用廣播變量,driver端定義的公共變量只會往每個集群中的worker節點中copy一份,由executor中的所有task共享。且該方法的底層實現涉及到了序列化與反序列化以及高效的廣播算法,所以效率比較高。

demo:

from pyspark.sql import SparkSession"""
需求:從rdd中過濾掉singer中歌手的歌曲
"""
spark = SparkSession.builder \.master("local[*]") \.appName("broadcast_demo") \.config("spark.executor.instances", "4") \.config("spark.executor.cores", "2") \.config("spark.executor.memory", "1g") \.getOrCreate()
sc = spark.sparkContextrdd = sc.parallelize([("梁靜茹", "向左轉向右轉"), ("梁靜茹", "親親"), ("王詩安", "Home"), ("李宗盛", "山丘"), ("邵夷貝", "未來俱樂部")], 2)
print(f"過濾前:{rdd.collect()}")singer = ["梁靜茹", "王詩安"]
# 設置廣播變量并將singer廣播到executor
bc = sc.broadcast(singer)# 根據廣播變量過濾并輸出過濾結果
rdd_filter = rdd.filter(lambda x: x[0] not in bc.value)
print(f"過濾后:{rdd_filter.collect()}")sc.stop()
spark.stop()

在這里插入圖片描述

2)累加器

累加器,簡要的概括,是一種分布式共享只寫變量。在driver端定義,并被序列化到每個executor中,在使用時被反序列化。所有executor中的task持有一個累加器的副本進行累加操作。并將結果回傳給driver進行匯總。spark原生支持數值型累加器,也支持開發人員自定義累計器類型。

demo:

from pyspark.sql import SparkSession"""
需求:統計rdd中屬于singer中歌手的歌曲數量
"""
spark = SparkSession.builder \.master("local[*]") \.appName("accumulator_demo") \.config("spark.executor.instances", "4") \.config("spark.executor.cores", "2") \.config("spark.executor.memory", "1g") \.getOrCreate()
sc = spark.sparkContextrdd = sc.parallelize([("梁靜茹", "向左轉向右轉"), ("梁靜茹", "親親"), ("王詩安", "Home"), ("李宗盛", "山丘"), ("邵夷貝", "未來俱樂部")], 2)
singer = ["梁靜茹", "王詩安"]# 初始化一個初值為0的累加器
acc = sc.accumulator(0)# 定義map函數,統計屬于singer的歌曲數量
def map_fun(x, s):if x[0] in s:acc.add(1)# 使用collect算子觸發執行map函數并輸出結果
rdd.map(lambda x: map_fun(x, singer)).collect()
print(f"屬于singer的歌曲數量:{acc.value}")sc.stop()
spark.stop()

在這里插入圖片描述

8.reduceByKey與groupByKey的區別?

https://blog.csdn.net/atwdy/article/details/133155108

9.spark數據傾斜及通用調優。

10.map與flatMap區別?

map:對RDD中的每個元素應用規則,并返回一個新的元素。也就是結果RDD的元素數量與原始RDD元素數量相等。
flatMap:對RDD中每個元素應用規則,并返回一個集合,集合中的元素可以為0個或多個。在此基礎之上,再對所有的集合進行flat平鋪操作,可以理解為將各個集合元素合并到一起。

demo:

from pyspark.sql import SparkSessionspark = SparkSession.builder \.master("local[*]") \.appName("demo") \.config("spark.executor.instances", "4") \.config("spark.executor.cores", "2") \.config("spark.executor.memory", "1g") \.getOrCreate()
sc = spark.sparkContextrdd = sc.parallelize([2, 3, 4], 2)
rdd1 = rdd.map(lambda x: range(1, x))
rdd2 = rdd.flatMap(lambda x: range(1, x))print(f"map: {rdd1.collect()}")
print(f"flatMap: {rdd2.collect()}")sc.stop()
spark.stop()

在這里插入圖片描述

11.spark中的shuffle有哪幾種方式?

兩種。早期的HashShuffle,和后期的SortShuffle。
HashShuffle(后續高版本已被SortShuffle取代):

  • 未優化:基于對下游分區個數hash取模實現,下游有多少個分區,上游每個task都會產生多少個小文件,帶來的問題是小文件過多,增大磁盤和網絡IO,拖慢執行效率。同時上游每個task維護了多個小文件緩沖區,增加內存壓力。理論上的小文件個數 = map task數量 x 下游分區數量。
  • 優化后:HashShuffle的優化其實就是針對上游task產生的小文件的合并優化。未優化前,每個task維護各自的緩沖區并生成和下游分區數量相等的小文件,優化后,每個executor中屬于同一個的core的task,會產生和下游分區數量相等的小文件并復用同一組小文件。所以理論上的小文件個數 = 上游core個數 x 下游分區數量。

SortShuffle:

  • 普通SortShuffle:上游的每個map task會不斷地往磁盤溢寫小文件(溢寫前會進行排序),每次溢寫產生一個小文件,最終將所有屬于同一個task溢寫的小文件merge為一個大文件,并且產生一個索引文件,下游的reduce task根據索引文件去讀取屬于自己分區的數據。即產生的小文件個數 = map task數量 x 2。
  • bypass機制:這種機制,可以理解為,在未優化的HashShuffle機制基礎上,對同一個task產生的小文件進行了一個合并的功能,產生一個大文件,同時生成一個索引文件。這種機制相比普通SortShuffle省略了排序的過程。產生的文件個數 = map task數量 x 2。觸發該機制的兩個閾值條件:1)reduce task數量 < spark.shuffle.sort.bypassMergeThreshold參數的值,默認為200。2)不是聚合類的shuffle算子。準確來說,不是map端預聚合的算子(eg:reduceByKey,因為為了聚合的高效,通常要求數據有序,而bypass機制并不對數據排序)。

12.spark為什么比MR快?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697741.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++模板為什么不能聲明和定義分離

首先我們要直到C程序運行需要進行的四個階段。 預處理->編譯->匯編->鏈接 編譯&#xff1a;對語法語義分析&#xff0c;分析無誤生成匯編&#xff0c;頭文件不參加編譯&#xff0c;多個源文件是分開單獨編譯的。 鏈接&#xff1a;將多個obj文件鏈接合成一個&#x…

ubuntu20.04安裝webots仿真

ubuntu20.04安裝webots仿真 1.首先: wget -qO- https://cyberbotics.com/Cyberbotics.asc | sudo apt-key add - sudo apt-add-repository deb https://cyberbotics.com/debian/ binary-amd64/ sudo apt-get update sudo apt-get install webots .bashrc中添加環境變量:…

Sora----打破虛實之間的最后一根枷鎖----這扇門的背后是人類文明的晟陽還是最后的余暉

目錄 一.Sora出道即巔峰 二.為何說Sora是該領域的巨頭 三.Sora無敵的背后究竟有怎樣先進的處理技術 1.Spacetime Latent Patches 潛變量時空碎片&#xff0c;建構視覺語言系統 2.擴散模型與Diffusion Transformer&#xff0c;組合成強大的信息提取器 3.DiT應用于潛變量時…

關于在分布式環境中RVN和使用場景的介紹4

簡介 在前面的文檔中&#xff0c;我們介紹了RVN的概念&#xff0c;通過RVN可以解決的某類問題和使用技巧&#xff0c;以及處理RVN的邏輯的具體實現。在本文中&#xff0c;我們將要介紹關于如何使用RVN解決另一種在分布式系統中常出現的問題。 問題 假設我們創建了一個servic…

C語言—自定義(構造)類型

2.20&#xff0c;17.56 1.只有當我們使用結構體類型定義變量/結構體數組,系統才會為結構體的成員分配內存空間,用于存儲對應類型的數據 2.strct 結構體 一起作為結構體類型標識符 嘿嘿暫時先這樣&#xff0c;我會回來改的1、定義一個表示公交線路的結構體&#xff0c;要…

pikachu靶場-CSRF

CSRF: 介紹&#xff1a; Cross-site request forgery簡稱為"CSRF”。 在CSF的攻擊場景中攻擊者會偽造一個請求&#xff08;這個請求一般是一個鏈接&#xff09; 然后欺騙目標用戶進行點擊&#xff0c;用戶一旦點擊了這個請求&#xff0c;整個攻擊也就完成了&#xff0…

VSCode-更改系統默認路徑

修改vscode中的默認擴展路徑&#xff1a;"%USERPROFILE%\.vscode" 打開目錄C:\用戶\電腦用戶名&#xff0c;將.vscode文件剪切至D:\VSCode文件夾下 用管理員身份打開cmd.exe命令界面輸入mklink /D "%USERPROFILE%\.vscode" "D:\VSCode\.vscode\"…

同一個包下 golang run時報undefined

問題描述 今天在運行一個項目&#xff0c;一個包下有兩個文件&#xff0c;分別是main.go和route&#xff0c;main函數在main.go文件中&#xff0c;main引用了route.go中的兩個函數&#xff0c;SetupRoutes和SetupAdminRoutes go build 編譯后&#xff0c;直接運行&#xff0c…

【C++私房菜】面向對象中的簡單繼承

文章目錄 一、 繼承基本概念二、派生類對象及派生類向基類的類型轉換三、繼承中的公有、私有和受保護的訪問控制規則四、派生類的作用域五、繼承中的靜態成員 一、 繼承基本概念 通過繼承&#xff08;inheritance&#xff09;聯系在一起的類構成一種層次關系。通常在層次關系的…

Leetcoder Day17| 二叉樹 part06

語言&#xff1a;Java/C 654.最大二叉樹 給定一個不含重復元素的整數數組。一個以此數組構建的最大二叉樹定義如下&#xff1a; 二叉樹的根是數組中的最大元素。左子樹是通過數組中最大值左邊部分構造出的最大二叉樹。右子樹是通過數組中最大值右邊部分構造出的最大二叉樹。 …

進程間傳遞 SQL 文的方法

SQL 文組成 SQL 文有 2 部分組成&#xff1a; SQL 原型&#xff0c;如&#xff1a;INSERT INTO test1 (id,name) VALUES (?,?)Args &#xff0c;? 號對應的值列表 有時&#xff0c;生成 SQL 文的進程和處理 SQL 文的進程&#xff0c;可能不是同一個 這里就涉及到如何高效…

免費搭建個人網盤

免費搭建一個屬于個人的網盤。 服務端 詳情請參考原網站的服務端下載和安裝虛擬磁盤Fuse4Ui可以支持把網盤內容掛載成系統的分區&#xff1b; 掛載工具效果圖&#xff1a;應用端應用端的下載 效果圖

藍橋杯第1374題——鍛造兵器

題目描述 小明一共有n塊鍛造石&#xff0c;第塊鍛造石的屬性值為ai. 現在小明決定從這n塊鍛造石中任取兩塊來鍛造兵器 通過周密計算&#xff0c;小明得出&#xff0c;只有當兩塊鍛造石的屬性值的差值等于C&#xff0c;兵器才能鍛造成功 請你幫小明算算&#xff0c;他有多少種選…

人工智能幾個關鍵節點:深藍,AlphaGo,ChatGPT,Sora

近30年&#xff0c;人工智能幾個關鍵節點&#xff1a;深藍&#xff0c;AlphaGo&#xff0c;ChatGPT&#xff0c;Sora 深藍&#xff1a; 1997年&#xff0c;深藍擊敗卡斯帕羅夫的比賽是通過一系列復雜的算法和策略實現的。深藍的開發團隊使用了一種名為“暴力搜索”的技術&…

OGG-00918 映射中缺少鍵列 id.

2024-02-23 14:54:49 INFO OGG-02756 從線索文件獲取了表 GISTAR.PXPH_PON_ROUTE 的定義。. The following columns did not default because of type mismatches: id OGG-00918 映射中缺少鍵列 id. 目標端有字段ID&#xff0c;由于mysql自增&#xff0c;所以只能是b…

短劇小程序系統,重塑視頻觀看體驗的科技革命

隨著科技的飛速發展&#xff0c;人們對于數字化內容的消費需求也在不斷增長。在這個大背景下&#xff0c;短劇小程序作為一種新型的視頻觀看方式&#xff0c;正逐漸受到大眾的青睞。本文將探討短劇小程序的發展背景、特點以及市場前景&#xff0c;分析其在重塑視頻觀看體驗方面…

如何使用Inno Setup制作Unity構建程序的Windows安裝程序

1. 準備 &#xff08;1&#xff09;準備好Unity構建的程序集合 必須包括&#xff1a; Data文件夾&#xff08;xxx_Data&#xff09; Mono文件夾&#xff08;MonoBleedingEdge&#xff09; 打包的應用程序文件&#xff08;xxx.exe&#xff09; Unity播放器dll文件&#xff…

SpringBoot+Docker:高效容器化的最佳實踐

首先為什么要使用 Docker&#xff1f; Docker 是一個強大的工具&#xff0c;它允許開發者將他們的應用程序打包到容器中&#xff0c;以便可以在任何平臺上輕松部署和運行。當涉及到對 Spring Boot 應用程序進行 Docker 化時&#xff0c;每個開發人員都應該遵循一些最佳實踐&am…

編程筆記 Golang基礎 017 數據類型:字符串類型

編程筆記 Golang基礎 017 數據類型&#xff1a;字符串類型 一、字符串類型小結 在Go語言中&#xff0c;字符串&#xff08;string&#xff09;是一種基本的數據類型&#xff0c;用于表示文本數據。它是一個不可變的字符序列&#xff0c;由UTF-8編碼的字節組成&#xff0c;支持U…

深入URP之Shader篇15: Shader關鍵字和變體

之前說了很多shader關鍵字的事情&#xff0c;本篇好好說一下關鍵字和變體。 關鍵字是干什么的 我們寫shader的時候&#xff0c;經常會遇到需要處理不同的情況&#xff0c;比如是否啟用霧&#xff0c;光源是平行光還是點光源&#xff0c;是否使用法線貼圖等等。如果為每一種情…