国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

萬字詳解 Spark開發(fā)調(diào)優(yōu)(建議收藏)

共 13318字,需瀏覽 27分鐘

 ·

2021-09-12 15:14

1一、前言

在大數(shù)據(jù)計算領(lǐng)域,Spark 已經(jīng)成為了越來越流行、越來越受歡迎的計算平臺之一。Spark 的功能涵蓋了大數(shù)據(jù)領(lǐng)域的離線批處理、SQL類處理、流式/實時計算、機器學(xué)習(xí)、圖計算等各種不同類型的計算操作,應(yīng)用范圍與前景非常廣泛。大多數(shù)同學(xué)(包括筆者在內(nèi)),最初開始嘗試使用Spark的原因很簡單,主要就是為了讓大數(shù)據(jù)計算作業(yè)的執(zhí)行速度更快、性能更高。

然而,通過Spark開發(fā)出高性能的大數(shù)據(jù)計算作業(yè),并不是那么簡單的。如果沒有對Spark作業(yè)進(jìn)行合理的調(diào)優(yōu),Spark作業(yè)的執(zhí)行速度可能會很慢,這樣就完全體現(xiàn)不出Spark作為一種快速大數(shù)據(jù)計算引擎的優(yōu)勢來。因此,想要用好Spark,就必須對其進(jìn)行合理的性能優(yōu)化。

Spark的性能調(diào)優(yōu)實際上是由很多部分組成的,不是調(diào)節(jié)幾個參數(shù)就可以立竿見影提升作業(yè)性能的。我們需要根據(jù)不同的業(yè)務(wù)場景以及數(shù)據(jù)情況,對Spark作業(yè)進(jìn)行綜合性的分析,然后進(jìn)行多個方面的調(diào)節(jié)和優(yōu)化,才能獲得最佳性能。

本文作為Spark性能優(yōu)化指南的基礎(chǔ),主要講解開發(fā)調(diào)優(yōu)以及資源調(diào)優(yōu)。

2二、開發(fā)調(diào)優(yōu)

3三、調(diào)優(yōu)概述

Spark性能優(yōu)化的第一步,就是要在開發(fā)Spark作業(yè)的過程中注意和應(yīng)用一些性能優(yōu)化的基本原則。開發(fā)調(diào)優(yōu),就是要讓大家了解以下一些Spark基本開發(fā)原則,包括:RDD lineage設(shè)計、算子的合理使用、特殊操作的優(yōu)化等。在開發(fā)過程中,時時刻刻都應(yīng)該注意以上原則,并將這些原則根據(jù)具體的業(yè)務(wù)以及實際的應(yīng)用場景,靈活地運用到自己的Spark作業(yè)中。

4原則一:避免創(chuàng)建重復(fù)的RDD

通常來說,我們在開發(fā)一個Spark作業(yè)時,首先是基于某個數(shù)據(jù)源(比如Hive表或HDFS文件)創(chuàng)建一個初始的RDD;接著對這個RDD執(zhí)行某個算子操作,然后得到下一個RDD;以此類推,循環(huán)往復(fù),直到計算出最終我們需要的結(jié)果。在這個過程中,多個RDD會通過不同的算子操作(比如map、reduce等)串起來,這個“RDD串”,就是RDD lineage,也就是“RDD的血緣關(guān)系鏈”。

我們在開發(fā)過程中要注意:對于同一份數(shù)據(jù),只應(yīng)該創(chuàng)建一個RDD,不能創(chuàng)建多個RDD來代表同一份數(shù)據(jù)。

一些Spark初學(xué)者在剛開始開發(fā)Spark作業(yè)時,或者是有經(jīng)驗的工程師在開發(fā)RDD lineage極其冗長的Spark作業(yè)時,可能會忘了自己之前對于某一份數(shù)據(jù)已經(jīng)創(chuàng)建過一個RDD了,從而導(dǎo)致對于同一份數(shù)據(jù),創(chuàng)建了多個RDD。這就意味著,我們的Spark作業(yè)會進(jìn)行多次重復(fù)計算來創(chuàng)建多個代表相同數(shù)據(jù)的RDD,進(jìn)而增加了作業(yè)的性能開銷。

一個簡單的例子

// 需要對名為“hello.txt”的HDFS文件進(jìn)行一次map操作,再進(jìn)行一次reduce操作。也就是說,需要對一份數(shù)據(jù)執(zhí)行兩次算子操作。

// 錯誤的做法:對于同一份數(shù)據(jù)執(zhí)行多次算子操作時,創(chuàng)建多個RDD。
// 這里執(zhí)行了兩次textFile方法,針對同一個HDFS文件,創(chuàng)建了兩個RDD出來,然后分別對每個RDD都執(zhí)行了一個算子操作。
// 這種情況下,Spark需要從HDFS上兩次加載hello.txt文件的內(nèi)容,并創(chuàng)建兩個單獨的RDD;第二次加載HDFS文件以及創(chuàng)建RDD的性能開銷,很明顯是白白浪費掉的。
val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt")
rdd1.map(...)
val rdd2 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt")
rdd2.reduce(...)

// 正確的用法:對于一份數(shù)據(jù)執(zhí)行多次算子操作時,只使用一個RDD。
// 這種寫法很明顯比上一種寫法要好多了,因為我們對于同一份數(shù)據(jù)只創(chuàng)建了一個RDD,然后對這一個RDD執(zhí)行了多次算子操作。
// 但是要注意到這里為止優(yōu)化還沒有結(jié)束,由于rdd1被執(zhí)行了兩次算子操作,第二次執(zhí)行reduce操作的時候,還會再次從源頭處重新計算一次rdd1的數(shù)據(jù),因此還是會有重復(fù)計算的性能開銷。
// 要徹底解決這個問題,必須結(jié)合“原則三:對多次使用的RDD進(jìn)行持久化”,才能保證一個RDD被多次使用時只被計算一次。
val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt")
rdd1.map(...)
rdd1.reduce(...)

5原則二:盡可能復(fù)用同一個RDD

除了要避免在開發(fā)過程中對一份完全相同的數(shù)據(jù)創(chuàng)建多個RDD之外,在對不同的數(shù)據(jù)執(zhí)行算子操作時還要盡可能地復(fù)用一個RDD。比如說,有一個RDD的數(shù)據(jù)格式是key-value類型的,另一個是單value類型的,這兩個RDD的value數(shù)據(jù)是完全一樣的。那么此時我們可以只使用key-value類型的那個RDD,因為其中已經(jīng)包含了另一個的數(shù)據(jù)。對于類似這種多個RDD的數(shù)據(jù)有重疊或者包含的情況,我們應(yīng)該盡量復(fù)用一個RDD,這樣可以盡可能地減少RDD的數(shù)量,從而盡可能減少算子執(zhí)行的次數(shù)。

一個簡單的例子

// 錯誤的做法。

// 有一個<Long, String>格式的RDD,即rdd1。
// 接著由于業(yè)務(wù)需要,對rdd1執(zhí)行了一個map操作,創(chuàng)建了一個rdd2,而rdd2中的數(shù)據(jù)僅僅是rdd1中的value值而已,也就是說,rdd2是rdd1的子集。
JavaPairRDD<Long, String> rdd1 = ...
JavaRDD<String> rdd2 = rdd1.map(...)

// 分別對rdd1和rdd2執(zhí)行了不同的算子操作。
rdd1.reduceByKey(...)
rdd2.map(...)

// 正確的做法。

// 上面這個case中,其實rdd1和rdd2的區(qū)別無非就是數(shù)據(jù)格式不同而已,rdd2的數(shù)據(jù)完全就是rdd1的子集而已,卻創(chuàng)建了兩個rdd,并對兩個rdd都執(zhí)行了一次算子操作。
// 此時會因為對rdd1執(zhí)行map算子來創(chuàng)建rdd2,而多執(zhí)行一次算子操作,進(jìn)而增加性能開銷。

