久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

手機(jī)站
千鋒教育

千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

千鋒教育

掃一掃進(jìn)入千鋒手機(jī)站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學(xué)習(xí)站小程序
隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > 大數(shù)據(jù)實(shí)時(shí)計(jì)算引擎Spark筆試題:Spark Catalyst查詢(xún)優(yōu)化器原理

大數(shù)據(jù)實(shí)時(shí)計(jì)算引擎Spark筆試題:Spark Catalyst查詢(xún)優(yōu)化器原理

來(lái)源:千鋒教育
發(fā)布人:小千
時(shí)間: 2021-01-27 09:21:00 1611710460

      小千今天分享的這篇spark筆試題是sparkSQL的優(yōu)化器catalyst,本質(zhì)上它就是一個(gè)SQL查詢(xún)的優(yōu)化器,大家了解了它之后基本就能了解其他的SQL處理引擎的優(yōu)化原理了。

      *SQL優(yōu)化器核心執(zhí)行策略主要分為兩個(gè)大的方向:基于規(guī)則優(yōu)化(RBO)以及基于代價(jià)優(yōu)化(CBO),基于規(guī)則優(yōu)化是一種經(jīng)驗(yàn)式、啟發(fā)式地優(yōu)化思路,更多地依靠前輩總結(jié)出來(lái)的優(yōu)化規(guī)則,簡(jiǎn)單易行且能夠覆蓋到大部分優(yōu)化邏輯,但是對(duì)于核心優(yōu)化算子Join卻顯得有點(diǎn)力不從心。舉個(gè)簡(jiǎn)單的例子,兩個(gè)表執(zhí)行Join到底應(yīng)該使用BroadcastHashJoin 還是SortMergeJoin?當(dāng)前SparkSQL的方式是通過(guò)手工設(shè)定參數(shù)來(lái)確定,如果一個(gè)表的數(shù)據(jù)量小于這個(gè)值就使用BroadcastHashJoin,但是這種方案顯得很不優(yōu)雅,很不靈活?;诖鷥r(jià)優(yōu)化就是為了解決這類(lèi)問(wèn)題,它會(huì)針對(duì)每個(gè)Join評(píng)估當(dāng)前兩張表使用每種Join策略的代價(jià),根據(jù)代價(jià)估算確定一種代價(jià)最小的方案。

      *我們這里主要說(shuō)明基于規(guī)則的優(yōu)化,略提一下CBO

1

      如上圖是一個(gè)SQL經(jīng)過(guò)優(yōu)化器的最終生成物理查詢(xún)計(jì)劃的留存,紅色部分是我們要重點(diǎn)說(shuō)明的內(nèi)容。大 家思考我們寫(xiě)的一個(gè)SQL最終如何在Spark引擎中轉(zhuǎn)換成具體的代碼執(zhí)行的。任何一個(gè)優(yōu)化器工作原理都大同小異:SQL語(yǔ)句首先通過(guò)Parser模塊被解析為語(yǔ)法樹(shù),此棵樹(shù)稱(chēng)為Unresolved Logical Plan; Unresolved Logical Plan通過(guò)Analyzer模塊借助于數(shù)據(jù)元數(shù)據(jù)解析為L(zhǎng)ogical Plan;此時(shí)再通過(guò)各種基于規(guī)則的優(yōu)化策略進(jìn)行深入優(yōu)化,得到Optimized Logical Plan;優(yōu)化后的邏輯執(zhí)行計(jì)劃依然是邏輯的,并不能被Spark系統(tǒng)理解,此時(shí)需要將此邏輯執(zhí)行計(jì)劃轉(zhuǎn)換為Physical Plan;為了更好的對(duì)整個(gè)過(guò)程進(jìn)行理解,下文通過(guò)一個(gè)簡(jiǎn)單示例進(jìn)行解釋。

      Parser

      Parser簡(jiǎn)單來(lái)說(shuō)是將SQL字符串切分成一個(gè)一個(gè)Token,再根據(jù)一定語(yǔ)義規(guī)則解析為一棵語(yǔ)法樹(shù)。Parser模塊目前基本都使用第三方類(lèi)庫(kù) ANTLR 進(jìn)行實(shí)現(xiàn),比如Hive、 Presto、SparkSQL等。下圖是一個(gè)示例性的SQL語(yǔ)句(有兩張表,其中people表主要存儲(chǔ)用戶(hù)基本信息,score表存儲(chǔ)用戶(hù) 的各種成績(jī)),通過(guò)Parser解析后的AST語(yǔ)法樹(shù)如下圖所示:

