精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Adaptive Execution 讓 Spark SQL 更智能更高效

大數據 Spark
本文介紹的 Adaptive Execution 將可以根據執行過程中的中間數據優化后續執行,從而提高整體執行效率。核心在于兩點,執行計劃可動態調整、調整的依據是中間結果的精確統計信息。

本文轉發自技術世界,原文鏈接 http://www.jasongj.com/spark/adaptive_execution/

1 背景

前面《Spark SQL / Catalyst 內部原理 與 RBO》與《Spark SQL 性能優化再進一步 CBO 基于代價的優化》介紹的優化,從查詢本身與目標數據的特點的角度盡可能保證了最終生成的執行計劃的高效性。但是執行計劃一旦生成,便不可更改,即使執行過程中發現后續執行計劃可以進一步優化,也只能按原計劃執行。

CBO 基于統計信息生成***執行計劃,需要提前生成統計信息,成本較大,且不適合數據更新頻繁的場景。

CBO 基于基礎表的統計信息與操作對數據的影響推測中間結果的信息,只是估算,不夠精確。

本文介紹的 Adaptive Execution 將可以根據執行過程中的中間數據優化后續執行,從而提高整體執行效率。核心在于兩點:

  • 執行計劃可動態調整
  • 調整的依據是中間結果的精確統計信息

2 動態設置 Shuffle Partition

2.1 Spark Shuffle 原理

Spark Shuffle 一般用于將上游 Stage 中的數據按 Key 分區,保證來自不同 Mapper (表示上游 Stage 的 Task)的相同的 Key 進入相同的 Reducer (表示下游 Stage 的 Task)。一般用于 group by 或者 Join 操作。 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark Shuffle 過程

 

如上圖所示,該 Shuffle 總共有 2 個 Mapper 與 5 個 Reducer。每個 Mapper 會按相同的規則(由 Partitioner 定義)將自己的數據分為五份。每個 Reducer 從這兩個 Mapper 中拉取屬于自己的那一份數據。

2.2 原有 Shuffle 的問題

使用 Spark SQL 時,可通過 spark.sql.shuffle.partitions 指定 Shuffle 時 Partition 個數,也即 Reducer 個數。

該參數決定了一個 Spark SQL Job 中包含的所有 Shuffle 的 Partition 個數。如下圖所示,當該參數值為 3 時,所有 Shuffle 中 Reducer 個數都為 3。 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL with multiple Shuffle

 

這種方法有如下問題:

  • Partition 個數不宜設置過大
  • Reducer(代指 Spark Shuffle 過程中執行 Shuffle Read 的 Task) 個數過多,每個 Reducer 處理的數據量過小。大量小 Task 造成不必要的 Task 調度開銷與可能的資源調度開銷(如果開啟了 Dynamic Allocation)
  • Reducer 個數過大,如果 Reducer 直接寫 HDFS 會生成大量小文件,從而造成大量 addBlock RPC,Name node 可能成為瓶頸,并影響其它使用 HDFS 的應用
  • 過多 Reducer 寫小文件,會造成后面讀取這些小文件時產生大量 getBlock RPC,對 Name node 產生沖擊
  • Partition 個數不宜設置過小
  • 每個 Reducer 處理的數據量太大,Spill 到磁盤開銷增大
  • Reducer GC 時間增長
  • Reducer 如果寫 HDFS,每個 Reducer 寫入數據量較大,無法充分發揮并行處理優勢
  • 很難保證所有 Shuffle 都***
  • 不同的 Shuffle 對應的數據量不一樣,因此***的 Partition 個數也不一樣。使用統一的 Partition 個數很難保證所有 Shuffle 都***
  • 定時任務不同時段數據量不一樣,相同的 Partition 數設置無法保證所有時間段執行時都***

2.3 自動設置 Shuffle Partition 原理

如 Spark Shuffle 原理 一節圖中所示,Stage 1 的 5 個 Partition 數據量分別為 60MB,40MB,1MB,2MB,50MB。其中 1MB 與 2MB 的 Partition 明顯過小(實際場景中,部分小 Partition 只有幾十 KB 及至幾十字節)。