// 其實在這種情況下完全可以復(fù)用同一個RDD。
// 我們可以使用rdd1,既做reduceByKey操作,也做map操作。
// 在進(jìn)行第二個map操作時,只使用每個數(shù)據(jù)的tuple._2,也就是rdd1中的value值,即可。
JavaPairRDD<Long, String> rdd1 = ...
rdd1.reduceByKey(...)
rdd1.map(tuple._2...)

// 第二種方式相較于第一種方式而言,很明顯減少了一次rdd2的計算開銷。
// 但是到這里為止,優(yōu)化還沒有結(jié)束,對rdd1我們還是執(zhí)行了兩次算子操作,rdd1實際上還是會被計算兩次。
// 因此還需要配合“原則三:對多次使用的RDD進(jìn)行持久化”進(jìn)行使用,才能保證一個RDD被多次使用時只被計算一次。

6原則三:對多次使用的RDD進(jìn)行持久化

當(dāng)你在Spark代碼中多次對一個RDD做了算子操作后,恭喜,你已經(jīng)實現(xiàn)Spark作業(yè)第一步的優(yōu)化了,也就是盡可能復(fù)用RDD。此時就該在這個基礎(chǔ)之上,進(jìn)行第二步優(yōu)化了,也就是要保證對一個RDD執(zhí)行多次算子操作時,這個RDD本身僅僅被計算一次。

Spark中對于一個RDD執(zhí)行多次算子的默認(rèn)原理是這樣的:每次你對一個RDD執(zhí)行一個算子操作時,都會重新從源頭處計算一遍,計算出那個RDD來,然后再對這個RDD執(zhí)行你的算子操作。這種方式的性能是很差的。

因此對于這種情況,我們的建議是:對多次使用的RDD進(jìn)行持久化。此時Spark就會根據(jù)你的持久化策略,將RDD中的數(shù)據(jù)保存到內(nèi)存或者磁盤中。以后每次對這個RDD進(jìn)行算子操作時,都會直接從內(nèi)存或磁盤中提取持久化的RDD數(shù)據(jù),然后執(zhí)行算子,而不會從源頭處重新計算一遍這個RDD,再執(zhí)行算子操作。

對多次使用的RDD進(jìn)行持久化的代碼示例

// 如果要對一個RDD進(jìn)行持久化,只要對這個RDD調(diào)用cache()和persist()即可。

// 正確的做法。
// cache()方法表示:使用非序列化的方式將RDD中的數(shù)據(jù)全部嘗試持久化到內(nèi)存中。
// 此時再對rdd1執(zhí)行兩次算子操作時,只有在第一次執(zhí)行map算子時,才會將這個rdd1從源頭處計算一次。
// 第二次執(zhí)行reduce算子時,就會直接從內(nèi)存中提取數(shù)據(jù)進(jìn)行計算,不會重復(fù)計算一個rdd。
val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt").cache()
rdd1.map(...)
rdd1.reduce(...)

// persist()方法表示:手動選擇持久化級別,并使用指定的方式進(jìn)行持久化。
// 比如說,StorageLevel.MEMORY_AND_DISK_SER表示,內(nèi)存充足時優(yōu)先持久化到內(nèi)存中,內(nèi)存不充足時持久化到磁盤文件中。
// 而且其中的_SER后綴表示,使用序列化的方式來保存RDD數(shù)據(jù),此時RDD中的每個partition都會序列化成一個大的字節(jié)數(shù)組,然后再持久化到內(nèi)存或磁盤中。
// 序列化的方式可以減少持久化的數(shù)據(jù)對內(nèi)存/磁盤的占用量,進(jìn)而避免內(nèi)存被持久化數(shù)據(jù)占用過多,從而發(fā)生頻繁GC。
val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt").persist(StorageLevel.MEMORY_AND_DISK_SER)
rdd1.map(...)
rdd1.reduce(...)

對于persist()方法而言,我們可以根據(jù)不同的業(yè)務(wù)場景選擇不同的持久化級別。

Spark的持久化級別

持久化級別含義解釋
MEMORY_ONLY使用未序列化的Java對象格式,將數(shù)據(jù)保存在內(nèi)存中。如果內(nèi)存不夠存放所有的數(shù)據(jù),則數(shù)據(jù)可能就不會進(jìn)行持久化。那么下次對這個RDD執(zhí)行算子操作時,那些沒有被持久化的數(shù)據(jù),需要從源頭處重新計算一遍。這是默認(rèn)的持久化策略,使用cache()方法時,實際就是使用的這種持久化策略。
MEMORY_AND_DISK使用未序列化的Java對象格式,優(yōu)先嘗試將數(shù)據(jù)保存在內(nèi)存中。如果內(nèi)存不夠存放所有的數(shù)據(jù),會將數(shù)據(jù)寫入磁盤文件中,下次對這個RDD執(zhí)行算子時,持久化在磁盤文件中的數(shù)據(jù)會被讀取出來使用。
MEMORY_ONLY_SER基本含義同MEMORY_ONLY。唯一的區(qū)別是,會將RDD中的數(shù)據(jù)進(jìn)行序列化,RDD的每個partition會被序列化成一個字節(jié)數(shù)組。這種方式更加節(jié)省內(nèi)存,從而可以避免持久化的數(shù)據(jù)占用過多內(nèi)存導(dǎo)致頻繁GC。
MEMORY_AND_DISK_SER基本含義同MEMORY_AND_DISK。唯一的區(qū)別是,會將RDD中的數(shù)據(jù)進(jìn)行序列化,RDD的每個partition會被序列化成一個字節(jié)數(shù)組。這種方式更加節(jié)省內(nèi)存,從而可以避免持久化的數(shù)據(jù)占用過多內(nèi)存導(dǎo)致頻繁GC。
DISK_ONLY使用未序列化的Java對象格式,將數(shù)據(jù)全部寫入磁盤文件中。
MEMORY_ONLY_2, MEMORY_AND_DISK_2, 等等.對于上述任意一種持久化策略,如果加上后綴_2,代表的是將每個持久化的數(shù)據(jù),都復(fù)制一份副本,并將副本保存到其他節(jié)點上。這種基于副本的持久化機制主要用于進(jìn)行容錯。假如某個節(jié)點掛掉,節(jié)點的內(nèi)存或磁盤中的持久化數(shù)據(jù)丟失了,那么后續(xù)對RDD計算時還可以使用該數(shù)據(jù)在其他節(jié)點上的副本。如果沒有副本的話,就只能將這些數(shù)據(jù)從源頭處重新計算一遍了。