2

      Analyzer

      通過(guò)解析后的邏輯執(zhí)行計(jì)劃基本有了?架,但是系統(tǒng)并不知道score、sum這些都是些什么?,此 時(shí)需要基本的元數(shù)據(jù)信息來(lái)表達(dá)這些詞素,最重要的元數(shù)據(jù)信息主要包括兩部分:表的Scheme和 基本函數(shù)信息,表的scheme主要包括表的基本定義(列名、數(shù)據(jù)類(lèi)型)、表的數(shù)據(jù)格式(Json、Text)、表的物理位置等,基本函數(shù)信息主要指類(lèi)信息。

      Analyzer會(huì)再次遍歷整個(gè)語(yǔ)法樹(shù),對(duì)樹(shù)上的每個(gè)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)類(lèi)型綁定以及函數(shù)綁定,比如people 詞素會(huì)根據(jù)元數(shù)據(jù)表信息解析為包含age、id以及name三列的表,people.age會(huì)被解析為數(shù)據(jù)類(lèi)型 為int的變量,sum會(huì)被解析為特定的聚合函數(shù),如下圖所示:

3

      Optimizer

      優(yōu)化器是整個(gè)Catalyst的核心,上文提到優(yōu)化器分為基于規(guī)則優(yōu)化和基于代價(jià)優(yōu)化兩種,此處只介 紹基于規(guī)則的優(yōu)化策略,基于規(guī)則的優(yōu)化策略實(shí)際上就是對(duì)語(yǔ)法樹(shù)進(jìn)行一次遍歷,模式匹配能夠滿(mǎn) 足特定規(guī)則的節(jié)點(diǎn),再進(jìn)行相應(yīng)的等價(jià)轉(zhuǎn)換。因此,基于規(guī)則優(yōu)化說(shuō)到底就是一棵樹(shù)等價(jià)地轉(zhuǎn)換為 另一棵樹(shù)。SQL中經(jīng)典的優(yōu)化規(guī)則有很多,下文結(jié)合示例介紹三種比較常?的規(guī)則:謂詞下推(Predicate Pushdown)、常量累加(Constant Folding)和列值裁剪(Column Pruning)

      1.謂詞下推, 下圖左邊是經(jīng)過(guò)Analyzer解析后的語(yǔ)法樹(shù),語(yǔ)法樹(shù)中兩個(gè)表先做join,之后再使用age>10對(duì)結(jié)果進(jìn)行過(guò)濾。大家知道join算子通常是一個(gè)非常耗時(shí)的算子,耗時(shí)多少一般取決于參與join的兩個(gè)表的大小,如果能夠減少參與join兩表的大小,就可以大大降低join算子所需 時(shí)間。謂詞下推就是這樣一種功能,它會(huì)將過(guò)濾操作下推到j(luò)oin之前進(jìn)行,下圖中過(guò)濾條件age>0以及id!=null兩個(gè)條件就分別下推到了join之前。這樣,系統(tǒng)在掃描數(shù)據(jù)的時(shí)候就對(duì)數(shù)據(jù) 進(jìn)行了過(guò)濾,參與join的數(shù)據(jù)量將會(huì)得到顯著的減少,join耗時(shí)必然也會(huì)降低。

4

      2.常量累加,如下圖。 常量累加其實(shí)很簡(jiǎn)單,就是 x+(1+2) -> x+3 這樣的規(guī)則,雖然是一個(gè)很小的改動(dòng),但是意義巨大。示例如果沒(méi)有進(jìn)行優(yōu)化的話(huà),每一條結(jié)果都需要執(zhí)行一次100+80的操作,然后再與變量math_score以及english_score相加,而優(yōu)化后就不需要再執(zhí)行100+80操作。