開啟 Adaptive Execution 后

  • Spark 在 Stage 0 的 Shuffle Write 結束后,根據各 Mapper 輸出,統計得到各 Partition 的數據量,即 60MB,40MB,1MB,2MB,50MB。
  • 通過 ExchangeCoordinator 計算出合適的 post-shuffle Partition 個數(即 Reducer)個數(本例中 Reducer 個數設置為 3)。
  • 啟動相應個數的 Reducer 任務。
  • 每個 Reducer 讀取一個或多個 Shuffle Write Partition 數據(如下圖所示,Reducer 0 讀取 Partition 0,Reducer 1 讀取 Partition 1、2、3,Reducer 2 讀取 Partition 4)。 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL adaptive reducer 1

 

三個 Reducer 這樣分配是因為:

  • targetPostShuffleInputSize 默認為 64MB,每個 Reducer 讀取數據量不超過 64MB
  • 如果 Partition 0 與 Partition 2 結合,Partition 1 與 Partition 3 結合,雖然也都不超過 64 MB。但讀完 Partition 0 再讀 Partition 2,對于同一個 Mapper 而言,如果每個 Partition 數據比較少,跳著讀多個 Partition 相當于隨機讀,在 HDD 上性能不高
  • 目前的做法是只結合相臨的 Partition,從而保證順序讀,提高磁盤 IO 性能
  • 該方案只會合并多個小的 Partition,不會將大的 Partition 拆分,因為拆分過程需要引入一輪新的 Shuffle
  • 基于上面的原因,默認 Partition 個數(本例中為 5)可以大一點,然后由 ExchangeCoordinator 合并。如果設置的 Partition 個數太小,Adaptive Execution 在此場景下無法發揮作用

由上圖可見,Reducer 1 從每個 Mapper 讀取 Partition 1、2、3 都有三根線,是因為原來的 Shuffle 設計中,每個 Reducer 每次通過 Fetch 請求從一個特定 Mapper 讀數據時,只能讀一個 Partition 的數據。也即在上圖中,Reducer 1 讀取 Mapper 0 的數據,需要 3 輪 Fetch 請求。對于 Mapper 而言,需要讀三次磁盤,相當于隨機 IO。

為了解決這個問題,Spark 新增接口,一次 Shuffle Read 可以讀多個 Partition 的數據。如下圖所示,Task 1 通過一輪請求即可同時讀取 Task 0 內 Partition 0、1 和 2 的數據,減少了網絡請求數量。同時 Mapper 0 一次性讀取并返回三個 Partition 的數據,相當于順序 IO,從而提升了性能。 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL adaptive reducer 2

 

由于 Adaptive Execution 的自動設置 Reducer 是由 ExchangeCoordinator 根據 Shuffle Write 統計信息決定的,因此即使在同一個 Job 中不同 Shuffle 的 Reducer 個數都可以不一樣,從而使得每次 Shuffle 都盡可能***。

上文 原有 Shuffle 的問題 一節中的例子,在啟用 Adaptive Execution 后,三次 Shuffle 的 Reducer 個數從原來的全部為 3 變為 2、4、3。 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL with adaptive Shuffle

 

2.4 使用與優化方法

可通過 spark.sql.adaptive.enabled=true 啟用 Adaptive Execution 從而啟用自動設置 Shuffle Reducer 這一特性。

通過 spark.sql.adaptive.shuffle.targetPostShuffleInputSize 可設置每個 Reducer 讀取的目標數據量,其單位是字節,默認值為 64 MB。上文例子中,如果將該值設置為 50 MB,最終效果仍然如上文所示,而不會將 Partition 0 的 60MB 拆分。具體原因上文已說明。

3 動態調整執行計劃

3.1 固定執行計劃的不足

在不開啟 Adaptive Execution 之前,執行計劃一旦確定,即使發現后續執行計劃可以優化,也不可更改。如下圖所示,SortMergJoin 的 Shuffle Write 結束后,發現 Join 一方的 Shuffle 輸出只有 46.9KB,仍然繼續執行 SortMergeJoin。

 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL with fixed DAG

 

此時完全可將 SortMergeJoin 變更為 BroadcastJoin 從而提高整體執行效率。

3.2 SortMergeJoin 原理

SortMergeJoin 是常用的分布式 Join 方式,它幾乎可使用于所有需要 Join 的場景。但有些場景下,它的性能并不是***的。