如何選擇一種最合適的持久化策略

  • 默認(rèn)情況下,性能最高的當(dāng)然是MEMORY_ONLY,但前提是你的內(nèi)存必須足夠足夠大,可以綽綽有余地存放下整個RDD的所有數(shù)據(jù)。因為不進(jìn)行序列化與反序列化操作,就避免了這部分的性能開銷;對這個RDD的后續(xù)算子操作,都是基于純內(nèi)存中的數(shù)據(jù)的操作,不需要從磁盤文件中讀取數(shù)據(jù),性能也很高;而且不需要復(fù)制一份數(shù)據(jù)副本,并遠(yuǎn)程傳送到其他節(jié)點上。但是這里必須要注意的是,在實際的生產(chǎn)環(huán)境中,恐怕能夠直接用這種策略的場景還是有限的,如果RDD中數(shù)據(jù)比較多時(比如幾十億),直接用這種持久化級別,會導(dǎo)致JVM的OOM內(nèi)存溢出異常。

  • 如果使用MEMORY_ONLY級別時發(fā)生了內(nèi)存溢出,那么建議嘗試使用MEMORY_ONLY_SER級別。該級別會將RDD數(shù)據(jù)序列化后再保存在內(nèi)存中,此時每個partition僅僅是一個字節(jié)數(shù)組而已,大大減少了對象數(shù)量,并降低了內(nèi)存占用。這種級別比MEMORY_ONLY多出來的性能開銷,主要就是序列化與反序列化的開銷。但是后續(xù)算子可以基于純內(nèi)存進(jìn)行操作,因此性能總體還是比較高的。此外,可能發(fā)生的問題同上,如果RDD中的數(shù)據(jù)量過多的話,還是可能會導(dǎo)致OOM內(nèi)存溢出的異常。

  • 如果純內(nèi)存的級別都無法使用,那么建議使用MEMORY_AND_DISK_SER策略,而不是MEMORY_AND_DISK策略。因為既然到了這一步,就說明RDD的數(shù)據(jù)量很大,內(nèi)存無法完全放下。序列化后的數(shù)據(jù)比較少,可以節(jié)省內(nèi)存和磁盤的空間開銷。同時該策略會優(yōu)先盡量嘗試將數(shù)據(jù)緩存在內(nèi)存中,內(nèi)存緩存不下才會寫入磁盤。

  • 通常不建議使用DISK_ONLY和后綴為_2的級別:因為完全基于磁盤文件進(jìn)行數(shù)據(jù)的讀寫,會導(dǎo)致性能急劇降低,有時還不如重新計算一次所有RDD。后綴為_2的級別,必須將所有數(shù)據(jù)都復(fù)制一份副本,并發(fā)送到其他節(jié)點上,數(shù)據(jù)復(fù)制以及網(wǎng)絡(luò)傳輸會導(dǎo)致較大的性能開銷,除非是要求作業(yè)的高可用性,否則不建議使用。

7原則四:盡量避免使用shuffle類算子

如果有可能的話,要盡量避免使用shuffle類算子。因為Spark作業(yè)運行過程中,最消耗性能的地方就是shuffle過程。shuffle過程,簡單來說,就是將分布在集群中多個節(jié)點上的同一個key,拉取到同一個節(jié)點上,進(jìn)行聚合或join等操作。比如reduceByKey、join等算子,都會觸發(fā)shuffle操作。

shuffle過程中,各個節(jié)點上的相同key都會先寫入本地磁盤文件中,然后其他節(jié)點需要通過網(wǎng)絡(luò)傳輸拉取各個節(jié)點上的磁盤文件中的相同key。而且相同key都拉取到同一個節(jié)點進(jìn)行聚合操作時,還有可能會因為一個節(jié)點上處理的key過多,導(dǎo)致內(nèi)存不夠存放,進(jìn)而溢寫到磁盤文件中。因此在shuffle過程中,可能會發(fā)生大量的磁盤文件讀寫的IO操作,以及數(shù)據(jù)的網(wǎng)絡(luò)傳輸操作。磁盤IO和網(wǎng)絡(luò)數(shù)據(jù)傳輸也是shuffle性能較差的主要原因。

因此在我們的開發(fā)過程中,能避免則盡可能避免使用reduceByKey、join、distinct、repartition等會進(jìn)行shuffle的算子,盡量使用map類的非shuffle算子。這樣的話,沒有shuffle操作或者僅有較少shuffle操作的Spark作業(yè),可以大大減少性能開銷。

Broadcast與map進(jìn)行join代碼示例

// 傳統(tǒng)的join操作會導(dǎo)致shuffle操作。
// 因為兩個RDD中,相同的key都需要通過網(wǎng)絡(luò)拉取到一個節(jié)點上,由一個task進(jìn)行join操作。
val rdd3 = rdd1.join(rdd2)

// Broadcast+map的join操作,不會導(dǎo)致shuffle操作。
// 使用Broadcast將一個數(shù)據(jù)量較小的RDD作為廣播變量。
val rdd2Data = rdd2.collect()
val rdd2DataBroadcast = sc.broadcast(rdd2Data)

// 在rdd1.map算子中,可以從rdd2DataBroadcast中,獲取rdd2的所有數(shù)據(jù)。
// 然后進(jìn)行遍歷,如果發(fā)現(xiàn)rdd2中某條數(shù)據(jù)的key與rdd1的當(dāng)前數(shù)據(jù)的key是相同的,那么就判定可以進(jìn)行join。
// 此時就可以根據(jù)自己需要的方式,將rdd1當(dāng)前數(shù)據(jù)與rdd2中可以連接的數(shù)據(jù),拼接在一起(String或Tuple)。
val rdd3 = rdd1.map(rdd2DataBroadcast...)

// 注意,以上操作,建議僅僅在rdd2的數(shù)據(jù)量比較少(比如幾百M,或者一兩G)的情況下使用。
// 因為每個Executor的內(nèi)存中,都會駐留一份rdd2的全量數(shù)據(jù)。

8原則五:使用map-side預(yù)聚合的shuffle操作

如果因為業(yè)務(wù)需要,一定要使用shuffle操作,無法用map類的算子來替代,那么盡量使用可以map-side預(yù)聚合的算子。

所謂的map-side預(yù)聚合,說的是在每個節(jié)點本地對相同的key進(jìn)行一次聚合操作,類似于MapReduce中的本地combiner。map-side預(yù)聚合之后,每個節(jié)點本地就只會有一條相同的key,因為多條相同的key都被聚合起來了。其他節(jié)點在拉取所有節(jié)點上的相同key時,就會大大減少需要拉取的數(shù)據(jù)數(shù)量,從而也就減少了磁盤IO以及網(wǎng)絡(luò)傳輸開銷。通常來說,在可能的情況下,建議使用reduceByKey或者aggregateByKey算子來替代掉groupByKey算子。因為reduceByKey和aggregateByKey算子都會使用用戶自定義的函數(shù)對每個節(jié)點本地的相同key進(jìn)行預(yù)聚合。而groupByKey算子是不會進(jìn)行預(yù)聚合的,全量的數(shù)據(jù)會在集群的各個節(jié)點之間分發(fā)和傳輸,性能相對來說比較差。

比如如下兩幅圖,就是典型的例子,分別基于reduceByKey和groupByKey進(jìn)行單詞計數(shù)。其中第一張圖是groupByKey的原理圖,可以看到,沒有進(jìn)行任何本地聚合時,所有數(shù)據(jù)都會在集群節(jié)點之間傳輸;第二張圖是reduceByKey的原理圖,可以看到,每個節(jié)點本地的相同key數(shù)據(jù),都進(jìn)行了預(yù)聚合,然后才傳輸?shù)狡渌?jié)點上進(jìn)行全局聚合。

9原則六:使用高性能的算子

除了shuffle相關(guān)的算子有優(yōu)化原則之外,其他的算子也都有著相應(yīng)的優(yōu)化原則。

使用reduceByKey/aggregateByKey替代groupByKey

詳情見“原則五:使用map-side預(yù)聚合的shuffle操作”。

使用mapPartitions替代普通map

mapPartitions類的算子,一次函數(shù)調(diào)用會處理一個partition所有的數(shù)據(jù),而不是一次函數(shù)調(diào)用處理一條,性能相對來說會高一些。但是有的時候,使用mapPartitions會出現(xiàn)OOM(內(nèi)存溢出)的問題。因為單次函數(shù)調(diào)用就要處理掉一個partition所有的數(shù)據(jù),如果內(nèi)存不夠,垃圾回收時是無法回收掉太多對象的,很可能出現(xiàn)OOM異常。所以使用這類操作時要慎重!

使用foreachPartitions替代foreach