5

      3.列值裁剪,如下圖。這是一個(gè)經(jīng)典的規(guī)則,示例中對(duì)于people表來(lái)說(shuō),并不需要掃描它的所有列值,而只需要列值id,所以在掃描people之后需要將其他列進(jìn)行裁剪,只留下列id。這個(gè) 優(yōu)化一方面大幅度減少了網(wǎng)絡(luò)、內(nèi)存數(shù)據(jù)量消耗,另一方面對(duì)于列存數(shù)據(jù)庫(kù)(Parquet)來(lái)說(shuō) 大大提高了掃描效率

6

      物理計(jì)劃

      經(jīng)過(guò)上述步驟,邏輯執(zhí)行計(jì)劃已經(jīng)得到了比較完善的優(yōu)化,然而,邏輯執(zhí)行計(jì)劃依然沒(méi)辦法真正執(zhí)行,他們只是邏輯上可行,實(shí)際上Spark并不知道如何去執(zhí)行這個(gè)東?。比如Join只是一個(gè)抽象概 念,代表兩個(gè)表根據(jù)相同的id進(jìn)行合并,然而具體怎么實(shí)現(xiàn)這個(gè)合并,邏輯執(zhí)行計(jì)劃并沒(méi)有說(shuō)明。

7

      此時(shí)就需要將邏輯執(zhí)行計(jì)劃轉(zhuǎn)換為物理執(zhí)行計(jì)劃,將邏輯上可行的執(zhí)行計(jì)劃變?yōu)镾park可以真正執(zhí) 行的計(jì)劃。比如Join算子,Spark根據(jù)不同場(chǎng)景為該算子制定了不同的算法策略,有BroadcastHashJoin、ShuffleHashJoin以及SortMergeJoin等(可以將Join理解為一個(gè)接口, BroadcastHashJoin是其中一個(gè)具體實(shí)現(xiàn)),物理執(zhí)行計(jì)劃實(shí)際上就是在這些具體實(shí)現(xiàn)中挑選一個(gè)耗時(shí)最小的算法實(shí)現(xiàn),這個(gè)過(guò)程涉及到基于代價(jià)優(yōu)化(CBO)策略,所謂基于代價(jià) , 是因?yàn)槲锢韴?zhí)行計(jì)劃的每一個(gè)節(jié)點(diǎn)都是有執(zhí)行代價(jià)的,這個(gè)代價(jià)主要分為兩部分

      第一部分:該執(zhí)行節(jié)點(diǎn)對(duì)數(shù)據(jù)集的影響,或者說(shuō)該節(jié)點(diǎn)輸出數(shù)據(jù)集的大小與分布(需要去采集)

      第二部分:該執(zhí)行節(jié)點(diǎn)操作算子的代價(jià)(相對(duì)固定,可用規(guī)則來(lái)描述)

      在SQL 執(zhí)行之前會(huì)根據(jù)代價(jià)估算確定一種代價(jià)最小的方案來(lái)執(zhí)行。我們這里以Join為例子做個(gè)簡(jiǎn)單說(shuō)明

      *在 Spark SQL 中 ,Join 可 分 為 Shuffle based Join 和 BroadcastJoin 。 Shuffle basedJoin 需要引入 Shuffle,代價(jià)相對(duì)較高。BroadcastJoin 無(wú)須 Join,但要求至少有一張表足夠小,能通過(guò) Spark 的 Broadcast 機(jī)制廣播到每個(gè) Executor 中。

      *在不開(kāi)啟 CBO 中,Spark SQL 通過(guò) spark.sql.autoBroadcastJoinThreshold 判斷是否啟用BroadcastJoin。其默認(rèn)值為 10485760 即 10 MB。并且該判斷基于參與 Join 的表的原始大小。

      *在下圖示例中,Table 1 大小為 1 TB,Table 2 大小為 20 GB,因此在對(duì)二者進(jìn)行 join 時(shí),由于二者都遠(yuǎn)大于自動(dòng) BroatcastJoin 的閾值,因此 Spark SQL 在未開(kāi)啟 CBO 時(shí)選用 SortMergeJoin 對(duì)二者進(jìn)行 Join。

      *而開(kāi)啟 CBO 后,由于 Table 1 經(jīng)過(guò) Filter 1 后結(jié)果集大小為 500 GB,Table 2 經(jīng)過(guò) Filter 2后結(jié)果集大小為 10 MB 低于自動(dòng) BroatcastJoin 閾值,因此 Spark SQL 選用 BroadcastJoin。

