日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spark性能优化指南——基础篇

發布時間:2024/7/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spark性能优化指南——基础篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在大數據計算領域,Spark已經成為了越來越流行、越來越受歡迎的計算平臺之一。Spark的功能涵蓋了大數據領域的離線批處理、SQL類處理、流式/實時計算、機器學習、圖計算等各種不同類型的計算操作,應用范圍與前景非常廣泛。在美團?大眾點評,已經有很多同學在各種項目中嘗試使用Spark。大多數同學(包括筆者在內),最初開始嘗試使用Spark的原因很簡單,主要就是為了讓大數據計算作業的執行速度更快、性能更高。

然而,通過Spark開發出高性能的大數據計算作業,并不是那么簡單的。如果沒有對Spark作業進行合理的調優,Spark作業的執行速度可能會很慢,這樣就完全體現不出Spark作為一種快速大數據計算引擎的優勢來。因此,想要用好Spark,就必須對其進行合理的性能優化。

Spark的性能調優實際上是由很多部分組成的,不是調節幾個參數就可以立竿見影提升作業性能的。我們需要根據不同的業務場景以及數據情況,對Spark作業進行綜合性的分析,然后進行多個方面的調節和優化,才能獲得最佳性能。

筆者根據之前的Spark作業開發經驗以及實踐積累,總結出了一套Spark作業的性能優化方案。整套方案主要分為開發調優、資源調優、數據傾斜調優、shuffle調優幾個部分。開發調優和資源調優是所有Spark作業都需要注意和遵循的一些基本原則,是高性能Spark作業的基礎;數據傾斜調優,主要講解了一套完整的用來解決Spark作業數據傾斜的解決方案;shuffle調優,面向的是對Spark的原理有較深層次掌握和研究的同學,主要講解了如何對Spark作業的shuffle運行過程以及細節進行調優。

本文作為Spark性能優化指南的基礎篇,主要講解開發調優以及資源調優。

調優概述

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

原則一:避免創建重復的RDD

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

我們在開發過程中要注意:對于同一份數據,只應該創建一個RDD,不能創建多個RDD來代表同一份數據。

一些Spark初學者在剛開始開發Spark作業時,或者是有經驗的工程師在開發RDD lineage極其冗長的Spark作業時,可能會忘了自己之前對于某一份數據已經創建過一個RDD了,從而導致對于同一份數據,創建了多個RDD。這就意味著,我們的Spark作業會進行多次重復計算來創建多個代表相同數據的RDD,進而增加了作業的性能開銷。

一個簡單的例子

// 需要對名為“hello.txt”的HDFS文件進行一次map操作,再進行一次reduce操作。也就是說,需要對一份數據執行兩次算子操作。// 錯誤的做法:對于同一份數據執行多次算子操作時,創建多個RDD。 // 這里執行了兩次textFile方法,針對同一個HDFS文件,創建了兩個RDD出來,然后分別對每個RDD都執行了一個算子操作。 // 這種情況下,Spark需要從HDFS上兩次加載hello.txt文件的內容,并創建兩個單獨的RDD;第二次加載HDFS文件以及創建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(...)// 正確的用法:對于一份數據執行多次算子操作時,只使用一個RDD。 // 這種寫法很明顯比上一種寫法要好多了,因為我們對于同一份數據只創建了一個RDD,然后對這一個RDD執行了多次算子操作。 // 但是要注意到這里為止優化還沒有結束,由于rdd1被執行了兩次算子操作,第二次執行reduce操作的時候,還會再次從源頭處重新計算一次rdd1的數據,因此還是會有重復計算的性能開銷。 // 要徹底解決這個問題,必須結合“原則三:對多次使用的RDD進行持久化”,才能保證一個RDD被多次使用時只被計算一次。 val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt") rdd1.map(...) rdd1.reduce(...)

原則二:盡可能復用同一個RDD

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

一個簡單的例子

// 錯誤的做法。// 有一個<Long, String>格式的RDD,即rdd1。 // 接著由于業務需要,對rdd1執行了一個map操作,創建了一個rdd2,而rdd2中的數據僅僅是rdd1中的value值而已,也就是說,rdd2是rdd1的子集。 JavaPairRDD<Long, String> rdd1 = ... JavaRDD<String> rdd2 = rdd1.map(...)// 分別對rdd1和rdd2執行了不同的算子操作。 rdd1.reduceByKey(...) rdd2.map(...)// 正確的做法。// 上面這個case中,其實rdd1和rdd2的區別無非就是數據格式不同而已,rdd2的數據完全就是rdd1的子集而已,卻創建了兩個rdd,并對兩個rdd都執行了一次算子操作。 // 此時會因為對rdd1執行map算子來創建rdd2,而多執行一次算子操作,進而增加性能開銷。// 其實在這種情況下完全可以復用同一個RDD。 // 我們可以使用rdd1,既做reduceByKey操作,也做map操作。 // 在進行第二個map操作時,只使用每個數據的tuple._2,也就是rdd1中的value值,即可。 JavaPairRDD<Long, String> rdd1 = ... rdd1.reduceByKey(...) rdd1.map(tuple._2...)// 第二種方式相較于第一種方式而言,很明顯減少了一次rdd2的計算開銷。 // 但是到這里為止,優化還沒有結束,對rdd1我們還是執行了兩次算子操作,rdd1實際上還是會被計算兩次。 // 因此還需要配合“原則三:對多次使用的RDD進行持久化”進行使用,才能保證一個RDD被多次使用時只被計算一次。

原則三:對多次使用的RDD進行持久化

當你在Spark代碼中多次對一個RDD做了算子操作后,恭喜,你已經實現Spark作業第一步的優化了,也就是盡可能復用RDD。此時就該在這個基礎之上,進行第二步優化了,也就是要保證對一個RDD執行多次算子操作時,這個RDD本身僅僅被計算一次。

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

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

對多次使用的RDD進行持久化的代碼示例

// 如果要對一個RDD進行持久化,只要對這個RDD調用cache()和persist()即可。// 正確的做法。 // cache()方法表示:使用非序列化的方式將RDD中的數據全部嘗試持久化到內存中。 // 此時再對rdd1執行兩次算子操作時,只有在第一次執行map算子時,才會將這個rdd1從源頭處計算一次。 // 第二次執行reduce算子時,就會直接從內存中提取數據進行計算,不會重復計算一個rdd。 val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt").cache() rdd1.map(...) rdd1.reduce(...)// persist()方法表示:手動選擇持久化級別,并使用指定的方式進行持久化。 // 比如說,StorageLevel.MEMORY_AND_DISK_SER表示,內存充足時優先持久化到內存中,內存不充足時持久化到磁盤文件中。 // 而且其中的_SER后綴表示,使用序列化的方式來保存RDD數據,此時RDD中的每個partition都會序列化成一個大的字節數組,然后再持久化到內存或磁盤中。 // 序列化的方式可以減少持久化的數據對內存/磁盤的占用量,進而避免內存被持久化數據占用過多,從而發生頻繁GC。 val rdd1 = sc.textFile("hdfs://192.168.0.1:9000/hello.txt").persist(StorageLevel.MEMORY_AND_DISK_SER) rdd1.map(...) rdd1.reduce(...)

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