SortMergeJoin 的原理如下圖所示:

  • 將 Join 雙方以 Join Key 為 Key 按照 HashPartitioner 分區,且保證分區數一致
  • Stage 0 與 Stage 1 的所有 Task 在 Shuffle Write 時,都將數據分為 5 個 Partition,并且每個 Partition 內按 Join Key 排序
  • Stage 2 啟動 5 個 Task 分別去 Stage 0 與 Stage 1 中所有包含 Partition 分區數據的 Task 中取對應 Partition 的數據。(如果某個 Mapper 不包含該 Partition 的數據,則 Redcuer 無須向其發起讀取請求)。
  • Stage 2 的 Task 2 分別從 Stage 0 的 Task 0、1、2 中讀取 Partition 2 的數據,并且通過 MergeSort 對其進行排序
  • Stage 2 的 Task 2 分別從 Stage 1 的 Task 0、1 中讀取 Partition 2 的數據,且通過 MergeSort 對其進行排序
  • Stage 2 的 Task 2 在上述兩步 MergeSort 的同時,使用 SortMergeJoin 對二者進行 Join 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL SortMergeJoin

 

3.3 BroadcastJoin 原理

當參與 Join 的一方足夠小,可全部置于 Executor 內存中時,可使用 Broadcast 機制將整個 RDD 數據廣播到每一個 Executor 中,該 Executor 上運行的所有 Task 皆可直接讀取其數據。(本文中,后續配圖,為了方便展示,會將整個 RDD 的數據置于 Task 框內,而隱藏 Executor)

對于大 RDD,按正常方式,每個 Task 讀取并處理一個 Partition 的數據,同時讀取 Executor 內的廣播數據,該廣播數據包含了小 RDD 的全量數據,因此可直接與每個 Task 處理的大 RDD 的部分數據直接 Join。 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL BroadcastJoin

 

根據 Task 內具體的 Join 實現的不同,又可分為 BroadcastHashJoin 與 BroadcastNestedLoopJoin。后文不區分這兩種實現,統稱為 BroadcastJoin。

與 SortMergeJoin 相比,BroadcastJoin 不需要 Shuffle,減少了 Shuffle 帶來的開銷,同時也避免了 Shuffle 帶來的數據傾斜,從而極大地提升了 Job 執行效率。

同時,BroadcastJoin 帶來了廣播小 RDD 的開銷。另外,如果小 RDD 過大,無法存于 Executor 內存中,則無法使用 BroadcastJoin。

對于基礎表的 Join,可在生成執行計劃前,直接通過 HDFS 獲取各表的大小,從而判斷是否適合使用 BroadcastJoin。但對于中間表的 Join,無法提前準確判斷中間表大小從而精確判斷是否適合使用 BroadcastJoin。

《Spark SQL 性能優化再進一步 CBO 基于代價的優化》一文介紹的 CBO 可通過表的統計信息與各操作對數據統計信息的影響,推測出中間表的統計信息,但是該方法得到的統計信息不夠準確。同時該方法要求提前分析表,具有較大開銷。

而開啟 Adaptive Execution 后,可直接根據 Shuffle Write 數據判斷是否適用 BroadcastJoin。

3.4 動態調整執行計劃原理

如上文 SortMergeJoin 原理 中配圖所示,SortMergeJoin 需要先對 Stage 0 與 Stage 1 按同樣的 Partitioner 進行 Shuffle Write。

Shuffle Write 結束后,可從每個 ShuffleMapTask 的 MapStatus 中統計得到按原計劃執行時 Stage 2 各 Partition 的數據量以及 Stage 2 需要讀取的總數據量。(一般來說,Partition 是 RDD 的屬性而非 Stage 的屬性,本文為了方便,不區分 Stage 與 RDD。可以簡單認為一個 Stage 只有一個 RDD,此時 Stage 與 RDD 在本文討論范圍內等價)。

如果其中一個 Stage 的數據量較小,適合使用 BroadcastJoin,無須繼續執行 Stage 2 的 Shuffle Read。相反,可利用 Stage 0 與 Stage 1 的數據進行 BroadcastJoin,如下圖所示: 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL Auto BroadcastJoin

 