原理類似于“使用mapPartitions替代map”,也是一次函數(shù)調(diào)用處理一個partition的所有數(shù)據(jù),而不是一次函數(shù)調(diào)用處理一條數(shù)據(jù)。在實踐中發(fā)現(xiàn),foreachPartitions類的算子,對性能的提升還是很有幫助的。比如在foreach函數(shù)中,將RDD中所有數(shù)據(jù)寫MySQL,那么如果是普通的foreach算子,就會一條數(shù)據(jù)一條數(shù)據(jù)地寫,每次函數(shù)調(diào)用可能就會創(chuàng)建一個數(shù)據(jù)庫連接,此時就勢必會頻繁地創(chuàng)建和銷毀數(shù)據(jù)庫連接,性能是非常低下;但是如果用foreachPartitions算子一次性處理一個partition的數(shù)據(jù),那么對于每個partition,只要創(chuàng)建一個數(shù)據(jù)庫連接即可,然后執(zhí)行批量插入操作,此時性能是比較高的。實踐中發(fā)現(xiàn),對于1萬條左右的數(shù)據(jù)量寫MySQL,性能可以提升30%以上。

使用filter之后進(jìn)行coalesce操作

通常對一個RDD執(zhí)行filter算子過濾掉RDD中較多數(shù)據(jù)后(比如30%以上的數(shù)據(jù)),建議使用coalesce算子,手動減少RDD的partition數(shù)量,將RDD中的數(shù)據(jù)壓縮到更少的partition中去。因為filter之后,RDD的每個partition中都會有很多數(shù)據(jù)被過濾掉,此時如果照常進(jìn)行后續(xù)的計算,其實每個task處理的partition中的數(shù)據(jù)量并不是很多,有一點資源浪費,而且此時處理的task越多,可能速度反而越慢。因此用coalesce減少partition數(shù)量,將RDD中的數(shù)據(jù)壓縮到更少的partition之后,只要使用更少的task即可處理完所有的partition。在某些場景下,對于性能的提升會有一定的幫助。

使用repartitionAndSortWithinPartitions替代repartition與sort類操作

repartitionAndSortWithinPartitions是Spark官網(wǎng)推薦的一個算子,官方建議,如果需要在repartition重分區(qū)之后,還要進(jìn)行排序,建議直接使用repartitionAndSortWithinPartitions算子。因為該算子可以一邊進(jìn)行重分區(qū)的shuffle操作,一邊進(jìn)行排序。shuffle與sort兩個操作同時進(jìn)行,比先shuffle再sort來說,性能可能是要高的。

10原則七:廣播大變量

有時在開發(fā)過程中,會遇到需要在算子函數(shù)中使用外部變量的場景(尤其是大變量,比如100M以上的大集合),那么此時就應(yīng)該使用Spark的廣播(Broadcast)功能來提升性能。

在算子函數(shù)中使用到外部變量時,默認(rèn)情況下,Spark會將該變量復(fù)制多個副本,通過網(wǎng)絡(luò)傳輸?shù)絫ask中,此時每個task都有一個變量副本。如果變量本身比較大的話(比如100M,甚至1G),那么大量的變量副本在網(wǎng)絡(luò)中傳輸?shù)男阅荛_銷,以及在各個節(jié)點的Executor中占用過多內(nèi)存導(dǎo)致的頻繁GC,都會極大地影響性能。

因此對于上述情況,如果使用的外部變量比較大,建議使用Spark的廣播功能,對該變量進(jìn)行廣播。廣播后的變量,會保證每個Executor的內(nèi)存中,只駐留一份變量副本,而Executor中的task執(zhí)行時共享該Executor中的那份變量副本。這樣的話,可以大大減少變量副本的數(shù)量,從而減少網(wǎng)絡(luò)傳輸?shù)男阅荛_銷,并減少對Executor內(nèi)存的占用開銷,降低GC的頻率。

廣播大變量的代碼示例

// 以下代碼在算子函數(shù)中,使用了外部的變量。
// 此時沒有做任何特殊操作,每個task都會有一份list1的副本。
val list1 = ...
rdd1.map(list1...)

// 以下代碼將list1封裝成了Broadcast類型的廣播變量。
// 在算子函數(shù)中,使用廣播變量時,首先會判斷當(dāng)前task所在Executor內(nèi)存中,是否有變量副本。
// 如果有則直接使用;如果沒有則從Driver或者其他Executor節(jié)點上遠(yuǎn)程拉取一份放到本地Executor內(nèi)存中。
// 每個Executor內(nèi)存中,就只會駐留一份廣播變量副本。
val list1 = ...
val list1Broadcast = sc.broadcast(list1)
rdd1.map(list1Broadcast...)

11原則八:使用Kryo優(yōu)化序列化性能

在Spark中,主要有三個地方涉及到了序列化:

  • 在算子函數(shù)中使用到外部變量時,該變量會被序列化后進(jìn)行網(wǎng)絡(luò)傳輸(見“原則七:廣播大變量”中的講解)。
  • 將自定義的類型作為RDD的泛型類型時(比如JavaRDD,Student是自定義類型),所有自定義類型對象,都會進(jìn)行序列化。因此這種情況下,也要求自定義的類必須實現(xiàn)Serializable接口。
  • 使用可序列化的持久化策略時(比如MEMORY_ONLY_SER),Spark會將RDD中的每個partition都序列化成一個大的字節(jié)數(shù)組。

對于這三種出現(xiàn)序列化的地方,我們都可以通過使用Kryo序列化類庫,來優(yōu)化序列化和反序列化的性能。Spark默認(rèn)使用的是Java的序列化機制,也就是ObjectOutputStream/ObjectInputStream API來進(jìn)行序列化和反序列化。但是Spark同時支持使用Kryo序列化庫,Kryo序列化類庫的性能比Java序列化類庫的性能要高很多。官方介紹,Kryo序列化機制比Java序列化機制,性能高10倍左右。Spark之所以默認(rèn)沒有使用Kryo作為序列化類庫,是因為Kryo要求最好要注冊所有需要進(jìn)行序列化的自定義類型,因此對于開發(fā)者來說,這種方式比較麻煩。

以下是使用Kryo的代碼示例,我們只要設(shè)置序列化類,再注冊要序列化的自定義類型即可(比如算子函數(shù)中使用到的外部變量類型、作為RDD泛型類型的自定義類型等):

// 創(chuàng)建SparkConf對象。
val conf = new SparkConf().setMaster(...).setAppName(...)
// 設(shè)置序列化器為KryoSerializer。
conf.set("spark.serializer""org.apache.spark.serializer.KryoSerializer")
// 注冊要序列化的自定義類型。
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))

12原則九:優(yōu)化數(shù)據(jù)結(jié)構(gòu)

Java中,有三種類型比較耗費內(nèi)存:

  • 對象,每個Java對象都有對象頭、引用等額外的信息,因此比較占用內(nèi)存空間。
  • 字符串,每個字符串內(nèi)部都有一個字符數(shù)組以及長度等額外信息。
  • 集合類型,比如HashMap、LinkedList等,因為集合類型內(nèi)部通常會使用一些內(nèi)部類來封裝集合元素,比如Map.Entry。

因此Spark官方建議,在Spark編碼實現(xiàn)中,特別是對于算子函數(shù)中的代碼,盡量不要使用上述三種數(shù)據(jù)結(jié)構(gòu),盡量使用字符串替代對象,使用原始類型(比如Int、Long)替代字符串,使用數(shù)組替代集合類型,這樣盡可能地減少內(nèi)存占用,從而降低GC頻率,提升性能。

但是在筆者的編碼實踐中發(fā)現(xiàn),要做到該原則其實并不容易。因為我們同時要考慮到代碼的可維護(hù)性,如果一個代碼中,完全沒有任何對象抽象,全部是字符串拼接的方式,那么對于后續(xù)的代碼維護(hù)和修改,無疑是一場巨大的災(zāi)難。同理,如果所有操作都基于數(shù)組實現(xiàn),而不使用HashMap、LinkedList等集合類型,那么對于我們的編碼難度以及代碼可維護(hù)性,也是一個極大的挑戰(zhàn)。因此筆者建議,在可能以及合適的情況下,使用占用內(nèi)存較少的數(shù)據(jù)結(jié)構(gòu),但是前提是要保證代碼的可維護(hù)性。