Spark的持久化級別

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

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

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

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

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

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

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

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

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

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

Broadcast與map進行join代碼示例

// 傳統的join操作會導致shuffle操作。 // 因為兩個RDD中,相同的key都需要通過網絡拉取到一個節點上,由一個task進行join操作。 val rdd3 = rdd1.join(rdd2)// Broadcast+map的join操作,不會導致shuffle操作。 // 使用Broadcast將一個數據量較小的RDD作為廣播變量。 val rdd2Data = rdd2.collect() val rdd2DataBroadcast = sc.broadcast(rdd2Data)// 在rdd1.map算子中,可以從rdd2DataBroadcast中,獲取rdd2的所有數據。 // 然后進行遍歷,如果發現rdd2中某條數據的key與rdd1的當前數據的key是相同的,那么就判定可以進行join。 // 此時就可以根據自己需要的方式,將rdd1當前數據與rdd2中可以連接的數據,拼接在一起(String或Tuple)。 val rdd3 = rdd1.map(rdd2DataBroadcast...)// 注意,以上操作,建議僅僅在rdd2的數據量比較少(比如幾百M,或者一兩G)的情況下使用。 // 因為每個Executor的內存中,都會駐留一份rdd2的全量數據。

原則五:使用map-side預聚合的shuffle操作

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

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

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

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

除了shuffle相關的算子有優化原則之外,其他的算子也都有著相應的優化原則。

使用reduceByKey/aggregateByKey替代groupByKey

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

使用mapPartitions替代普通map

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

使用foreachPartitions替代foreach

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

使用filter之后進行coalesce操作

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

使用repartitionAndSortWithinPartitions替代repartition與sort類操作

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

原則七:廣播大變量

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

在算子函數中使用到外部變量時,默認情況下,Spark會將該變量復制多個副本,通過網絡傳輸到task中,此時每個task都有一個變量副本。如果變量本身比較大的話(比如100M,甚至1G),那么大量的變量副本在網絡中傳輸的性能開銷,以及在各個節點的Executor中占用過多內存導致的頻繁GC,都會極大地影響性能。

因此對于上述情況,如果使用的外部變量比較大,建議使用Spark的廣播功能,對該變量進行廣播。廣播后的變量,會保證每個Executor的內存中,只駐留一份變量副本,而Executor中的task執行時共享該Executor中的那份變量副本。這樣的話,可以大大減少變量副本的數量,從而減少網絡傳輸的性能開銷,并減少對Executor內存的占用開銷,降低GC的頻率。

廣播大變量的代碼示例

// 以下代碼在算子函數中,使用了外部的變量。 // 此時沒有做任何特殊操作,每個task都會有一份list1的副本。 val list1 = ... rdd1.map(list1...)// 以下代碼將list1封裝成了Broadcast類型的廣播變量。 // 在算子函數中,使用廣播變量時,首先會判斷當前task所在Executor內存中,是否有變量副本。 // 如果有則直接使用;如果沒有則從Driver或者其他Executor節點上遠程拉取一份放到本地Executor內存中。 // 每個Executor內存中,就只會駐留一份廣播變量副本。 val list1 = ... val list1Broadcast = sc.broadcast(list1) rdd1.map(list1Broadcast...)

原則八:使用Kryo優化序列化性能

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

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

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

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

原則九:優化數據結構

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

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

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

調優概述

在開發完Spark作業之后,就該為作業配置合適的資源了。Spark的資源參數,基本都可以在spark-submit命令中作為參數設置。很多Spark初學者,通常不知道該設置哪些必要的參數,以及如何設置這些參數,最后就只能胡亂設置,甚至壓根兒不設置。資源參數設置的不合理,可能會導致沒有充分利用集群資源,作業運行會極其緩慢;或者設置的資源過大,隊列沒有足夠的資源來提供,進而導致各種異常。總之,無論是哪種情況,都會導致Spark作業的運行效率低下,甚至根本無法運行。因此我們必須對Spark作業的資源使用原理有一個清晰的認識,并知道在Spark作業運行過程中,有哪些資源參數是可以設置的,以及如何設置合適的參數值。

Spark作業基本運行原理

詳細原理見上圖。我們使用spark-submit提交一個Spark作業之后,這個作業就會啟動一個對應的Driver進程。根據你使用的部署模式(deploy-mode)不同,Driver進程可能在本地啟動,也可能在集群中某個工作節點上啟動。Driver進程本身會根據我們設置的參數,占有一定數量的內存和CPU core。而Driver進程要做的第一件事情,就是向集群管理器(可以是Spark Standalone集群,也可以是其他的資源管理集群,美團?大眾點評使用的是YARN作為資源管理集群)申請運行Spark作業需要使用的資源,這里的資源指的就是Executor進程。YARN集群管理器會根據我們為Spark作業設置的資源參數,在各個工作節點上,啟動一定數量的Executor進程,每個Executor進程都占有一定數量的內存和CPU core。

在申請到了作業執行所需的資源之后,Driver進程就會開始調度和執行我們編寫的作業代碼了。Driver進程會將我們編寫的Spark作業代碼分拆為多個stage,每個stage執行一部分代碼片段,并為每個stage創建一批task,然后將這些task分配到各個Executor進程中執行。task是最小的計算單元,負責執行一模一樣的計算邏輯(也就是我們自己編寫的某個代碼片段),只是每個task處理的數據不同而已。一個stage的所有task都執行完畢之后,會在各個節點本地的磁盤文件中寫入計算中間結果,然后Driver就會調度運行下一個stage。下一個stage的task的輸入數據就是上一個stage輸出的中間結果。如此循環往復,直到將我們自己編寫的代碼邏輯全部執行完,并且計算完所有的數據,得到我們想要的結果為止。