具體做法是

  • 將 Stage 1 全部 Shuffle Write 結果廣播出去
  • 啟動 Stage 2,Partition 個數與 Stage 0 一樣,都為 3
  • 每個 Stage 2 每個 Task 讀取 Stage 0 每個 Task 的 Shuffle Write 數據,同時與廣播得到的 Stage 1 的全量數據進行 Join

注:廣播數據存于每個 Executor 中,其上所有 Task 共享,無須為每個 Task 廣播一份數據。上圖中,為了更清晰展示為什么能夠直接 Join 而將 Stage 2 每個 Task 方框內都放置了一份 Stage 1 的全量數據

雖然 Shuffle Write 已完成,將后續的 SortMergeJoin 改為 Broadcast 仍然能提升執行效率

  • SortMergeJoin 需要在 Shuffle Read 時對來自 Stage 0 與 Stage 1 的數據進行 Merge Sort,并且可能需要 Spill 到磁盤,開銷較大
  • SortMergeJoin 時,Stage 2 的所有 Task 需要取 Stage 0 與 Stage 1 的所有 Task 的輸出數據(如果有它要的數據 ),會造成大量的網絡連接。且當 Stage 2 的 Task 較多時,會造成大量的磁盤隨機讀操作,效率不高,且影響相同機器上其它 Job 的執行效率
  • SortMergeJoin 時,Stage 2 每個 Task 需要從幾乎所有 Stage 0 與 Stage 1 的 Task 取數據,無法很好利用 Locality
  • Stage 2 改用 Broadcast,每個 Task 直接讀取 Stage 0 的每個 Task 的數據(一對一),可很好利用 Locality 特性。***在 Stage 0 使用的 Executor 上直接啟動 Stage 2 的 Task。如果 Stage 0 的 Shuffle Write 數據并未 Spill 而是在內存中,則 Stage 2 的 Task 可直接讀取內存中的數據,效率非常高。如果有 Spill,那可直接從本地文件中讀取數據,且是順序讀取,效率遠比通過網絡隨機讀數據效率高

3.5 使用與優化方法

該特性的使用方式如下

  • 當 spark.sql.adaptive.enabled 與 spark.sql.adaptive.join.enabled 都設置為 true 時,開啟 Adaptive Execution 的動態調整 Join 功能
  • spark.sql.adaptiveBroadcastJoinThreshold 設置了 SortMergeJoin 轉 BroadcastJoin 的閾值。如果不設置該參數,該閾值與 spark.sql.autoBroadcastJoinThreshold 的值相等
  • 除了本文所述 SortMergeJoin 轉 BroadcastJoin,Adaptive Execution 還可提供其它 Join 優化策略。部分優化策略可能會需要增加 Shuffle。spark.sql.adaptive.allowAdditionalShuffle 參數決定了是否允許為了優化 Join 而增加 Shuffle。其默認值為 false

4 自動處理數據傾斜

4.1 解決數據傾斜典型方案

《Spark性能優化之道——解決Spark數據傾斜(Data Skew)的N種姿勢》一文講述了數據傾斜的危害,產生原因,以及典型解決方法

  • 保證文件可 Split 從而避免讀 HDFS 時數據傾斜
  • 保證 Kafka 各 Partition 數據均衡從而避免讀 Kafka 引起的數據傾斜
  • 調整并行度或自定義 Partitioner 從而分散分配給同一 Task 的大量不同 Key
  • 使用 BroadcastJoin 代替 ReduceJoin 消除 Shuffle 從而避免 Shuffle 引起的數據傾斜
  • 對傾斜 Key 使用隨機前綴或后綴從而分散大量傾斜 Key,同時將參與 Join 的小表擴容,從而保證 Join 結果的正確性

4.2 自動解決數據傾斜

目前 Adaptive Execution 可解決 Join 時數據傾斜問題。其思路可理解為將部分傾斜的 Partition (傾斜的判斷標準為該 Partition 數據是所有 Partition Shuffle Write 中位數的 N 倍) 進行單獨處理,類似于 BroadcastJoin,如下圖所示: 

Adaptive Execution 讓 Spark SQL 更智能更高效

Spark SQL resolve joinm skew

 