13原則十:Data Locality本地化級別

PROCESS_LOCAL:進(jìn)程本地化,代碼和數(shù)據(jù)在同一個進(jìn)程中,也就是在同一個executor中;計算數(shù)據(jù)的task由executor執(zhí)行,數(shù)據(jù)在executor的BlockManager中;性能最好

NODE_LOCAL:節(jié)點本地化,代碼和數(shù)據(jù)在同一個節(jié)點中;比如說,數(shù)據(jù)作為一個HDFS block塊,就在節(jié)點上,而task在節(jié)點上某個executor中運行;或者是,數(shù)據(jù)和task在一個節(jié)點上的不同executor中;數(shù)據(jù)需要在進(jìn)程間進(jìn)行傳輸NO_PREF:對于task來說,數(shù)據(jù)從哪里獲取都一樣,沒有好壞之分RACK_LOCAL:機架本地化,數(shù)據(jù)和task在一個機架的兩個節(jié)點上;數(shù)據(jù)需要通過網(wǎng)絡(luò)在節(jié)點之間進(jìn)行傳輸ANY:數(shù)據(jù)和task可能在集群中的任何地方,而且不在一個機架中,性能最差

spark.locality.wait,默認(rèn)是3s

Spark在Driver上,對Application的每一個stage的task,進(jìn)行分配之前,都會計算出每個task要計算的是哪個分片數(shù)據(jù),RDD的某個partition;Spark的task分配算法,優(yōu)先,會希望每個task正好分配到它要計算的數(shù)據(jù)所在的節(jié)點,這樣的話,就不用在網(wǎng)絡(luò)間傳輸數(shù)據(jù);

但是可能task沒有機會分配到它的數(shù)據(jù)所在的節(jié)點,因為可能那個節(jié)點的計算資源和計算能力都滿了;所以呢,這種時候,通常來說,Spark會等待一段時間,默認(rèn)情況下是3s鐘(不是絕對的,還有很多種情況,對不同的本地化級別,都會去等待),到最后,實在是等待不了了,就會選擇一個比較差的本地化級別,比如說,將task分配到靠它要計算的數(shù)據(jù)所在節(jié)點,比較近的一個節(jié)點,然后進(jìn)行計算。

但是對于第二種情況,通常來說,肯定是要發(fā)生數(shù)據(jù)傳輸,task會通過其所在節(jié)點的BlockManager來獲取數(shù)據(jù),BlockManager發(fā)現(xiàn)自己本地沒有數(shù)據(jù),會通過一個getRemote()方法,通過TransferService(網(wǎng)絡(luò)數(shù)據(jù)傳輸組件)從數(shù)據(jù)所在節(jié)點的BlockManager中,獲取數(shù)據(jù),通過網(wǎng)絡(luò)傳輸回task所在節(jié)點。

對于我們來說,當(dāng)然不希望是類似于第二種情況的了。最好的,當(dāng)然是task和數(shù)據(jù)在一個節(jié)點上,直接從本地executor的BlockManager中獲取數(shù)據(jù),純內(nèi)存,或者帶一點磁盤IO;如果要通過網(wǎng)絡(luò)傳輸數(shù)據(jù)的話,那么實在是,性能肯定會下降的,大量網(wǎng)絡(luò)傳輸,以及磁盤IO,都是性能的殺手。

什么時候要調(diào)節(jié)這個參數(shù)?

觀察日志,spark作業(yè)的運行日志,推薦大家在測試的時候,先用client模式,在本地就直接可以看到比較全的日志。日志里面會顯示,starting task,PROCESS LOCAL、NODE LOCAL,觀察大部分task的數(shù)據(jù)本地化級別。

如果大多都是PROCESS_LOCAL,那就不用調(diào)節(jié)了,如果是發(fā)現(xiàn),好多的級別都是NODE_LOCAL、ANY,那么最好就去調(diào)節(jié)一下數(shù)據(jù)本地化的等待時長調(diào)節(jié)完,應(yīng)該是要反復(fù)調(diào)節(jié),每次調(diào)節(jié)完以后,再來運行,觀察日志 看看大部分的task的本地化級別有沒有提升;看看,整個spark作業(yè)的運行時間有沒有縮短

但是注意別本末倒置,本地化級別倒是提升了,但是因為大量的等待時長,spark作業(yè)的運行時間反而增加了,那就還是不要調(diào)節(jié)了。

spark.locality.wait,默認(rèn)是3s;可以改成6s,10s

默認(rèn)情況下,下面3個的等待時長,都是跟上面那個是一樣的,都是3s。

spark.locality.wait.process//建議60s
spark.locality.wait.node//建議30s
spark.locality.wait.rack//建議20s


資源獲取 獲取Flink面試題,Spark面試題,程序員必備軟件,hive面試題,Hadoop面試題,Docker面試題,簡歷模板等資源請去 GitHub自行下載 https://github.com/lhh2002/Framework-Of-BigData Gitee 自行下載  https://gitee.com/li_hey_hey/dashboard/projects

推薦閱讀:

世界的真實格局分析,地球人類社會底層運行原理

不是你需要中臺,而是一名合格的架構(gòu)師(附各大廠中臺建設(shè)PPT)

企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案

論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

華為干部與人才發(fā)展手冊(附PPT)

企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

【中臺實踐】華為大數(shù)據(jù)中臺架構(gòu)分享.pdf

華為的數(shù)字化轉(zhuǎn)型方法論

華為如何實施數(shù)字化轉(zhuǎn)型(附PPT)

超詳細(xì)280頁Docker實戰(zhàn)文檔!開放下載

華為大數(shù)據(jù)解決方案(PPT)