Spark是根據shuffle類算子來進行stage的劃分。如果我們的代碼中執行了某個shuffle類算子(比如reduceByKey、join等),那么就會在該算子處,劃分出一個stage界限來。可以大致理解為,shuffle算子執行之前的代碼會被劃分為一個stage,shuffle算子執行以及之后的代碼會被劃分為下一個stage。因此一個stage剛開始執行的時候,它的每個task可能都會從上一個stage的task所在的節點,去通過網絡傳輸拉取需要自己處理的所有key,然后對拉取到的所有相同的key使用我們自己編寫的算子函數執行聚合操作(比如reduceByKey()算子接收的函數)。這個過程就是shuffle。

當我們在代碼中執行了cache/persist等持久化操作時,根據我們選擇的持久化級別的不同,每個task計算出來的數據也會保存到Executor進程的內存或者所在節點的磁盤文件中。

因此Executor的內存主要分為三塊:第一塊是讓task執行我們自己編寫的代碼時使用,默認是占Executor總內存的20%;第二塊是讓task通過shuffle過程拉取了上一個stage的task的輸出后,進行聚合等操作時使用,默認也是占Executor總內存的20%;第三塊是讓RDD持久化時使用,默認占Executor總內存的60%。

task的執行速度是跟每個Executor進程的CPU core數量有直接關系的。一個CPU core同一時間只能執行一個線程。而每個Executor進程上分配到的多個task,都是以每個task一條線程的方式,多線程并發運行的。如果CPU core數量比較充足,而且分配到的task數量比較合理,那么通常來說,可以比較快速和高效地執行完這些task線程。

以上就是Spark作業的基本運行原理的說明,大家可以結合上圖來理解。理解作業基本原理,是我們進行資源參數調優的基本前提。

資源參數調優

了解完了Spark作業運行的基本原理之后,對資源相關的參數就容易理解了。所謂的Spark資源參數調優,其實主要就是對Spark運行過程中各個使用資源的地方,通過調節各種參數,來優化資源使用的效率,從而提升Spark作業的執行性能。以下參數就是Spark中主要的資源參數,每個參數都對應著作業運行原理中的某個部分,我們同時也給出了一個調優的參考值。

num-executors

  • 參數說明:該參數用于設置Spark作業總共要用多少個Executor進程來執行。Driver在向YARN集群管理器申請資源時,YARN集群管理器會盡可能按照你的設置來在集群的各個工作節點上,啟動相應數量的Executor進程。這個參數非常之重要,如果不設置的話,默認只會給你啟動少量的Executor進程,此時你的Spark作業的運行速度是非常慢的。
  • 參數調優建議:每個Spark作業的運行一般設置50~100個左右的Executor進程比較合適,設置太少或太多的Executor進程都不好。設置的太少,無法充分利用集群資源;設置的太多的話,大部分隊列可能無法給予充分的資源。

executor-memory

  • 參數說明:該參數用于設置每個Executor進程的內存。Executor內存的大小,很多時候直接決定了Spark作業的性能,而且跟常見的JVM OOM異常,也有直接的關聯。
  • 參數調優建議:每個Executor進程的內存設置4G~8G較為合適。但是這只是一個參考值,具體的設置還是得根據不同部門的資源隊列來定。可以看看自己團隊的資源隊列的最大內存限制是多少,num-executors乘以executor-memory,是不能超過隊列的最大內存量的。此外,如果你是跟團隊里其他人共享這個資源隊列,那么申請的內存量最好不要超過資源隊列最大總內存的1/3~1/2,避免你自己的Spark作業占用了隊列所有的資源,導致別的同學的作業無法運行。

executor-cores

  • 參數說明:該參數用于設置每個Executor進程的CPU core數量。這個參數決定了每個Executor進程并行執行task線程的能力。因為每個CPU core同一時間只能執行一個task線程,因此每個Executor進程的CPU core數量越多,越能夠快速地執行完分配給自己的所有task線程。
  • 參數調優建議:Executor的CPU core數量設置為2~4個較為合適。同樣得根據不同部門的資源隊列來定,可以看看自己的資源隊列的最大CPU core限制是多少,再依據設置的Executor數量,來決定每個Executor進程可以分配到幾個CPU core。同樣建議,如果是跟他人共享這個隊列,那么num-executors * executor-cores不要超過隊列總CPU core的1/3~1/2左右比較合適,也是避免影響其他同學的作業運行。

driver-memory

  • 參數說明:該參數用于設置Driver進程的內存。
  • 參數調優建議:Driver的內存通常來說不設置,或者設置1G左右應該就夠了。唯一需要注意的一點是,如果需要使用collect算子將RDD的數據全部拉取到Driver上進行處理,那么必須確保Driver的內存足夠大,否則會出現OOM內存溢出的問題。

spark.default.parallelism

  • 參數說明:該參數用于設置每個stage的默認task數量。這個參數極為重要,如果不設置可能會直接影響你的Spark作業性能。
  • 參數調優建議:Spark作業的默認task數量為500~1000個較為合適。很多同學常犯的一個錯誤就是不去設置這個參數,那么此時就會導致Spark自己根據底層HDFS的block數量來設置task的數量,默認是一個HDFS block對應一個task。通常來說,Spark默認設置的數量是偏少的(比如就幾十個task),如果task數量偏少的話,就會導致你前面設置好的Executor的參數都前功盡棄。試想一下,無論你的Executor進程有多少個,內存和CPU有多大,但是task只有1個或者10個,那么90%的Executor進程可能根本就沒有task執行,也就是白白浪費了資源!因此Spark官網建議的設置原則是,設置該參數為num-executors * executor-cores的2~3倍較為合適,比如Executor的總CPU core數量為300個,那么設置1000個task是可以的,此時可以充分地利用Spark集群的資源。

spark.storage.memoryFraction

  • 參數說明:該參數用于設置RDD持久化數據在Executor內存中能占的比例,默認是0.6。也就是說,默認Executor 60%的內存,可以用來保存持久化的RDD數據。根據你選擇的不同的持久化策略,如果內存不夠時,可能數據就不會持久化,或者數據會寫入磁盤。
  • 參數調優建議:如果Spark作業中,有較多的RDD持久化操作,該參數的值可以適當提高一些,保證持久化的數據能夠容納在內存中。避免內存不夠緩存所有的數據,導致數據只能寫入磁盤中,降低了性能。但是如果Spark作業中的shuffle類操作比較多,而持久化操作比較少,那么這個參數的值適當降低一些比較合適。此外,如果發現作業由于頻繁的gc導致運行緩慢(通過spark web ui可以觀察到作業的gc耗時),意味著task執行用戶代碼的內存不夠用,那么同樣建議調低這個參數的值。