在上圖中,左右兩邊分別是參與 Join 的 Stage 0 與 Stage 1 (實際應該是兩個 RDD 進行 Join,但如同上文所述,這里不區分 RDD 與 Stage),中間是獲取 Join 結果的 Stage 2

明顯 Partition 0 的數據量較大,這里假設 Partition 0 符合“傾斜”的條件,其它 4 個 Partition 未傾斜

以 Partition 對應的 Task 2 為例,它需獲取 Stage 0 的三個 Task 中所有屬于 Partition 2 的數據,并使用 MergeSort 排序。同時獲取 Stage 1 的兩個 Task 中所有屬于 Partition 2 的數據并使用 MergeSort 排序。然后對二者進行 SortMergeJoin

對于 Partition 0,可啟動多個 Task

  • 在上圖中,啟動了兩個 Task 處理 Partition 0 的數據,分別名為 Task 0-0 與 Task 0-1
  • Task 0-0 讀取 Stage 0 Task 0 中屬于 Partition 0 的數據
  • Task 0-1 讀取 Stage 0 Task 1 與 Task 2 中屬于 Partition 0 的數據,并進行 MergeSort
  • Task 0-0 與 Task 0-1 都從 Stage 1 的兩個 Task 中所有屬于 Partition 0 的數據
  • Task 0-0 與 Task 0-1 使用 Stage 0 中屬于 Partition 0 的部分數據與 Stage 1 中屬于 Partition 0 的全量數據進行 Join

通過該方法,原本由一個 Task 處理的 Partition 0 的數據由多個 Task 共同處理,每個 Task 需處理的數據量減少,從而避免了 Partition 0 的傾斜

對于 Partition 0 的處理,有點類似于 BroadcastJoin 的做法。但區別在于,Stage 2 的 Task 0-0 與 Task 0-1 同時獲取 Stage 1 中屬于 Partition 0 的全量數據,是通過正常的 Shuffle Read 機制實現,而非 BroadcastJoin 中的變量廣播實現

4.3 使用與優化方法

開啟與調優該特性的方法如下:

  • 將 spark.sql.adaptive.skewedJoin.enabled 設置為 true 即可自動處理 Join 時數據傾斜
  • spark.sql.adaptive.skewedPartitionMaxSplits 控制處理一個傾斜 Partition 的 Task 個數上限,默認值為 5
  • spark.sql.adaptive.skewedPartitionRowCountThreshold 設置了一個 Partition 被視為傾斜 Partition 的行數下限,也即行數低于該值的 Partition 不會被當作傾斜 Partition 處理。其默認值為 10L * 1000 * 1000 即一千萬
  • spark.sql.adaptive.skewedPartitionSizeThreshold設置了一個 Partition 被視為傾斜 Partition 的大小下限,也即大小小于該值的 Partition 不會被視作傾斜 Partition。其默認值為 64 * 1024 * 1024 也即 64MB
  • spark.sql.adaptive.skewedPartitionFactor 該參數設置了傾斜因子。如果一個 Partition 的大小大于 spark.sql.adaptive.skewedPartitionSizeThreshold的同時大于各 Partition 大小中位數與該因子的乘積,或者行數大于 spark.sql.adaptive.skewedPartitionRowCountThreshold 的同時大于各 Partition 行數中位數與該因子的乘積,則它會被視為傾斜的 Partition
責任編輯:未麗燕 來源: 大數據架構
相關推薦

2024-04-26 07:54:07

ZustandReact狀態管理庫

2025-04-29 08:20:51

2024-10-15 10:47:12

2009-06-19 10:16:10

巔峰訪談

2009-07-06 14:23:00

SSL VPNArray netwo

2016-09-29 13:44:23

數據中心

2018-05-08 14:58:07

戴爾

2024-12-20 16:41:22

2023-11-24 11:20:04

functoolsPython

2016-06-30 16:54:49

UCloud愛數云計算

2019-04-19 08:47:00

前端監控數據

2015-08-14 10:44:33

HTML5

2021-04-02 14:06:59

鑒釋科技劉新銘靜態代碼開發

2019-05-20 07:24:19

工業物聯網物聯網重型設備

2025-03-25 09:53:02

點贊
收藏

51CTO技術棧公眾號