瀏覽 41
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 久99视频| 亚洲免费视频在线观看| www中文字幕| 可以免费看的AV| 国产伦精品一区二区三区妓女下载| 国产激倩都市一区二区三区欧美| 一级aa片| 国产麻豆三级片| 中文字幕VA| 99都是精品| 午夜无码在线观看视频| 俺来也俺也啪www色| 午夜精品久久久| V天堂| 久久久久亚洲AV成人片乱码| 成人AV免费| 91中文字幕在线| 欧美在线视频免费观看| 亚洲精品国偷拍自产在线观看蜜桃| 亚洲成人AV| 久久婷婷久久| 欧美成人毛片AAAAAA| 日韩免费A片| 亚洲av免费看| 国产人妖TS重口系列网站观看| 最近中文字幕中文翻译歌词| 色婷婷官网| 少妇在线观看| 国产精品扒开腿做爽爽爽A片唱戏 中文字幕一区二区三区精华液 | 神马午夜秋霞不卡| 亚洲成人精品一区二区| 欧美AⅤ视频| 超碰毛片| 亚洲国产黄片| 白虎高清无码大尺度免费在线观看| 国产精品你懂的| 色婷婷综合激情| 午夜神马影院| 国产av中文| 一级aa免费视频| 人人妻人人操人人爱| 日韩A片一级无码免费蜜桃| 99er热精品视频| 日韩小电影免费观看高清完整版在线观| 五月丁香婷婷色色| 色撸撸在线视频| 久久青青草在线视频| 婷婷五月天激情丁香| 操逼片| 亚洲精品99| 17c.白丝喷水自慰| 国产资源在线观看| 亚洲性天堂| 日韩无码中文字幕视频| 国产91探花精品一区二区| 久久99高清| 在线免费观看国产视频| 国产美女网站| 香蕉av在线观看| 丰满人妻一区二区三区| 日日精品| 日本大香蕉视频| 国产一级a毛一级a做免费高清视频 | 2021天天夜日| 亚洲成人视频网| 亚洲视频欧洲视频| 日韩一欧美| 东京热在线观看| 亚洲无线观看| 免费小视频| 91精品视频在线播放| 亚洲精品成人7777777| 手机在线观看av| 日韩人妻码一区二区三区| 停停六综合| 91三级片在线观看| 做a视频| www.黄色av| 午夜成人国产| 大香蕉伊人青青草| 欧美V视频| 操欧美女人| 91黄色毛片| 东京热综合影院| 婷婷综合在线| 欧美中文字幕在线观看| 自拍偷拍网站| 亚洲精品99| 国产777777| 三级黄色片| 91狠狠综合久久久久久| 亚洲免费一区二区| 亚洲免费小视频| 嫩BBB槡BBBB槡BBBB撒尿| 久久一| 国产精品揄拍500视频| 无码精品成人观看A片| av影片在线播放| 99久久精品国产一区二区三区| 91热爆TS人妖系列| a网站在线| 蜜桃视频app| 内射网站在线看| 一级AV在线| 国产成人精品免高潮在线观看| 三级视频国产| 97人人爽人人爽人人爽人人爽| 欧美高清一区二区| 91无码精品国产AⅤ| 精品视频免费在线观看| 大香蕉偷拍视频| 成人综合娱乐网| 色播国产成人AV| 日本一区二区在线视频| 欧美日在线观看| 边添小泬边狠狠躁视频| 国产九九九视频| 53岁露大奶熟女偷情贴吧| 亚洲在线资源| 免费无码蜜臀在线观看| 无码秘蜜桃吴梦梦| 久久国产欧美| 中文解说AⅤ水果派| 俺去俺来也WWW色老板| 四色永久成人网站| 影音先锋成人片| 日韩AV一级片| 国产欧美综合一区二区三区| 国产在线观看一区二区| 亚洲久久久久| 亚洲视频网| 91精品久久久久久| 日本A片| 亚洲日色| 久久午夜无码鲁片午夜精品男男| 国产av一二三区| 在线观看免费视频无码| 嫩草久久| 美女高潮网站| 97国产精品视频人人做人人爱| 99re国产视频| 骚逼黄片| 能看的AV网站| 欧美夜夜爽| 亚洲日韩第一页| 国产福利网站| 日韩操比| 亚洲综合社区在线| 二区三区不卡| 大逼影院| 天天日天天操天天爽| 男人天堂视频在线| 亚洲.无码.制服.日韩.中文字幕| 婷婷久久婷婷| 91在线无码精品秘入口三人| jk无码| 亚洲精品福利视频| 在线观看黄| 老妇性BBWBBWBBWBBW| 99热碰碰热| 老鸭窝久久久| 亚洲高清无码视频大全| 99国产精品久久久久久久成人| 欧美成人视频网| 亚洲人妻系列| 91啪啪视频| 苍井空无码| 日韩成人在线视频| 欧美操逼免费视频| 91精品国产综合久久久蜜臀粉嫩 | 亚洲九九视频| 五月婷婷激情综合| 亚洲欧美另类在线| 久久久久久国产精品| 欧美夜夜草视频| 人人操成人| 黑人精品XXX一区一二区| 久久波多野结衣一区二区| 国产AV资源网| 真人BBwBBWBBw另类视频| 国产SUV精品一区二区| 久久久亚洲| 在线中文字幕AV| 国内精品久久久久久久久久| 懂色午夜福利一区二区三区| 精品福利一区二区三区| 亚洲国产成人av| 欧美色影院| 青草视频网| 色婷婷国产精品综合在线观看| 日韩小黄片| 国产在线a| 少妇大战黑人46厘米| 亚洲精品视频在线观看网站| 欧美日韩一区二区三区视频| 18禁网站免费观看| 国产乱码一区二区三区的区别| 欧美日韩一区二区在线观看| 亚洲日韩精品成人无码专区AV| 欧美成人视频电影无码高清| 大香蕉国产| 草逼视频网| 噜噜噜在线视频| 五月天激情爱爱| 亚洲中文字幕在线观看视频网站| 丁香五月婷婷视频| 国产精品久久久久久久久久久久久久久久 | 一级黄色性爱视频| 国产精品免费人成人网站酒店| 亚洲精品国产精品国自产曰本| 成人性生活免费视频| 中文字幕观看| 国产精品久久免费视频| 日韩人妻在线播放| 热久久这里只有精品| 国产99re| 国产一区二区三区在线| 亚洲午夜久久久| 夜夜操狠狠操| 中文字幕无码精品| 欧美操逼视频| 日韩激情视频| 人人看人人草| 一级黄色电影网| 国产欧美日韩| 久操手机在线| AV天堂资源| av在线资源观看| 91口爆| 美国一级A片草草视频| 精品女同一区二区三区四区外站在线 | 黑人AV| 无码天天| 国产精品丝袜| 国产一级a毛一级a做免费图片 | 精品无码AV一区二区三区| 亚洲无码三级视频| 免费国产A片| 人人干国产| 亚洲成人无码高清| 欧美乱伦一区| 中文字幕无码一区二区三区一本久 | 欧美一区三区| 粉粉嫩嫩的18虎白女| 好吊视频一区二区三区| 大鸡巴操小逼视频| 久久偷看各类wc女厕嘘嘘偷窃 | 精品成人视频| 中国熟妇XXXX18| 五月丁香欧美性爱| 手机看片1024你懂的| 亚洲精品女人久久久| 久久草在线| 长泽梓黑人初解禁BDD07| 精品一区二区免费视频| 91吴梦梦一区二区传媒| 欧美青青草| 九九九九精品视频| 日韩乱伦av| 九九精品视频在线播放| 国产亚洲一区二区三区| 一本久久精品一区二区| 伊人一区二区三区| 丰满熟妇高潮呻吟无码| 欧美区亚洲区| 国产成人A| 久草视频在线播放| 亚洲操逼AV| 亚洲激情在线观看| 久久高清无码视频| 久久久久久久三级片| 91欧美性爱| 国产黄色免费乱伦片| 777av| 永久免费叼嘿| 国产AV无码成人精品区| 国产麻豆剧传媒精品国产AV| 国产超级无码高清在线视频观看 | 蜜桃秘一二三区最新| 人人弄人人| 日本少妇做爱| 亚洲性爱视频在线观看| 日韩成人在线视频| 思思热在线视频精品| 少妇搡BBBB搡BBB搡小说| 地表最强网红八月未央道具大秀| 精品视频网| 淫香淫色天天影视| 视频在线一区| 成人无码免费毛片A片| 四虎无码视频| 青青操逼网| 这里有精品| 高清无码高潮| 久久福利社| 日韩一区二区视频| 日韩一级A| 特级西西444www大精品| 狠狠操网| 亚洲无码理论片| 亚洲无码视频免费| 黄色电影免费看| 欧美色色综合| 日韩无码三级| 午夜免费播放观看在线视频| 中文字幕精品视频在线观看| 亚洲精品蜜桃| 综合成人在线| 日本免费版网站nba| 操久| 久久久三级| 超碰免费在线观看| a天堂8| 色色97| 黄色A片网址| 一级黄色片免费| 亚洲无线观看| 就爱av| 亚洲欧美国产日韩字幕| 91热99| 黄片大全在线免费观看| 国产精品扒开腿做爽爽爽A片唱戏| 五月天亚洲无码| 黄色国产免费| 亚洲AV官方网站| www.xxx国产| 无码高清一区| 人妻北条麻妃在线| 三级午夜在线无码| 91在线免费视频| 国产美女做爱视频| 国产精品扒开腿做爽爽爽A片唱戏 中文字幕一区二区三区精华液 | 国产亲子乱XXXXinin| 99香蕉视频| 婷婷五月电影| 国产夫妻自拍av| 亚洲V无码| 成人福利网站| 最近中文字幕免费mv第一季歌词強上| 丁香婷婷在线| 丁香五月天网站| 日韩免费Av| 天堂8在线| 91成人做爰A片| 国产免费一级特黄A片| 男女内射视频| 久久蜜桃成人| 高清无码在线观看免费| 翔田千里在线一区二区三区| 青草福利在线| 欧美国产成人在线| 天天干无码| 天天干天天干天天干| 超碰福利导航| 久久久精品电影| 97pao| 一级A片亲子乱| 51伦理| 天堂网av在线| 中文√在线天堂8| 国产久久久久久| 樱桃Av| 91在线无码精品秘入口国战| 亚洲免费视频在线| 亚洲欧美高清视频| 欧美疯狂做受XXXXX高潮| 91视频观看| 亚洲色图1| 500部大龄熟乱4K视频| 国产一级婬乱A片| 久操AV| 综合久久视频| 欧美成人精品一区二区三区| 黄色视频网站观看| 亚洲高清无码一区| 精品狼友| 日韩欧美中文在线| 黄色视频大全免费看| 男插女青青影院| 高清免费在线中文Av| www.国产精品| 日韩综合区| 午夜福利毛片| 精品久久无码| 日本黄色三级片| 97超碰中文字幕| 99精品免费视频| 97pao| 久久久久亚洲AV无码网影音先锋| 国产成人精品一区二三区熟女在线 | 一级日逼视频| 五月天性爱视频| 一级AAAAA片裸体做受| 午夜福利院| 亚洲最大网站| 91精品一区| 五月天婷婷影院影院| 91精品国久久久久久无码一区二区三区| 91亚洲精品国偷拍自产在线观看 | www.日韩AV| 国产日逼视频| 看肏屄视频| 国产操女人| 免费黄色视频网址| 精品乱子伦一区二区三区下载| 亚洲无码AV在线播放| 一级片AA| 日逼天堂| 美日韩一区| 91精品人妻一区二区三区蜜桃 | 最新中文字幕免费MV第一季歌词| 欧美91熟| 乱子伦国产精品一区二区| 国产一区二区免费看| 色欲欲www成人网站| 大香蕉网视频| 亚洲午夜成人精品一区二区| 四川BBBBBB搡BBBBB| 国产毛片一照区| 久久婷婷综合网| 成人五月天黄色电影| 成人小说在线观看| jizz丝袜| 欧美成人一区二区三区| 久久学生妹| 综合欧美国产视频二区| 久久999| 日韩欧美一级A片| 曰韩毛片| 亚洲在线一区二区| 天天精品| 青娱乐成人在线| 51成人免费| 欧美囗交荫蒂AAAA| 狠狠狠狠狠狠操| 日本在线观看| 狠狠干天天日| 亚洲国产成人无码| 精品毛片| 亚洲高清电影| 丰满人妻一区二区三区视频在线不卡| 综合色婷婷一区二区亚洲欧美国产 | 91ncom| 男人的天堂在线视频| 91av在线电影| 欧美激情在线| 欧美成人福利| 人人色人人色| 黄色电影网站在线观看| 超碰91免费在线观看| 狠狠狠狠狠狠| 成人免费在线网站| 国产又爽又黄视频| 91精品国产偷窥一区二区| 欧美亚洲在线观看| 亚洲无码免费观看| 巨爆乳肉感一区二区三区| 欧美三级性爱视频| 日韩激情网| 一卡二卡三卡| 天天色图片| 久久99精品视频| 日韩无码少妇| 日本色情网| 九色PORNY自拍视频| yw尤物视频| 国产欧美日本视频| 天天操天天干天天射| 91乱| 在线免费人成视频| 午夜性爱剧场| 1000部毛片A片免费视频| 九九免费视频| 中文资源在线a| 波多野结衣视频在线播放| 亚洲无码一二区| 亚洲精品无码一区| 污网站免费在线观看| 黑人巨大翔田千里AⅤ| 日韩中文字幕不卡| 激情久久综合| 日本AI高清无码在线观看网址| 成人做爰69片免费观看| 91一级片| 午夜av免费在线| 黑人一级| 天天精品视频| 亚洲AV综合色区无码国产播放 | 乱伦播放五月天| 欧美一级A片高清免费播放| 亚洲a网| 97播播| 中文字幕在线观看辣文| 成人毛片| 婷婷综合一区| 日韩中文字幕无码人妻| 天天干天天操天天干| 丁香五月婷婷啪啪| 免费观看的av| 操逼视频网| 国产h视频| 91蝌蚪视频在线播放| yy午夜福利| 精品国产99| 亚洲在线大香蕉| 精品无码一区二区三区| 99视频热| 天天色天天日天天干| 国产激情无码免费| 国产精品一级无码免费播放| 777AV| 伊人久久免费视频| 免费做a爰片77777| 日本AI高清无码在线观看网址| 久久久久久久亚洲| 99热免费精品| 中文字幕无码精品三级在线欧美| 日韩黄色毛片| 日产无码| 亚洲成人在线观看视频| 四川妇搡BBBB搡BBBB| 成人在线观看网站| 911精品国产一区二区在线| 欧美日韩国产免费观看成人片| 成人女人18女人毛片| 中文无码熟妇人妻AV在线| 婷婷在线电影| 在线播放91灌醉迷J高跟美女| 91黄色毛片| www.狠狠| 在线日韩av| 国产无码高清在线| 在线观看免费视频无码| 成人自拍偷拍视频| 亚洲人妻在线观看| 欧美日韩精品一区二区三区视频播放| 高清无码一区二区在线| 九色PORNY国产成人蝌蚪| 欧美日韩中文字幕| 久久黄色视频免费观看| 91精品少妇高潮一区二区三区不卡| 日韩美女免费性爱视频| 色五月视频| 91抽插| 99热精品免费观看| 欧美人人插| 亚洲资源在线| 国内老熟妇对白HDXXXX| 高清无码第一页| 能看的操逼视频| 超碰在线人人干| 欧亚毛片| 国产精品成人无码| 国产精品AV在线观看| 五月天婷婷网址| www99| 欧美午夜精品| 国产网站在线| 黄色小说视频网站| 色呦呦视频在线观看| 久久久久久久久成人| 国产午夜男女性爱| 青草视频在线播放| 婷婷色在线播放| 无码免费毛片一区二区三区古代 | 成人在线一区二区三区| 色婷婷AV在线观看| 色欧美大香蕉| 综合网久久| 亚洲AV电影网| 嫰BBB槡BBBB槡BBBB| 日本aaaa片| 国产熟妇搡BBBB搡BBBB搡| 成人三级黄色| 婷婷在线播放| 国产肏逼视频| 大香蕉中文网| 亚洲免费一级片| 久草视频在线免费播放| 德国肥妇熟妇BBwBBw| 天天做| 九九热在线观看| 久久停停| 老婆被黑人杂交呻吟视频| 人人操超碰在线观看| 久久影院av| 久久久久久久久久久久久久久久久久免费精品分类视频 | 日韩Av无码一区二区三区不卡 | 亚洲成人视频在线观看| 五月丁香综合激情| 丰满老妇高潮一级A片| 中日韩特黄A片免费视频| 翔田千里中文字幕无码| 午夜噜噜| 久久国产精品伦子伦| 短发妹子双人啪啪秀| 日韩精品区| h片免费观看| 欧美三级毛片| 探花无码| 一本色道久久| 欧美日韩一区二区在线| 亚洲AV永久无码国产精品久久| 激情亚洲五月天| 国内夫妻【20p】| 成人免费版欧美州| 日韩精品成人无码免费| 国产无遮挡又黄又爽| chinese搡老熟老妇人| 成人AV午夜福利| 永久免费黄色视频网站| 国产真人一级a爱做片| 国产三级| 影音先锋自拍| 无码一区二区三区在线| 国产成人无码区免费AV片在线| 一区二区日本| 少妇无码在线观看| 欧美日韩在线视频免费| 加勒比国产在线| 91香蕉网站| 少妇搡BBBB搡BBB搡毛片| 汇聚全球淫荡熟女| 色天堂在线观看| 国产综合激情| 午夜福利毛片| 日韩成人网址| 婷婷丁香五月综合| 成人毛片100免费观看| 久久偷拍网| 亚洲黄色免费观看| 五月天福利影院| 地表最强网红八月未央道具大秀| 看免费操逼视频| av影音先锋| 欧美一级片免费看| 婷婷五月电影| 国产91在线中日| 91视频在线观看网| 五月婷婷色| 麻豆回家视频区一区二| 老鸭窝毛片| 无码免费在线视频| 无码人妻av黄色一区二区三区| 嫩草在线视频| 丝袜美腿亚洲综合| 成人在线免费网站| 久久XX| 午夜福利黄| 久久婷婷网| 欧美性爱天天操| 久久牛牛| 亚洲乱码中文字幕| 人人做人人做人人做,人人做全句下一 | 五月综合色| 婷婷99狠狠躁天天躁| 91人妻人人爽人人爽| 久久精品大香蕉| 国产精品视频久久久| 成人做爰100部免费网站| 成人a片在线观看| 日韩有码电影| 18久久| 91丨熟女丨对白| 北条麻妃被躁57分钟视频在线 | 理论片熟女奶水哺乳| 人人色人人干| 久久99老妇伦国产熟女| 毛片在线观看网站| 国产精品黄色电影| 国产黄| 久久天天操| 黄色一级a片| 人人爽人人澡| 91麻豆精品传媒国产| 婷婷免费视频| aa无码| 重庆美女揉BBBB搡BBBB| 亚洲热在线观看| 91蝌蚪| 国产高清不卡| 日本无码嫩草一区二区| 亚洲国产成人精品女人| jizzjizz国产| 欧美爱爱网| 亚洲成人黄色电影| 伊人成人在线| 欧美激情四射老司机| 亚洲高清国产欧美综合s8| 精品一区二区三区毛片| 国产一级特黄aaa大片| 加勒比日韩无码| 日韩人妻精品一区二区| 中文字幕精品一区久久久久| 白嫩无码| 欧美日韩色视频| 日韩欧美91| 国产AV直播| japanese在线观看| 中文字幕va| 夜色视频网| 丁香五月婷婷啪啪| av在线免费观看网站| 色色视频在线观看| 天天爽夜夜爽人人爽| 人妖毛片| 人人妻人人| 亚洲日韩视频在线观看| 国产免费自拍| 招土一级黄色片| 小H片在线观看| 欧美A片免费观看| 色婷婷俺来也| 色999亚洲人成色| 国产精品美女在线观看| 北条麻妃AV在线播放| 99精品全国免费观看| 国产精品成人在线观看| 精品一区二区久久久久久久网站 | 久操视频免费在线观看| 毛片操逼视频| 国产女同性系列| 操逼网站在线观看| 男女www| 人妻少妇视频| 看操b视频| 色天堂视频在线观看| 国产一区视频18| av黄色网址| 日韩免费视频一区| 美日韩一区二区三区| 国产三级AV在线| 久久精品成人| 翔田千里一区二区| 操比视频| 激情淫荡少妇| 日本一区二区三区四区| 欧美日韩国产成人在线观看| 一级黄色电影免费在线观看| 国产乱伦一区| 中文无码第一页| www.6969成人片亚洲| 97人人爽| 97精品国产| 韩国毛片基地久久| 69视频在线观看免费| 免费的黄色视频网站| AV天堂资源| 撒尿BBw搡BBwBBw| 超碰在线天天干| 免费无码一区二区三区| 精品国产av| 无码av亚洲一区二区毛片公司| 国产三级成人| 在线高清无码视频| 欧美日韩精品一区二区三区视频播放| 免费日本黄色| 亚洲视频免费播放| 黄色片在线看| 国产免费一区二区三区网站免费 | 成人播放视频| 羞羞AV| 中文字幕在线播放第一页| 久久久波多野结衣| 高清无码三级片在线观看| 永久免费看片视频| 亚洲成人在线免费观看| 国产福利视频| 亚洲俺去了| 黑人乱伦| 九九精品热播| 久草香蕉视频| 国产一级大片| 少妇人妻偷人精品无码视频新浪 | 黄色电影视频在线| 日韩在线视频中文字幕码无| 久久综合伊人| 大香蕉手机视频| 免费看日韩毛片| 一级片电影网站| 精品人妻一区二区免费蜜桃| 猫咪AV大香蕉| 国产精品久久久久久久久久九秃| 五月天婷婷丁香| 大香蕉大香蕉大香蕉| 国产精品视频导航| 亚洲精品视频免费在线观看| 少妇白洁视频| 日韩黄色小说| 香蕉漫画在线观看18| 久久婷婷热| 日批动态图| 久久久久久穴| 激情一区二区三区| 在线综合国产欧美| 国产精品做爱| 精品永久免费| 好色婷婷| 国产激情视频在线观看| 欧美日韩不卡在线| 97成人精品| 草草国产| 国产一区在线播放| 青娱乐亚洲视频| 大黑人荫蒂BBBBBBBBB| 亚洲乱码一区| 亚洲一区二区在线播放| 国产久久精品视频| 大香伊人| 国产三级在线观看视频| 免费福利在线视频| 成人免费在线视频| 二区三区在线| 一级特黄妇女高潮AA片免费播放| 欧美一级a| 欧一美一婬一伦一区二区三区黑人| 91成人网站| 大香蕉玖玖| 噜噜色色噜噜| 中文无码播放| 青娱乐| 国产噜噜噜噜噜久久久久久久久 | 超碰午夜| 鸭子AV| 中文字幕91| 古装一级无遮挡A片| 三级片网站在线观看| 久久久91人妻无码精品蜜桃ID| 性少妇| 日本综合久久| 无码在线免费播放| 国产毛片一照区| 在线看a片| 人操人操人操| 婷婷中文| 成人先锋AV| 人妻少妇视频| 成人A片免费视频| 大伊香蕉久久| 国产一级片免费视频| 做aAAAAA免费视频| 浪潮在线观看完整版| 免费成人黄色| 操逼视频在线播放| 色色777| 不卡的一区二区| 日本一区二区视频在线| 国产精品美女久久久| 3D动漫精品啪啪一区二区| 日韩精品成人专区无码| 国产精品成人AV在线| 亚洲三级久久| 日本高清无码在线观看| 激情综合视频| 91色在线视频| 欧美精品在线免费观看| 日本久久精品| 内射免费视频| 国产成人精品一区二三区熟女在线 | 成人视频18| 人人综合| 欧美又粗又大| 欧美日韩成人在线观看| 天天爽天天摸| 国产69精品久久| 91av在线观看视频| 精品操逼视频| 久久久久亚洲AV成人片乱码| 亚洲午夜无码精品专区| 国产精品剧情| 国产性爱自拍一下| 婷婷五月天色| 欧美成人一区二区三区| 安徽妇搡BBBB搡BBBB按摩小说| 国产传媒在线观看| A级网站| 国产精品美女毛片真酒店| 中文字幕人妻一区| 国产精品无码成人AV在线播放| 丁香五月综合网| 奇米一区| 91精品丝袜久久久久久久久粉嫩| 中文解说AⅤ水果派| 色天使视频| 亚洲精品suv视频| 欧美a区| 青娱乐在线视频精品| 久久婷婷色| 国产在线免费视频| 麻豆一区二区三区四区| 男人的天堂色婷婷| 草草国产| 熟女综合| 国产精品粉嫩福利在线| 无码国产一区二区三区四区五区| 青青草免费观看视频| 欧美成人福利| 欧美日韩国产精品成人| 亚洲精品911| 中文字幕日韩视频|