spark.shuffle.memoryFraction

  • 參數說明:該參數用于設置shuffle過程中一個task拉取到上個stage的task的輸出后,進行聚合操作時能夠使用的Executor內存的比例,默認是0.2。也就是說,Executor默認只有20%的內存用來進行該操作。shuffle操作在進行聚合時,如果發現使用的內存超出了這個20%的限制,那么多余的數據就會溢寫到磁盤文件中去,此時就會極大地降低性能。
  • 參數調優建議:如果Spark作業中的RDD持久化操作較少,shuffle操作較多時,建議降低持久化操作的內存占比,提高shuffle操作的內存占比比例,避免shuffle過程中數據過多時內存不夠用,必須溢寫到磁盤上,降低了性能。此外,如果發現作業由于頻繁的gc導致運行緩慢,意味著task執行用戶代碼的內存不夠用,那么同樣建議調低這個參數的值。

資源參數的調優,沒有一個固定的值,需要同學們根據自己的實際情況(包括Spark作業中的shuffle操作數量、RDD持久化操作數量以及spark web ui中顯示的作業gc情況),同時參考本篇文章中給出的原理以及調優建議,合理地設置上述參數。

資源參數參考示例

以下是一份spark-submit命令的示例,大家可以參考一下,并根據自己的實際情況進行調節:

./bin/spark-submit \--master yarn-cluster \--num-executors 100 \--executor-memory 6G \--executor-cores 4 \--driver-memory 1G \--conf spark.default.parallelism=1000 \--conf spark.storage.memoryFraction=0.5 \--conf spark.shuffle.memoryFraction=0.3 \

根據實踐經驗來看,大部分Spark作業經過本次基礎篇所講解的開發調優與資源調優之后,一般都能以較高的性能運行了,足以滿足我們的需求。但是在不同的生產環境和項目背景下,可能會遇到其他更加棘手的問題(比如各種數據傾斜),也可能會遇到更高的性能要求。為了應對這些挑戰,需要使用更高級的技巧來處理這類問題。在后續的《Spark性能優化指南——高級篇》中,我們會詳細講解數據傾斜調優以及Shuffle調優。

總結