久久视频在线看| 51午夜精品国产| 欧美重口乱码一区二区| 日本三级一区二区三区| 99久久99久久精品国产片果冰| 911精品国产一区二区在线| 日本一区午夜艳熟免费| 国产日本在线视频| 国产精品一区久久久久| 538国产精品一区二区免费视频| 五月激情四射婷婷| 视频成人永久免费视频| 91高清在线观看| 国产爆乳无码一区二区麻豆| 免费在线一级视频| 国产成人av自拍| 国产精品久久久久91| 人妻久久一区二区| 欧洲激情视频| 亚洲国产精品va在线看黑人动漫| 韩国视频一区二区三区| 2020日本在线视频中文字幕| 国产精品免费久久| 精品伦理一区二区三区| 国产美女免费视频| 日本免费新一区视频| 欧美精品电影在线| 黑人狂躁日本娇小| 精品国产91乱码一区二区三区四区 | 97人人澡人人爽| 一级特黄免费视频| 亚洲在线黄色| 97久久精品人人澡人人爽缅北| 亚洲熟女少妇一区二区| 自拍偷拍欧美一区| 亚洲韩国青草视频| 亚洲911精品成人18网站| 国精品产品一区| 欧美在线观看一二区| 日韩激情免费视频| 都市激情国产精品| 亚洲自拍偷拍av| 老汉色影院首页| 日本在线观看视频| 国产欧美精品日韩区二区麻豆天美| 国内一区二区三区在线视频| 亚洲欧美黄色片| 国产成人自拍在线| 成人在线中文字幕| 国产精品一级二级| 极品美女销魂一区二区三区| 国产精品一区二区三区久久久| 日本一级片免费看| 亚洲精品资源| 91精品国产成人| 日韩欧美亚洲视频| 99视频一区| 97精品国产97久久久久久春色| 国产亚洲精品成人| 亚洲视频精品| 97在线视频观看| 色婷婷av国产精品| 性欧美videos另类喷潮| 欧美亚洲一级片| 丁香社区五月天| 日精品一区二区| 国产精品极品美女粉嫩高清在线| www.日韩一区| 精品一区二区在线看| 91精品视频免费看| 午夜美女福利视频| 成人午夜精品在线| 久久狠狠久久综合桃花| 欧美视频免费一区二区三区| 国产欧美日韩中文久久| 亚洲精品成人久久久998| 视频免费一区| 一区二区三区四区五区视频在线观看| 第九区2中文字幕| av免费不卡| 日本韩国一区二区三区视频| 奇米影视四色在线| 日韩一区网站| 亚洲欧美国产制服动漫| 激情五月激情综合| 亚洲激情亚洲| 国产精品69av| 国产夫绿帽单男3p精品视频| caoporn国产精品| 五月天亚洲综合| 欧洲在线视频| 色综合天天综合给合国产| 久久国产精品国产精品| 9999久久久久| 最新的欧美黄色| 久久精品欧美一区二区| 快she精品国产999| 99高清视频有精品视频| 免费在线看v| 伊人色综合久久天天| 久久国产亚洲精品无码| 日本一区二区三区中文字幕| 亚洲国产成人在线播放| 色婷婷国产精品免| 亚洲一级影院| 国产欧美日韩精品专区| 欧美一区二区三区成人片在线| 久久精品亚洲乱码伦伦中文 | 色综合久久五月| jizzjizz欧美69巨大| 欧美激情欧美激情在线五月| 国内av在线播放| 成人18视频日本| 少妇熟女一区二区| 全亚洲第一av番号网站| 精品成人在线观看| 福利视频第一页| 欧美一级一区| 国产精品大全| 久草资源在线| 欧美午夜免费电影| 无套内谢大学处破女www小说| 亚洲欧美亚洲| 国产欧美精品xxxx另类| 青草久久伊人| 天天综合日日夜夜精品| 一个人看的视频www| 手机亚洲手机国产手机日韩| 欧美有码在线观看| 少妇高潮一区二区三区69| 一区二区三区四区在线免费观看| 亚洲xxx在线观看| 欧美日中文字幕| 青青久久av北条麻妃黑人| 少妇喷水在线观看| 亚洲午夜激情网页| 国产在线a视频| 亚洲成av人电影| 国产精品欧美日韩一区二区| 欧美色图另类| 欧美性xxxxx极品娇小| 国产高清成人久久| 最新国产拍偷乱拍精品 | 亚洲精品一二三四五区| 综合综合综合综合综合网| 91av在线看| 五十路在线视频| 欧美日韩裸体免费视频| 欧美熟妇精品一区二区蜜桃视频| 国内精品久久久久久久影视麻豆| 91在线观看免费高清| 国产黄色在线网站| 日韩欧美高清在线| 妺妺窝人体色www婷婷| 国产激情视频一区二区在线观看 | 一区二区三区福利| 国精产品一区二区| 在线黄色的网站| 亚洲女人被黑人巨大进入| 免费看日批视频| 国产欧美一区二区在线观看| 99久久国产宗和精品1上映| 国产精品最新| 国产在线精品播放| www在线视频| 精品福利视频一区二区三区| 日韩av在线电影| 久久精品亚洲乱码伦伦中文| 在线免费观看av的网站| 国产大片一区| 丁香婷婷久久久综合精品国产 | 午夜国产在线视频| 一本色道久久综合亚洲aⅴ蜜桃| 中文字幕第4页| 久久99热国产| 男人日女人视频网站| 在线日韩一区| 成人黄色av播放免费| 牛牛精品视频在线| 亚洲男人的天堂在线| 中国女人一级一次看片| 亚洲欧美成aⅴ人在线观看| 少妇搡bbbb搡bbb搡打电话| 亚洲一区二区伦理| 亚洲一区在线直播| 婷婷视频一区二区三区| 欧洲成人免费aa| 麻豆tv免费在线观看| 亚洲精品在线免费播放| 亚洲中文字幕无码爆乳av| 椎名由奈av一区二区三区| 日韩无码精品一区二区| 日韩不卡一区二区三区 | 二区三区四区高清视频在线观看| 精品国产污网站| 国产99免费视频| 夜夜精品视频一区二区| 黄瓜视频污在线观看| 国产一区欧美二区| 亚洲精品无码久久久久久| 天天天综合网| 欧美精品一区在线| 99亚洲乱人伦aⅴ精品| 国产精品老女人精品视频| 美女精品导航| 久久久国产视频| 日韩二区三区| 欧美tk—视频vk| 自拍偷拍第八页| 午夜久久久久久久久久一区二区| 无码人中文字幕| 久久新电视剧免费观看| 制服下的诱惑暮生| 日本不卡一区二区三区| 国产精品秘入口18禁麻豆免会员| 亚洲欧美网站在线观看| 日韩欧美一区二区视频在线播放| 国产成人澳门| 91精品国产99久久久久久红楼 | 91免费看国产| 国模一区二区| 欧美一级大胆视频| 17videosex性欧美| 欧美理论片在线观看| 在线看免费av| 亚洲欧美综合区自拍另类| 黄色av网站免费在线观看| 91麻豆精品国产自产在线观看一区 | 欧美日本中文| 天天操天天干天天玩| 久久精品av| 五月婷婷综合色| 国精一区二区| 欧美一区2区三区4区公司二百 | 亚洲精品在线91| 日本黄色大片视频| 亚洲第一网站免费视频| 国产黄色高清视频| 日韩一级黄色大片| av综合在线观看| 3d成人h动漫网站入口| 6—12呦国产精品| 欧美日本国产一区| 在线观看一二三区| 欧美老女人在线| 国产免费av电影| 日韩女优av电影| 亚洲成人黄色片| 欧美精品一区二区三区在线| 亚洲黄色a级片| 亚洲精品一区二区三区香蕉| 欧美熟妇交换久久久久久分类 | 欧美日韩在线第一页| 免费观看成人毛片| 一本色道久久综合亚洲91| 日韩 国产 欧美| 欧美三级日韩三级| 97精品人妻一区二区三区香蕉 | 欧美亚洲午夜视频在线观看| 在线女人免费视频| 国产精品海角社区在线观看| 成人黄色在线| 成人精品一区二区三区电影免费| 色综合一区二区日本韩国亚洲| 91久久国产婷婷一区二区| 日本少妇精品亚洲第一区| 成人激情直播| 窝窝社区一区二区| 午夜精品一区二区在线观看| 我不卡神马影院| 成人国产一区二区三区| 亚洲久久在线| 日本新janpanese乱熟| 精品亚洲成a人在线观看| 伊人av在线播放| 久久午夜色播影院免费高清| 国产午夜精品久久久久久久久| 中文字幕一区二区三中文字幕| 日本高清不卡免费| 午夜精品福利在线| 国产一级精品毛片| 日韩欧美色电影| 欧美色图另类| 欧美成人午夜激情在线| 国产传媒av在线| 国产精品欧美日韩| 岛国精品一区| 亚洲一区二区精品在线| 国产精品magnet| 亚洲精品中文字幕无码蜜桃| 精品无人码麻豆乱码1区2区| 星空大象在线观看免费播放| 欧美激情一区二区三区| 国产性一乱一性一伧一色| 欧美中文字幕一二三区视频| 精品人妻无码一区二区三区蜜桃一 | 一区二区三区精品视频| 中文字幕xxxx| 精品国产乱码久久久久久1区2区| 国产色a在线| 欧美激情视频一区二区三区不卡 | 91久久综合亚洲鲁鲁五月天| 美女扒开腿让男人桶爽久久动漫| 日韩av一区二区三区美女毛片| 欧美日韩一区二区国产| 午夜激情福利在线| www.欧美色图| 婷婷伊人五月天| 欧美系列日韩一区| 日韩一区av| 欧美激情久久久久| 成人精品视频在线观看| 人禽交欧美网站免费| 欧美fxxxxxx另类| 日本激情综合网| 久久久久久久电影| 国产无套在线观看| 欧美一区二区三区免费观看视频| 都市激情一区| 青青久久aⅴ北条麻妃| 国产精品男女| 可以在线看黄的网站| 奇米精品一区二区三区在线观看一| 亚州av综合色区无码一区| 一区二区三区四区在线免费观看| 国产乱码精品一区二三区蜜臂| 一本色道久久综合亚洲精品小说 | 国产精品爽爽ⅴa在线观看| 无码日韩精品一区二区免费| xxxx18hd亚洲hd捆绑| 国产电影精品久久禁18| 91麻豆免费视频网站| 欧美日韩国产a| 亚洲麻豆精品| 国产欧美一区二区三区在线看 | 手机在线看片1024| 亚洲国产中文字幕久久网| 欧洲精品二区| 国产精品国产三级国产专区53 | 亚洲天堂精品在线观看| 中文字幕+乱码+中文| 国产亚洲xxx| 国产福利亚洲| 亚洲国产精品一区二区第四页av| 日韩精品久久久久久| 免费网站在线高清观看| 欧洲精品一区二区| 成全电影播放在线观看国语| 国产精品网站大全| 国产二区精品| 无码人妻一区二区三区免费n鬼沢| 亚洲老妇xxxxxx| 超碰免费在线97| 97热精品视频官网| 日韩av字幕| 精品视频无码一区二区三区| 国产亚洲综合性久久久影院| 制服丝袜在线一区| 裸体女人亚洲精品一区| 一本一道久久a久久| 久久亚洲中文字幕无码| 99久久久精品免费观看国产蜜| 亚洲精品午夜国产va久久成人| 国产亚洲欧美一区| 欧美黄色网络| 91午夜在线观看| www国产成人免费观看视频 深夜成人网| 免费看日批视频| 日韩在线观看免费高清| 视频亚洲一区二区| 欧美老熟妇喷水| 中文字幕视频一区| 亚洲AV无码成人片在线观看| 97香蕉超级碰碰久久免费软件| 国产亚洲一区| 亚洲日本黄色片| 午夜成人免费视频| 黄色影院在线播放| 2022国产精品| 一本久久综合| 国产精品成人69xxx免费视频| 欧美成人欧美edvon| 在线视频超级| av久久久久久| 国产亚洲精品aa午夜观看| 97免费观看视频| 97久久精品视频| 亚欧美无遮挡hd高清在线视频| 艳妇乳肉豪妇荡乳xxx| 欧美在线观看禁18| 国产一线二线在线观看| 欧美一区二区三区四区在线观看地址| 久久99国产精品成人| 国产做受高潮漫动| 日韩中文字幕第一页| 日本天堂一区| 久久出品必属精品| 欧美性受极品xxxx喷水| 免费电影视频在线看| 亚洲一卡二卡区|