8

      學(xué)習(xí)大數(shù)據(jù)開(kāi)發(fā),可以參考千鋒大數(shù)據(jù)培訓(xùn)班提供的大數(shù)據(jù)學(xué)習(xí)路線(xiàn),千鋒大數(shù)據(jù)培訓(xùn)機(jī)構(gòu)的學(xué)習(xí)路線(xiàn)提供完整的大數(shù)據(jù)開(kāi)發(fā)知識(shí)體系,內(nèi)容包含Linux&&Hadoop生態(tài)體系、大數(shù)據(jù)計(jì)算框架體系、云計(jì)算體系、機(jī)器學(xué)習(xí)&&深度學(xué)習(xí)。根據(jù)千鋒大數(shù)據(jù)培訓(xùn)班提供的大數(shù)據(jù)學(xué)習(xí)路線(xiàn)圖可以讓你對(duì)學(xué)習(xí)大數(shù)據(jù)需要掌握的知識(shí)有個(gè)清晰的了解,并快速入門(mén)大數(shù)據(jù)開(kāi)發(fā)。想要獲取免費(fèi)的大數(shù)據(jù)學(xué)習(xí)資料可以添加我們的大數(shù)據(jù)技術(shù)交流qq群:857910996,加群找管理領(lǐng)取即可,有任何大數(shù)據(jù)相關(guān)問(wèn)題也可以加群解決,等你來(lái)哦~~

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
請(qǐng)您保持通訊暢通,專(zhuān)屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
免費(fèi)領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學(xué) 138****2860 剛剛成功領(lǐng)取
王同學(xué) 131****2015 剛剛成功領(lǐng)取
張同學(xué) 133****4652 剛剛成功領(lǐng)取
李同學(xué) 135****8607 剛剛成功領(lǐng)取
楊同學(xué) 132****5667 剛剛成功領(lǐng)取
岳同學(xué) 134****6652 剛剛成功領(lǐng)取
梁同學(xué) 157****2950 剛剛成功領(lǐng)取
劉同學(xué) 189****1015 剛剛成功領(lǐng)取
張同學(xué) 155****4678 剛剛成功領(lǐng)取
鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
董同學(xué) 138****2867 剛剛成功領(lǐng)取
周同學(xué) 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
為什么sql語(yǔ)句不支持關(guān)系代數(shù)中的除法?

為什么SQL語(yǔ)句不支持關(guān)系代數(shù)中的除法1. SQL和關(guān)系代數(shù)的關(guān)系:SQL是一種基于關(guān)系代數(shù)的查詢(xún)語(yǔ)言,它的設(shè)計(jì)初衷是為了能夠以一種更接近自然語(yǔ)言...詳情>>

2023-10-14 04:07:35
sql 怎么根據(jù)父id查詢(xún)下三級(jí)子集?

一、概述處理樹(shù)形數(shù)據(jù)時(shí),我們常常需要根據(jù)父ID查詢(xún)其下的子集。本文將引導(dǎo)您如何使用SQL進(jìn)行這一操作,尤其是查詢(xún)下三級(jí)子集。二、查詢(xún)方法詳...詳情>>

2023-10-14 03:59:07
什么是分治算法,和遞歸有什么關(guān)系?

分治算法是什么分治算法是一種算法設(shè)計(jì)思想,其主要思想是將一個(gè)復(fù)雜的問(wèn)題分解為兩個(gè)或更多相同或相似的子問(wèn)題,直到子問(wèn)題簡(jiǎn)單到可以直接解決...詳情>>

2023-10-14 03:22:51
為什么微服務(wù)一定要上Docker?

為什么微服務(wù)一定要上Docker微服務(wù)作為一種軟件架構(gòu)模式,需要考慮的因素包括服務(wù)的獨(dú)立性、可擴(kuò)展性、可維護(hù)性和可移植性等。這其中,Docker的...詳情>>

2023-10-14 03:15:33
C++的traits技術(shù)到底是什么?

在C++編程中,traits是一種編程技巧,其主要目的是在編譯時(shí)提供關(guān)于類(lèi)型的額外信息。它可以將類(lèi)型的一些特性(如其關(guān)聯(lián)類(lèi)型、屬性、函數(shù)等)抽...詳情>>

2023-10-14 03:00:03
快速通道