以上是生活随笔為你收集整理的Spark性能优化指南——基础篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久久高清av | 免费看黄色毛片 | 免费观看9x视频网站在线观看 | 国产精品久久久久一区二区国产 | 日韩视频欧美视频 | 福利网在线 | 国产福利av在线 | 日韩精品亚洲专区在线观看 | 免费观看丰满少妇做爰 | 国产黄色精品在线 | 99久久日韩精品视频免费在线观看 | 911国产精品 | 91精品国产91p65 | 欧美日韩在线观看一区二区三区 | 国产成人久久av免费高清密臂 | 奇米影视四色8888 | 少妇18xxxx性xxxx片 | 91亚洲视频在线观看 | 久草免费色站 | 国产一级性生活视频 | 成人小视频免费在线观看 | 日韩在线观看网址 | 制服丝袜欧美 | 亚洲精品免费观看视频 | 天天草综合网 | 久久在现视频 | 久久视了 | 欧美一区在线看 | 久久久黄视频 | 成年人在线观看视频免费 | 激情视频久久 | 国产成人一区二区精品非洲 | 久久免费视频4 | 成人av在线一区二区 | 视频国产区 | 欧美巨大荫蒂茸毛毛人妖 | 日本精品视频一区二区 | 久久久久久久免费观看 | 奇米先锋 | 一区在线观看 | 免费a网| 四虎在线免费观看视频 | 黄色日视频| 国产成人一区二区三区电影 | 国产精品一区二区三区免费视频 | 午夜精品视频福利 | 天天射天天爽 | 久久久av电影 | 99精品黄色| 亚洲三级在线 | 麻豆国产电影 | 99久在线精品99re8热视频 | 亚洲精品合集 | 国产在线看 | 天天做天天射 | 有码中文字幕在线观看 | 欧美激情精品久久久久久免费印度 | 在线视频观看91 | 一级黄色网址 | 欧美日韩高清一区二区 | 欧美日韩中文国产一区发布 | 亚洲综合色婷婷 | 婷婷六月久久 | 黄网站app在线观看免费视频 | 免费观看视频的网站 | 欧美成人性网 | 免费观看午夜视频 | 亚洲免费视频在线观看 | 国产精品自在线 | 蜜臀aⅴ国产精品久久久国产 | 免费观看91视频 | 国产手机在线 | 人人爽久久久噜噜噜电影 | 国产精品永久在线观看 | 久日视频| aⅴ视频在线| 在线观看mv的中文字幕网站 | 天天爱天天插 | 欧美在线观看禁18 | 亚洲精品一区二区三区高潮 | 91综合色| 久久综合五月天 | 国产麻豆视频免费观看 | 国产一级三级 | 亚洲激情一区二区三区 | 操碰av| 国产午夜一区 | 久久精品国产亚洲精品 | 日日夜夜精品视频天天综合网 | 激情丁香久久 | 色综合久久久久久中文网 | 久久亚洲免费 | 亚洲国产精品视频在线观看 | 日韩欧美国产视频 | 综合婷婷 | 亚洲国产人午在线一二区 | 日韩精品一区二区三区丰满 | 成年人视频在线 | 久久字幕网| 91mv.cool在线观看| 色a在线观看 | 成人国产网站 | 国产中文字幕网 | 在线观看视频日韩 | 国产区免费在线 | 最新一区二区三区 | 色九色 | 激情五月婷婷综合网 | 国产一级在线观看视频 | 免费a v在线| 91尤物国产尤物福利在线播放 | 激情五月婷婷综合网 | 国产中文欧美日韩在线 | 在线观看视频国产一区 | 伊人婷婷激情 | 免费看黄20分钟 | 国产成人综合精品 | 久久国产午夜精品理论片最新版本 | 在线免费色视频 | 中日韩三级视频 | 久久天堂亚洲 | 成人久久18免费网站麻豆 | 久久99国产精品久久99 | jizz欧美性9 国产一区高清在线观看 | 亚洲午夜精品久久久久久久久久久久 | 国产三级在线播放 | 国产精品成人一区二区三区吃奶 | 欧美在线一| 成人免费一级片 | 成人毛片在线观看视频 | 超碰精品在线 | 免费成人在线观看视频 | 久久久久综合精品福利啪啪 | 一本一道久久a久久综合蜜桃 | 国产精品久久久久久久久久三级 | 欧美国产日韩激情 | 国产精品美女视频 | 国产亚洲高清视频 | 精品久久久久久国产偷窥 | 久久99久国产精品黄毛片入口 | aaa日本高清在线播放免费观看 | 欧美最爽乱淫视频播放 | 欧美性做爰猛烈叫床潮 | 国产成人亚洲在线观看 | www91在线观看 | 精品国产_亚洲人成在线 | 中文字幕在线观看视频网站 | 久久99国产精品视频 | 97色婷婷成人综合在线观看 | 中文字幕av一区二区三区四区 | 国产超碰在线观看 | 国产日韩欧美在线观看 | 亚洲女在线 | 97av在线视频免费播放 | 免费色网站 | 超碰97人人射妻 | 久久蜜臀一区二区三区av | 一级一片免费看 | 91九色在线观看视频 | 亚洲精品久久久久中文字幕二区 | 久草香蕉在线 | 人人干人人超 | 色大片免费看 | 91丨九色丨国产在线观看 | 最近更新好看的中文字幕 | 婷婷精品 | 91精品啪在线观看国产线免费 | 特及黄色片| 国产精品9999久久久久仙踪林 | 黄色三级在线观看 | 美女av免费看 | 69国产精品成人在线播放 | 91精品在线视频观看 | 国产91免费观看 | 久久精品导航 | 免费看v片| 亚洲动漫在线观看 | 亚洲精品综合一二三区在线观看 | 久久久久这里只有精品 | 91精品婷婷国产综合久久蝌蚪 | 国产三级午夜理伦三级 | 在线精品亚洲 | 久久久久色 | 91丨九色丨首页 | 国产精品不卡一区 | 成人av电影网址 | 日韩久久视频 | 草久在线观看 | 国产99在线播放 | av大全在线| 97色资源 | 久久avav | 久久少妇免费视频 | 国产精品原创在线 | 日韩精品一区二区在线观看视频 | 中文在线字幕免费观看 | 337p西西人体大胆瓣开下部 | 国产精品 欧美 日韩 | 成年人在线| 日韩欧美高清视频在线观看 | 亚洲天堂精品视频 | 夜夜夜夜夜夜操 | 天天色天天干天天色 | 99久久这里只有精品 | 亚洲视频久久久久 | 国产色视频一区二区三区qq号 | 在线视频麻豆 | 精品亚洲免费 | 国产美女在线免费观看 | 伊人va | 九九热视频在线 | 中文字幕无吗 | 日韩成人高清在线 | 午夜精品一区二区三区在线观看 | 91亚洲精品在线观看 | 中文字幕久久亚洲 | 国产精品久久久久久久久婷婷 | 波多野结衣在线视频免费观看 | 久久99热这里只有精品国产 | 亚洲欧美日韩不卡 | 欧美影院久久 | 九九热av | 四虎视频| 999久久久久久久久 69av视频在线观看 | 综合av在线 | 成人免费一区二区三区在线观看 | 97碰碰碰| 黄色小说网站在线 | 婷婷在线资源 | 日韩精品一区二区三区中文字幕 | 中文字幕中文字幕在线中文字幕三区 | 欧美 激情 国产 91 在线 | 九九在线高清精品视频 | 国产在线观看你懂的 | 18久久久久| 91在线观看视频网站 | 中文字幕第 | 午夜精品久久久久 | 久草视频免费播放 | 久久乐九色婷婷综合色狠狠182 | 亚洲黄色免费在线 | www.五月天婷婷.com | 欧美极品少妇xbxb性爽爽视频 | 免费av片在线 | 国产亚洲人| 欧美大荫蒂xxx | 欧美激情精品久久久久久变态 | 久操中文字幕在线观看 | 天天躁日日躁狠狠 | 欧美极品一区二区三区 | 91av视频在线免费观看 | 国产在线观看99 | 久久一区二区三区四区 | 欧美三级高清 | 日韩av看片| 欧美最爽乱淫视频播放 | 日韩欧美观看 | 精品视频在线免费 | 啪嗒啪嗒免费观看完整版 | www日韩视频| 久久超碰99 | 精品国产伦一区二区三区免费 | 国产一区二区三区四区在线 | 中文字幕乱码电影 | 国产精品日韩在线 | 日韩三级中文字幕 | av先锋影音少妇 | 在线免费观看羞羞视频 | bbbbb女女女女女bbbbb国产 | 欧洲精品亚洲精品 | 深爱婷婷 | 麻豆一精品传二传媒短视频 | 国产精品网在线观看 | 操操操日日日 | 亚洲一区网 | 日韩中文在线播放 | 久久精品99久久久久久2456 | 天天操天天干天天爽 | 免费看国产黄色 | 国产亚洲视频在线 | 国内视频 | 久草手机视频 | 中文字幕在线观看视频免费 | 日韩欧美在线第一页 | a级片久久久 | 日韩欧美视频免费在线观看 | 免费人成在线观看网站 | 成人a免费看 | 2018好看的中文在线观看 | 69国产盗摄一区二区三区五区 | 亚洲精品欧美成人 | 午夜精品久久久久久中宇69 | 黄色官网在线观看 | 伊人久久五月天 | 叶爱av在线| 99精品免费在线 | 97色噜噜 | 午夜视频亚洲 | 日日爽| 国产九色在线播放九色 | 国产一区免费 | 一区二区三区在线观看 | 在线观看成人网 | 黄a在线观看 | 中文在线天堂资源 | 亚洲一区二区三区毛片 | 国产一区二区在线免费 | 一区精品在线 | 中文视频在线 | 国产精品久久久久久久久久东京 | 日韩在线一区二区免费 | 成人宗合网 | 国产精品成人aaaaa网站 | 超碰99人人| 成人91在线| 91社区国产高清 | 四虎在线免费观看 | 日韩中文字幕免费视频 | japanesexxxxfreehd乱熟 | 麻豆视频免费入口 | 久久视频一区 | 久草99| 免费网站在线观看成人 | 中文国产成人精品久久一 | 亚洲精品一区二区网址 | 日韩精品一区在线观看 | 亚洲精品啊啊啊 | 久久视频在线免费观看 | 国产精品国产毛片 | 亚洲va欧美va人人爽春色影视 | 激情亚洲综合在线 | 国产美女在线精品免费观看 | 成人免费网站视频 | 日本精品视频免费观看 | 91视频网址入口 | 99视频国产精品免费观看 | 毛片888 | 日韩精品你懂的 | 久久久精品 一区二区三区 国产99视频在线观看 | 久久视频在线免费观看 | 国产午夜精品在线 | 西西人体4444www高清视频 | 欧美国产大片 | www国产亚洲精品久久麻豆 | 国产精品大全 | 国产精品丝袜久久久久久久不卡 | 日韩性xxxx| 日日夜夜狠狠操 | 色婷婷99| 国模吧一区 | 久草手机视频 | 国产区精品区 | 日日夜操 | 免费久久99精品国产婷婷六月 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 成人一区二区三区在线观看 | 97在线成人 | 国产精品成人一区二区 | 中文字幕有码在线 | 日韩高清不卡一区二区三区 | 中文字幕人成不卡一区 | 在线观看午夜av | 日躁夜躁狠狠躁2001 | 欧美精品xxx | 欧美性成人 | 色是在线视频 | 国产精品尤物 | av无限看 | 欧美日韩在线精品一区二区 | 99热只有精品在线观看 | 亚州国产视频 | 国产 日韩 在线 亚洲 字幕 中文 | 99精品免费久久久久久久久日本 | 久久99精品国产一区二区三区 | 亚洲精品免费看 | 久久久久一区二区三区四区 | 久久福利 | 成人小视频免费在线观看 | 九九免费观看全部免费视频 | 久色小说| 国产黄色片一级三级 | 亚洲激情在线视频 | 久久99精品久久久久久久久久久久 | 日韩av黄 | 国产精品99久久久久久人免费 | 伊人色播| 在线看岛国av | 亚洲情婷婷 | 色婷婷色| 国产精品一区二区av麻豆 | 久久九九精品久久 | 九九日九九操 | 久久综合色8888 | av一区二区在线观看中文字幕 | 丁香高清视频在线看看 | 国产麻豆成人传媒免费观看 | 成人午夜电影免费在线观看 | 久草影视在线 | 狠狠躁夜夜av | 午夜久久福利影院 | 麻豆精品国产传媒 | 狠狠狠狠狠操 | 国产精品视频永久免费播放 | 五月婷婷六月丁香激情 | 久久99九九99精品 | 国产精品都在这里 | 精品国产一区二区三区男人吃奶 | 日韩精品中字 | 日韩精品一区二区三区三炮视频 | 精品国产中文字幕 | 国产五月天婷婷 | 免费三级网 | 精品国产一区二区三区在线 | 国产女人18毛片水真多18精品 | 色婷婷电影网 | 日韩视频www | 色在线免费观看 | 91在线看黄 | 久久视讯| 中文在线免费看视频 | www视频在线播放 | 亚洲久在线| 韩国在线一区二区 | 久久99国产精品免费网站 | 国产操在线 | 亚洲欧美精品一区二区 | 91免费观看视频网站 | 日韩精品一区二区在线观看 | 天天射日 | 成人91在线| 97在线观看免费观看高清 | 在线国产视频观看 | 日日操日日操 | www激情网 | 丁香电影小说免费视频观看 | 色综合天天干 | 啪啪午夜免费 | 亚洲激情综合 | 精品一区二区免费视频 | 97色在线观看 | 亚州激情视频 | av在线免费网| 日日碰夜夜爽 | 西西444www大胆无视频 | 亚洲激情一区二区三区 | 国语精品视频 | 2019中文字幕第一页 | 91国内在线视频 | 天天躁日日躁狠狠躁av麻豆 | 欧美一级电影片 | 亚洲成人高清在线 | 999国产精品视频 | 91最新中文字幕 | 999精品在线| 国产黄色片久久 | 亚洲在线视频观看 | 久久开心激情 | 久久99精品久久久久久秒播蜜臀 | 天天色天天射天天干 | 国产一区二区中文字幕 | 欧洲亚洲女同hd | 亚洲一区视频免费观看 | 日韩精品一区二区在线 | 精品二区久久 | 国产黄色片久久 | 精品国产乱码久久久久久1区2匹 | 日韩高清一区二区 | 亚洲精品视频在线观看免费视频 | 在线观看一区二区精品 | 91视频一8mav| 五月天视频网 | 国产精品2018| 亚洲爱视频 | 视频一区二区免费 | 日韩欧美黄色网址 | 免费观看的黄色片 | 国产免费观看高清完整版 | 日本精品久久久久中文字幕 | 麻豆一级视频 | 高清av在线| 伊人色综合网 | 国产精品9999久久久久仙踪林 | 四虎影视av | 日韩精品在线观看av | 91人人爽人人爽人人精88v | 一区二区三区四区精品视频 | 国产精品综合在线 | 一二三区av | 亚洲精品男女 | 久久久久女人精品毛片九一 | 国产视频在线观看一区 | 日韩在线观看网站 | 91精品久久久久久综合乱菊 | 亚洲综合色激情五月 | 中文字幕亚洲不卡 | 色偷偷人人澡久久超碰69 | 日韩国产精品久久久久久亚洲 | 欧美日韩在线免费观看 | 欧美乱码精品一区 | 一区二区三区在线观看 | 黄色网大全| 91视频电影 | 日韩精品一区二区三区丰满 | 特级a毛片| 日韩免费视频线观看 | 四虎8848免费高清在线观看 | 色老板在线视频 | 日韩一区二区三区免费视频 | 成人h在线 | 中文字幕精品一区二区精品 | 免费观看的av | 少妇性xxx | 成人资源在线观看 | 免费男女羞羞的视频网站中文字幕 | 成人黄色大片 | 免费看三级网站 | 精品久久久一区二区 | 免费在线观看黄 | 狠狠操夜夜操 | 国产第一页在线观看 | 激情久久伊人 | 欧美日韩国产精品久久 | 又黄又爽的视频在线观看网站 | 97av在线视频免费播放 | 亚洲日日日 | 国产91精品久久久久久 | 久久免费国产电影 | 中文av资源站 | 国产午夜精品免费一区二区三区视频 | 国产福利免费看 | 日韩三级视频在线观看 | 香蕉视频免费在线播放 | 国内久久久久 | 婷婷综合导航 | 精品久久视频 | 欧美日韩国产精品一区二区 | av品善网 | 西西大胆免费视频 | 成片视频在线观看 | 97天堂网 | 国产在线免费观看 | 国产在线2020 | 亚洲欧美日韩精品一区二区 | 欧美一区二区三区在线观看 | 最近的中文字幕大全免费版 | 国产精品18毛片一区二区 | 在线天堂亚洲 | 久久综合狠狠狠色97 | 综合色综合 | 黄色www| 欧美午夜久久久 | 国产一级久久 | 在线免费观看国产视频 | 精品一区二区在线观看 | 国产精品久久久久一区二区三区共 | 激情综合色综合久久综合 | 欧美精品久久久久久久久久白贞 | 久久亚洲人 | 黄色免费电影网站 | 黄色av电影网| 日韩电影在线一区 | 国产高清精 | 一区二区中文字幕在线 | 国产一二三四在线视频 | 国产精彩视频一区二区 | 黄色小说在线免费观看 | 视频 天天草 | av片一区| 黄色影院在线免费观看 | 香蕉成人在线视频 | 日韩美一区二区三区 | 欧美 日韩 国产 中文字幕 | 国产中文视频 | 色婷婷亚洲精品 | 免费亚洲视频在线观看 | 久草在线视频看看 | 日韩午夜一级片 | 亚洲黄色免费观看 | 中文资源在线播放 | 天天操天天操天天操天天操天天操天天操 | 伊人电影天堂 | 91av在线视频播放 | 天天射夜夜爽 | 97精产国品一二三产区在线 | av资源在线看 | 日韩视| 亚洲久草视频 | 国产成人精品国内自产拍免费看 | 亚洲精品免费在线观看视频 | 亚洲精品激情 | 国产精品免费一区二区 | 干av在线 | 91看片一区二区三区 | 中文字幕av在线免费 | 国产精品视频最多的网站 | 在线观看一区二区视频 | 夜夜骑天天操 | 六月丁香婷婷久久 | 欧美另类一二三四区 | 一区二区精品视频 | 91中文字幕在线播放 | 国产精品久久久久久一二三四五 | 日日爱影视 | 久久久人人人 | 最近中文字幕第一页 | 偷拍精偷拍精品欧洲亚洲网站 | a级片韩国| 久久久久久综合 | 999国产在线| 91色九色 | 亚洲国产一区二区精品专区 | 夜夜爱av| 精品9999| 久久久久欠精品国产毛片国产毛生 | 极品美女被弄高潮视频网站 | 欧美天堂影院 | 综合天天网 | 久草视频免费在线播放 | 久久国产精品视频观看 | 国语久久| 色久综合 | 国产成人在线播放 | 亚洲精品视频二区 | 九草视频在线 | 色综合久久88色综合天天6 | 国产黄色理论片 | 国产一级二级在线观看 | 精品久久网| 久久超级碰视频 | 国产成人精品一区二三区 | 最新超碰在线 | 91专区在线观看 | 亚洲精品在线资源 | 久久伊人精品天天 | 欧美在线观看视频一区二区 | 中文字幕亚洲精品日韩 | 免费精品在线 | 91精品国产高清自在线观看 | 国产精品 中文字幕 亚洲 欧美 | 欧美日韩不卡一区二区三区 | 成人福利在线观看 | 奇米影视在线99精品 | 日韩在线免费视频观看 | 国产精品视频永久免费播放 | 国产精品国产三级在线专区 | 国产精品毛片一区视频播 | 亚洲五月六月 | 久久成人午夜 | 欧美一区二区在线刺激视频 | 成人黄色资源 | 欧美性生活免费看 | 美女视频久久 | 国产自产在线视频 | 少妇bbb | 日日干av | 91免费在线看片 | 国产福利一区二区在线 | 日韩av在线看 | 99久久久国产精品免费99 | 最近2019好看的中文字幕免费 | 麻豆久久久久久久 | 久久不射电影院 | 国产综合91 | 在线免费高清视频 | 婷婷丁香视频 | av在线h| 国产精品a久久久久 | 五月天激情综合网 | 亚洲成人影音 | 欧美日韩不卡在线 | 亚洲首页| 91网在线看 | 一本一本久久a久久精品综合妖精 | 麻豆一级视频 | 亚洲欧美日韩国产精品一区午夜 | 亚洲视频在线视频 | 久久久久亚洲精品男人的天堂 | 亚洲国产无 | 二区中文字幕 | 高清av免费一区中文字幕 | 日韩一区二区免费在线观看 | 免费精品视频在线观看 | 在线观看av中文字幕 | 国产福利中文字幕 | 干干干操操操 | 亚洲精品毛片一级91精品 | 成人性生交大片免费观看网站 | 亚洲电影第一页av | 精品亚洲成a人在线观看 | 久久99国产精品久久99 | 久久综合精品一区 | 一级黄色片在线观看 | 国产精品人成电影在线观看 | 黄色成人小视频 | 91高清免费观看 | 亚洲国产精品99久久久久久久久 | 毛片在线网 | 99精品偷拍视频一区二区三区 | 99综合电影在线视频 | 国产亚洲午夜高清国产拍精品 | 天天插伊人 | 成人av高清在线观看 | 日韩精品免费专区 | 91丨九色丨高潮丰满 | 亚洲精品免费在线播放 | 久久www免费人成看片高清 | 中文字幕在线观看视频一区二区三区 | 欧美福利视频一区 | 久久a久久 | 国产 日韩 欧美 中文 在线播放 | 日本精品久久久久中文字幕 | 天天天干天天天操 | 午夜精品一区二区三区免费视频 | 精品91久久久久 | 国产精品一区二区久久久久 | 国产精品婷婷 | 中文字幕综合在线 | 国产高清在线观看 | 91九色免费视频 | 亚洲精品五月 | 国产a视频免费观看 | 丁香婷婷激情啪啪 | 久草综合在线观看 | 久久五月婷婷丁香社区 | 又黄又爽又无遮挡免费的网站 | 久草视频国产 | 天天天综合网 | 国产女教师精品久久av | 国产亚洲午夜高清国产拍精品 | 免费高清在线观看成人 | 亚洲欧美视频网站 | 国产视频一级 | 欧美极品xxxxx | 日韩欧美在线视频一区二区三区 | 成人在线观看你懂的 | 日韩成人在线免费观看 | 久久99久国产精品黄毛片入口 | 天天在线操 | 国产在线视频不卡 | 欧美精品在线观看免费 | 就要色综合 | 免费在线观看一级片 | 久久理伦片 | 精品毛片一区二区免费看 | 久久久久久久久久久网站 | 日韩综合精品 | 91看片网址 | 久久精品视频观看 | 午夜精品在线看 | 奇米影视在线99精品 | 一 级 黄 色 片免费看的 | 国产不卡在线 | 国产剧情一区二区 | 国产高清av免费在线观看 | 亚洲精品字幕在线 | 欧美一级片播放 | 伊人天天操| 99久久er热在这里只有精品66 | 天堂av在线网址 | 国产在线探花 | 日韩精品一区二区三区高清免费 | 99日精品| 在线国产视频 | 久久久久久网址 | 中文一区在线观看 | 日日夜夜精品免费观看 | 日日夜夜精品免费视频 | 天天操天天干天天干 | 婷婷久久亚洲 | 久久国产高清 | 国产在线观看你懂得 | 国产三级精品三级在线观看 | 国产手机在线视频 | 色全色在线资源网 | 久久色在线播放 | 国产免费久久 | 国产婷婷精品av在线 | 波多野结衣一区 | 国产精品久久久久久久久久久杏吧 | 国产高清不卡 | 黄色a级片在线观看 | 国内精品久久久久久久影视麻豆 | 国产精品免费久久久久 | 正在播放 久久 | 色狠狠婷婷 | 草久视频在线观看 | 亚洲在线观看av | 69国产盗摄一区二区三区五区 | 亚洲午夜精品久久久 | 日韩色区 | 人人干人人超 | 日韩一级片网址 | 蜜臀av夜夜澡人人爽人人桃色 | 看污网站 | 国产美腿白丝袜足在线av | 天天狠狠操 | 99亚洲国产 | 国产成人一区三区 | 欧美一性一交一乱 | 色婷婷久久| 在线看一区二区 | av在线8| 手机看片1042 | 黄色av大片 | 日韩丝袜 | 午夜美女福利 | 五月天久久久久 | 欧美激情视频一二三区 | 91探花在线 | 久久久久久久网站 | 狠狠干.com | 国内精品在线一区 | 综合网婷婷 | 欧美一二三视频 | 中文视频在线播放 | 精品久久一区二区 | 热久久在线视频 | 日韩中文字幕视频在线观看 | 日本性久久 | 久久艹中文字幕 | 午夜国产一区二区三区四区 | 亚洲日本在线一区 | 国产精品亚洲精品 | 亚洲视频综合在线 | 精品久久久久久久久久久院品网 | 国产精品中文字幕在线播放 | 久久国产成人午夜av影院宅 | 午夜精品久久久久久久99无限制 | 中文字幕免费观看全部电影 | 亚洲激色 | 天天色宗合| 日日夜夜操av | av在线之家电影网站 | 手机av在线网站 | 又黄又刺激的视频 | 久久精品区 | 九九久久精品视频 | 久久久99精品免费观看app | 免费日韩 精品中文字幕视频在线 | 久久九九国产视频 | 日韩超碰在线 | 黄色av一级 | 亚洲精品 在线视频 | 嫩嫩影院理论片 | av不卡中文字幕 | 手机在线小视频 | 欧美一区日韩精品 | 国产成人精品女人久久久 | 国产一卡久久电影永久 | 深爱激情综合 | 91精品欧美一区二区三区 | 中文不卡视频在线 | 伊人色播 | 久久精品电影院 | 国产一级视频 | 丰满少妇麻豆av | 激情综合六月 | 97av影院| 色视频网站在线观看一=区 a视频免费在线观看 | 亚洲国产中文字幕在线观看 | 在线观看视频亚洲 | 成人欧美一区二区三区在线观看 | 久视频在线 | 国产一区av在线 | 婷婷六月在线 | 国产成人免费 | 91av中文 | 色婷婷亚洲综合 | 日韩在线色 | 99色在线| 久久99日韩 | 97狠狠干 | 精品国产欧美一区二区 | 在线精品在线 | 国产精品精品视频 | 99精品国产福利在线观看免费 | 久久精品国产亚洲aⅴ | av一级久久 | 国产免费视频一区二区裸体 | 精品国产一区二区在线 | 欧美少妇的秘密 | 日韩a级免费视频 | 黄色精品在线看 | 久久精品牌麻豆国产大山 | 五月天伊人 | 久久艹精品 | www.五月天色 | 日韩欧美视频免费观看 | 最近最新中文字幕 | 久久成人高清 | 精品福利在线视频 | 中文字幕在线一区观看 | 一区二区三区在线不卡 | 99九九免费视频 | 免费网站在线观看成人 | 久久久国产精品一区二区中文 | 玖草在线观看 | 久久蜜臀一区二区三区av | 国产又黄又爽又猛视频日本 | 中文av日韩 | 久久99视频免费 | 日韩欧美视频一区二区 | 成人一级片免费看 | 免费av片在线 | 久久久久久久久久免费 | 亚洲经典视频 | 成人毛片一区二区三区 | 91精品国产欧美一区二区成人 | 日本最新中文字幕 | 在线观看的av网站 | 欧美一区二区三区在线观看 | 在线看小早川怜子av | 视频在线观看入口黄最新永久免费国产 | 成人动漫一区二区三区 | 欧美另类亚洲 | 麻豆国产精品永久免费视频 | 激情 亚洲 | 美女免费网视频 | 人人精久 | 欧美污污视频 | a级片久久久 | 国产精品mv | av综合在线观看 | 狠狠色噜噜狠狠狠狠 | a天堂在线看 | 四虎成人精品永久免费av九九 | 色婷婷中文 | 日日躁夜夜躁aaaaxxxx | 视频二区 | 色老板在线| 五月婷久 | 婷婷丁香花五月天 | 久热色超碰 | 国产一二三在线视频 | 福利精品在线 | 欧美91在线 | 久久久.com| 日韩在线免费播放 | 欧美性久久久久久 | 国产手机视频在线观看 | 人人超碰免费 | 蜜臀久久99精品久久久久久网站 | 国产又黄又爽又猛视频日本 | 麻豆va一区二区三区久久浪 | 日韩在线视频一区 | 国产亚洲成人网 | 麻豆va一区二区三区久久浪 | 久久久久久欧美二区电影网 | 日韩免费中文字幕 | 日本精品视频网站 | 99久久精品久久久久久动态片 | 国产理论在线 | 国产成人精品福利 | 亚a在线 | 久久精品一区二区国产 | 中文字幕在线日亚洲9 | 99理论片 | 久久这里只有精品23 | 日韩高清一区在线 | 天天爽天天做 | 久草视频中文 | 中文字幕高清有码 | 夜夜澡人模人人添人人看 | www麻豆视频 | 免费看三级黄色片 | 天天综合网 天天综合色 | 五月婷av | 久久电影中文字幕视频 | av千婊在线免费观看 | 一区二区三区四区五区在线 | www.伊人色.com| 亚洲一区精品二人人爽久久 | 91香蕉嫩草| 一区二区三区四区在线免费观看 | 夜夜摸夜夜爽 | 亚洲精品黄色片 | 国产高清久久 | 久久婷婷国产色一区二区三区 | 欧美aaaxxxx做受视频 | 91亚洲精品久久久中文字幕 | 日韩91精品| 日韩精品一区二区三区水蜜桃 | 久久精品伊人 | 综合久久2023 | 免费在线观看成人 | 亚洲在线精品 | 久久日本视频 | 国产高清不卡av | 在线观看国产成人av片 | av 一区二区三区四区 | 久久免费视频在线观看6 | 国产精美视频 | 亚洲成人精品在线 | 手机在线观看国产精品 | 天天插天天爱 | 午夜在线看 | 国产欧美三级 | 日韩免费电影一区二区三区 |