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

Spark的兩種核心Shuffle詳解

開發 前端 Spark
在 MapReduce 框架中, Shuffle 階段是連接 Map 與 Reduce 之間的橋梁, Map 階段通過 Shuffle 過程將數據輸出到 Reduce 階段中。由于 Shuffle 涉及磁盤的讀寫和網絡 I/O,

[[416741]]

本文轉載自微信公眾號「五分鐘學大數據」,作者園陌。轉載本文請聯系五分鐘學大數據公眾號。

在 MapReduce 框架中, Shuffle 階段是連接 Map 與 Reduce 之間的橋梁, Map 階段通過 Shuffle 過程將數據輸出到 Reduce 階段中。由于 Shuffle 涉及磁盤的讀寫和網絡 I/O,因此 Shuffle 性能的高低直接影響整個程序的性能。Spark 也有 Map 階段和 Reduce 階段,因此也會出現 Shuffle 。

Spark Shuffle

Spark Shuffle 分為兩種:一種是基于 Hash 的 Shuffle;另一種是基于 Sort 的 Shuffle。先介紹下它們的發展歷程,有助于我們更好的理解 Shuffle:

在 Spark 1.1 之前, Spark 中只實現了一種 Shuffle 方式,即基于 Hash 的 Shuffle 。在 Spark 1.1 版本中引入了基于 Sort 的 Shuffle 實現方式,并且 Spark 1.2 版本之后,默認的實現方式從基于 Hash 的 Shuffle 修改為基于 Sort 的 Shuffle 實現方式,即使用的 ShuffleManager 從默認的 hash 修改為 sort。在 Spark 2.0 版本中, Hash Shuffle 方式己經不再使用。

Spark 之所以一開始就提供基于 Hash 的 Shuffle 實現機制,其主要目的之一就是為了避免不需要的排序,大家想下 Hadoop 中的 MapReduce,是將 sort 作為固定步驟,有許多并不需要排序的任務,MapReduce 也會對其進行排序,造成了許多不必要的開銷。

在基于 Hash 的 Shuffle 實現方式中,每個 Mapper 階段的 Task 會為每個 Reduce 階段的 Task 生成一個文件,通常會產生大量的文件(即對應為 M*R 個中間文件,其中, M 表示 Mapper 階段的 Task 個數, R 表示 Reduce 階段的 Task 個數) 伴隨大量的隨機磁盤 I/O 操作與大量的內存開銷。

為了緩解上述問題,在 Spark 0.8.1 版本中為基于 Hash 的 Shuffle 實現引入了 Shuffle Consolidate 機制(即文件合并機制),將 Mapper 端生成的中間文件進行合并的處理機制。通過配置屬性 spark.shuffie.consolidateFiles=true,減少中間生成的文件數量。通過文件合并,可以將中間文件的生成方式修改為每個執行單位為每個 Reduce 階段的 Task 生成一個文件。

執行單位對應為:每個 Mapper 端的 Cores 數/每個 Task 分配的 Cores 數(默認為 1) 。最終可以將文件個數從 M*R 修改為 E*C/T*R,其中, E 表示 Executors 個數, C 表示可用 Cores 個數, T 表示 Task 分配的 Cores 數。

Spark1.1 版本引入了 Sort Shuffle:

基于 Hash 的 Shuffle 的實現方式中,生成的中間結果文件的個數都會依賴于 Reduce 階段的 Task 個數,即 Reduce 端的并行度,因此文件數仍然不可控,無法真正解決問題。為了更好地解決問題,在 Spark1.1 版本引入了基于 Sort 的 Shuffle 實現方式,并且在 Spark 1.2 版本之后,默認的實現方式也從基于 Hash 的 Shuffle,修改為基于 Sort 的 Shuffle 實現方式,即使用的 ShuffleManager 從默認的 hash 修改為 sort。

在基于 Sort 的 Shuffle 中,每個 Mapper 階段的 Task 不會為每 Reduce 階段的 Task 生成一個單獨的文件,而是全部寫到一個數據(Data)文件中,同時生成一個索引(Index)文件, Reduce 階段的各個 Task 可以通過該索引文件獲取相關的數據。避免產生大量文件的直接收益就是降低隨機磁盤 I/0 與內存的開銷。最終生成的文件個數減少到 2*M ,其中 M 表示 Mapper 階段的 Task 個數,每個 Mapper 階段的 Task 分別生成兩個文件(1 個數據文件、 1 個索引文件),最終的文件個數為 M 個數據文件與 M 個索引文件。因此,最終文件個數是 2*M 個。

從 Spark 1.4 版本開始,在 Shuffle 過程中也引入了基于 Tungsten-Sort 的 Shuffie 實現方式,通 Tungsten 項目所做的優化,可以極大提高 Spark 在數據處理上的性能。(Tungsten 翻譯為中文是鎢絲)

注:在一些特定的應用場景下,采用基于 Hash 實現 Shuffle 機制的性能會超過基于 Sort 的 Shuffle 實現機制。

一張圖了解下 Spark Shuffle 的迭代歷史:

Spark Shuffle 迭代歷史

為什么 Spark 最終還是放棄了 HashShuffle ,使用了 Sorted-Based Shuffle?

我們可以從 Spark 最根本要優化和迫切要解決的問題中找到答案,使用 HashShuffle 的 Spark 在 Shuffle 時產生大量的文件。當數據量越來越多時,產生的文件量是不可控的,這嚴重制約了 Spark 的性能及擴展能力,所以 Spark 必須要解決這個問題,減少 Mapper 端 ShuffleWriter 產生的文件數量,這樣便可以讓 Spark 從幾百臺集群的規模瞬間變成可以支持幾千臺,甚至幾萬臺集群的規模。

但使用 Sorted-Based Shuffle 就完美了嗎,答案是否定的,Sorted-Based Shuffle 也有缺點,其缺點反而是它排序的特性,它強制要求數據在 Mapper 端必須先進行排序,所以導致它排序的速度有點慢。好在出現了 Tungsten-Sort Shuffle ,它對排序算法進行了改進,優化了排序的速度。Tungsten-Sort Shuffle 已經并入了 Sorted-Based Shuffle,Spark 的引擎會自動識別程序需要的是 Sorted-Based Shuffle,還是 Tungsten-Sort Shuffle。

下面詳細剖析每個 Shuffle 的底層執行原理:

一、Hash Shuffle 解析

以下的討論都假設每個 Executor 有 1 個 cpu core。

1. HashShuffleManager

shuffle write 階段,主要就是在一個 stage 結束計算之后,為了下一個 stage 可以執行 shuffle 類的算子(比如 reduceByKey),而將每個 task 處理的數據按 key 進行“劃分”。所謂“劃分”,就是對相同的 key 執行 hash 算法,從而將相同 key 都寫入同一個磁盤文件中,而每一個磁盤文件都只屬于下游 stage 的一個 task。在將數據寫入磁盤之前,會先將數據寫入內存緩沖中,當內存緩沖填滿之后,才會溢寫到磁盤文件中去。

下一個 stage 的 task 有多少個,當前 stage 的每個 task 就要創建多少份磁盤文件。比如下一個 stage 總共有 100 個 task,那么當前 stage 的每個 task 都要創建 100 份磁盤文件。如果當前 stage 有 50 個 task,總共有 10 個 Executor,每個 Executor 執行 5 個 task,那么每個 Executor 上總共就要創建 500 個磁盤文件,所有 Executor 上會創建 5000 個磁盤文件。由此可見,未經優化的 shuffle write 操作所產生的磁盤文件的數量是極其驚人的。

shuffle read 階段,通常就是一個 stage 剛開始時要做的事情。此時該 stage 的每一個 task 就需要將上一個 stage 的計算結果中的所有相同 key,從各個節點上通過網絡都拉取到自己所在的節點上,然后進行 key 的聚合或連接等操作。由于 shuffle write 的過程中,map task 給下游 stage 的每個 reduce task 都創建了一個磁盤文件,因此 shuffle read 的過程中,每個 reduce task 只要從上游 stage 的所有 map task 所在節點上,拉取屬于自己的那一個磁盤文件即可。

shuffle read 的拉取過程是一邊拉取一邊進行聚合的。每個 shuffle read task 都會有一個自己的 buffer 緩沖,每次都只能拉取與 buffer 緩沖相同大小的數據,然后通過內存中的一個 Map 進行聚合等操作。聚合完一批數據后,再拉取下一批數據,并放到 buffer 緩沖中進行聚合操作。以此類推,直到最后將所有數據到拉取完,并得到最終的結果。

HashShuffleManager 工作原理如下圖所示:

未優化的HashShuffleManager工作原理

2. 優化的 HashShuffleManager

為了優化 HashShuffleManager 我們可以設置一個參數:spark.shuffle.consolidateFiles,該參數默認值為 false,將其設置為 true 即可開啟優化機制,通常來說,如果我們使用 HashShuffleManager,那么都建議開啟這個選項。

開啟 consolidate 機制之后,在 shuffle write 過程中,task 就不是為下游 stage 的每個 task 創建一個磁盤文件了,此時會出現shuffleFileGroup的概念,每個 shuffleFileGroup 會對應一批磁盤文件,磁盤文件的數量與下游 stage 的 task 數量是相同的。一個 Executor 上有多少個 cpu core,就可以并行執行多少個 task。而第一批并行執行的每個 task 都會創建一個 shuffleFileGroup,并將數據寫入對應的磁盤文件內。

當 Executor 的 cpu core 執行完一批 task,接著執行下一批 task 時,下一批 task 就會復用之前已有的 shuffleFileGroup,包括其中的磁盤文件,也就是說,此時 task 會將數據寫入已有的磁盤文件中,而不會寫入新的磁盤文件中。因此,consolidate 機制允許不同的 task 復用同一批磁盤文件,這樣就可以有效將多個 task 的磁盤文件進行一定程度上的合并,從而大幅度減少磁盤文件的數量,進而提升 shuffle write 的性能。

假設第二個 stage 有 100 個 task,第一個 stage 有 50 個 task,總共還是有 10 個 Executor(Executor CPU 個數為 1),每個 Executor 執行 5 個 task。那么原本使用未經優化的 HashShuffleManager 時,每個 Executor 會產生 500 個磁盤文件,所有 Executor 會產生 5000 個磁盤文件的。但是此時經過優化之后,每個 Executor 創建的磁盤文件的數量的計算公式為:cpu core的數量 * 下一個stage的task數量,也就是說,每個 Executor 此時只會創建 100 個磁盤文件,所有 Executor 只會創建 1000 個磁盤文件。

這個功能優點明顯,但為什么 Spark 一直沒有在基于 Hash Shuffle 的實現中將功能設置為默認選項呢,官方給出的說法是這個功能還欠穩定。

優化后的 HashShuffleManager 工作原理如下圖所示:

優化后的HashShuffleManager工作原理

基于 Hash 的 Shuffle 機制的優缺點

優點:

  • 可以省略不必要的排序開銷。
  • 避免了排序所需的內存開銷。

缺點:

  • 生產的文件過多,會對文件系統造成壓力。
  • 大量小文件的隨機讀寫帶來一定的磁盤開銷。
  • 數據塊寫入時所需的緩存空間也會隨之增加,對內存造成壓力。

二、SortShuffle 解析

SortShuffleManager 的運行機制主要分成三種:

普通運行機制;

bypass 運行機制,當 shuffle read task 的數量小于等于spark.shuffle.sort.bypassMergeThreshold參數的值時(默認為 200),就會啟用 bypass 機制;

Tungsten Sort 運行機制,開啟此運行機制需設置配置項 spark.shuffle.manager=tungsten-sort。開啟此項配置也不能保證就一定采用此運行機制(后面會解釋)。

1. 普通運行機制

在該模式下,數據會先寫入一個內存數據結構中,此時根據不同的 shuffle 算子,可能選用不同的數據結構。如果是 reduceByKey 這種聚合類的 shuffle 算子,那么會選用 Map 數據結構,一邊通過 Map 進行聚合,一邊寫入內存;如果是 join 這種普通的 shuffle 算子,那么會選用 Array 數據結構,直接寫入內存。接著,每寫一條數據進入內存數據結構之后,就會判斷一下,是否達到了某個臨界閾值。如果達到臨界閾值的話,那么就會嘗試將內存數據結構中的數據溢寫到磁盤,然后清空內存數據結構。

在溢寫到磁盤文件之前,會先根據 key 對內存數據結構中已有的數據進行排序。排序過后,會分批將數據寫入磁盤文件。默認的 batch 數量是 10000 條,也就是說,排序好的數據,會以每批 1 萬條數據的形式分批寫入磁盤文件。寫入磁盤文件是通過 Java 的 BufferedOutputStream 實現的。BufferedOutputStream 是 Java 的緩沖輸出流,首先會將數據緩沖在內存中,當內存緩沖滿溢之后再一次寫入磁盤文件中,這樣可以減少磁盤 IO 次數,提升性能。

一個 task 將所有數據寫入內存數據結構的過程中,會發生多次磁盤溢寫操作,也就會產生多個臨時文件。最后會將之前所有的臨時磁盤文件都進行合并,這就是merge 過程,此時會將之前所有臨時磁盤文件中的數據讀取出來,然后依次寫入最終的磁盤文件之中。此外,由于一個 task 就只對應一個磁盤文件,也就意味著該 task 為下游 stage 的 task 準備的數據都在這一個文件中,因此還會單獨寫一份索引文件,其中標識了下游各個 task 的數據在文件中的 start offset 與 end offset。

SortShuffleManager 由于有一個磁盤文件 merge 的過程,因此大大減少了文件數量。比如第一個 stage 有 50 個 task,總共有 10 個 Executor,每個 Executor 執行 5 個 task,而第二個 stage 有 100 個 task。由于每個 task 最終只有一個磁盤文件,因此此時每個 Executor 上只有 5 個磁盤文件,所有 Executor 只有 50 個磁盤文件。

普通運行機制的 SortShuffleManager 工作原理如下圖所示:

普通運行機制的SortShuffleManager工作原理

2. bypass 運行機制

Reducer 端任務數比較少的情況下,基于 Hash Shuffle 實現機制明顯比基于 Sort Shuffle 實現機制要快,因此基于 Sort Shuffle 實現機制提供了一個帶 Hash 風格的回退方案,就是 bypass 運行機制。對于 Reducer 端任務數少于配置屬性spark.shuffle.sort.bypassMergeThreshold設置的個數時,使用帶 Hash 風格的回退計劃。

bypass 運行機制的觸發條件如下:

  • shuffle map task 數量小于spark.shuffle.sort.bypassMergeThreshold=200參數的值。
  • 不是聚合類的 shuffle 算子。

此時,每個 task 會為每個下游 task 都創建一個臨時磁盤文件,并將數據按 key 進行 hash 然后根據 key 的 hash 值,將 key 寫入對應的磁盤文件之中。當然,寫入磁盤文件時也是先寫入內存緩沖,緩沖寫滿之后再溢寫到磁盤文件的。最后,同樣會將所有臨時磁盤文件都合并成一個磁盤文件,并創建一個單獨的索引文件。

該過程的磁盤寫機制其實跟未經優化的 HashShuffleManager 是一模一樣的,因為都要創建數量驚人的磁盤文件,只是在最后會做一個磁盤文件的合并而已。因此少量的最終磁盤文件,也讓該機制相對未經優化的 HashShuffleManager 來說,shuffle read 的性能會更好。

而該機制與普通 SortShuffleManager 運行機制的不同在于:第一,磁盤寫機制不同;第二,不會進行排序。也就是說,啟用該機制的最大好處在于,shuffle write 過程中,不需要進行數據的排序操作,也就節省掉了這部分的性能開銷。

bypass 運行機制的 SortShuffleManager 工作原理如下圖所示:

bypass運行機制的SortShuffleManager工作原理

3. Tungsten Sort Shuffle 運行機制

Tungsten Sort 是對普通 Sort 的一種優化,Tungsten Sort 會進行排序,但排序的不是內容本身,而是內容序列化后字節數組的指針(元數據),把數據的排序轉變為了指針數組的排序,實現了直接對序列化后的二進制數據進行排序。由于直接基于二進制數據進行操作,所以在這里面沒有序列化和反序列化的過程。內存的消耗大大降低,相應的,會極大的減少的 GC 的開銷。

Spark 提供了配置屬性,用于選擇具體的 Shuffle 實現機制,但需要說明的是,雖然默認情況下 Spark 默認開啟的是基于 SortShuffle 實現機制,但實際上,參考 Shuffle 的框架內核部分可知基于 SortShuffle 的實現機制與基于 Tungsten Sort Shuffle 實現機制都是使用 SortShuffleManager,而內部使用的具體的實現機制,是通過提供的兩個方法進行判斷的:

對應非基于 Tungsten Sort 時,通過 SortShuffleWriter.shouldBypassMergeSort 方法判斷是否需要回退到 Hash 風格的 Shuffle 實現機制,當該方法返回的條件不滿足時,則通過 SortShuffleManager.canUseSerializedShuffle 方法判斷是否需要采用基于 Tungsten Sort Shuffle 實現機制,而當這兩個方法返回都為 false,即都不滿足對應的條件時,會自動采用普通運行機制。

因此,當設置了 spark.shuffle.manager=tungsten-sort 時,也不能保證就一定采用基于 Tungsten Sort 的 Shuffle 實現機制。

要實現 Tungsten Sort Shuffle 機制需要滿足以下條件:

  • Shuffle 依賴中不帶聚合操作或沒有對輸出進行排序的要求。
  • Shuffle 的序列化器支持序列化值的重定位(當前僅支持 KryoSerializer Spark SQL 框架自定義的序列化器)。
  • Shuffle 過程中的輸出分區個數少于 16777216 個。

實際上,使用過程中還有其他一些限制,如引入 Page 形式的內存管理模型后,內部單條記錄的長度不能超過 128 MB (具體內存模型可以參考 PackedRecordPointer 類)。另外,分區個數的限制也是該內存模型導致的。

 

所以,目前使用基于 Tungsten Sort Shuffle 實現機制條件還是比較苛刻的。

參考資料:

 

  • 《Spark大數據商業實戰三部曲》
  • https://spark.apache.org/docs/2.0.0/programming-guide.html#shuffle-operations
  • https://mp.weixin.qq.com/s/2yT4QGIc7XTI62RhpYEGjw

 

責任編輯:武曉燕 來源: 五分鐘學大數據
相關推薦

2022-03-15 08:25:32

SparkShuffle框架

2024-06-06 08:32:52

.NET框架代碼

2025-09-15 06:25:00

2010-06-02 15:29:06

SVN版本控制

2010-03-18 10:18:52

python模塊

2023-11-09 09:09:36

ZookeeperCP組件

2010-01-25 17:14:53

核心交換機

2009-06-08 20:07:44

Eclipse中使用p

2010-03-11 10:38:34

Python運算符

2013-05-27 14:31:34

Hadoop 2.0

2010-10-11 10:31:51

MySQL分區

2009-09-14 19:25:09

Ruby form

2021-05-27 10:57:01

TCP定時器網絡協議

2020-01-06 14:54:31

RDBAOFRedis

2018-10-24 09:00:26

KafkaSpark數據

2011-03-03 10:26:04

Pureftpd

2010-03-11 14:34:47

Python環境

2009-06-25 13:43:00

Buffalo AJA

2010-10-21 16:24:18

sql server升

2011-04-06 12:41:41

Java異常
點贊
收藏

51CTO技術棧公眾號

亚洲不卡在线播放| 国内精品国产三级国产aⅴ久| 国产刺激高潮av| 亚洲麻豆一区| 夜夜嗨av色综合久久久综合网| 国产免费又粗又猛又爽| 日韩在线观看www| 国产精品一区2区| 91国产美女视频| 精品日韩在线视频| 岛国av一区| 欧美三级日本三级少妇99| 潘金莲一级淫片aaaaaa播放1| 污视频在线免费观看| 麻豆专区一区二区三区四区五区| 久久99精品久久久久久噜噜| 亚洲天堂视频一区| 日韩中文字幕在线一区| 日本韩国精品一区二区在线观看| 久久久成人精品一区二区三区| 天天爱天天干天天操| 久久精品国产秦先生| 98精品国产自产在线观看| 亚洲欧美卡通动漫| 亚洲都市激情| 亚洲成年人在线播放| 国模私拍视频在线观看| 天堂av在线| 夜夜爽夜夜爽精品视频| 午夜精品区一区二区三| 少妇一级淫片免费看| 韩国一区二区视频| 国产精品直播网红| 波多野结衣黄色网址| 亚洲视频精品| 欧美另类在线观看| 女同久久另类69精品国产| 网曝91综合精品门事件在线| 日韩欧美一区在线观看| 亚洲欧美日韩精品一区| 免费污视频在线一区| 精品久久久久久久久久久久| wwwwww欧美| 国产二区三区在线| 国产精品电影院| 一本一本久久a久久精品综合妖精| 日本啊v在线| 91小视频在线| 精品国产免费一区二区三区| 国产成人无码www免费视频播放| 国产麻豆精品在线| 91亚洲va在线va天堂va国 | 欧美性videos高清精品| 日本一本中文字幕| h片精品在线观看| 亚洲综合久久av| 久草视频这里只有精品| 欧美大片黄色| 亚洲国产精品一区二区久久| 999久久欧美人妻一区二区| 粗大黑人巨茎大战欧美成人| 日韩码欧中文字| 欧洲美女和动交zoz0z| 大地资源网3页在线观看| 亚洲免费电影在线| 天天想你在线观看完整版电影免费| 韩国中文字幕在线| 亚洲品质自拍视频| 久久久久久av无码免费网站下载| 日本大胆在线观看| 午夜天堂影视香蕉久久| 免费成人在线视频网站| 精品视频一区二区三区四区五区| 欧美唯美清纯偷拍| 国产探花在线观看视频| 国产成人一二片| 日韩精品视频在线观看免费| 高潮毛片无遮挡| 色狮一区二区三区四区视频| 欧美老女人xx| 欧美日韩一二三四区| 日韩av一区二区三区| 亚洲一区二区久久久久久久| 色香蕉在线视频| 欧美国产一区二区在线观看| 五月天色婷婷综合| 黄色成人在线网| 色欧美乱欧美15图片| 97超碰成人在线| 精品少妇一区| 视频在线观看一区二区| 波多野结衣家庭教师| 亚洲精品黄色| 国产精品女主播| 亚洲av无码一区二区乱子伦| 97精品国产露脸对白| 亚洲一区二区在线看| 伦理av在线| 在线观看不卡一区| 精品国产免费久久久久久婷婷| 免费av一区二区三区四区| 久久国产精品久久国产精品| 日本视频免费观看| 国产成人在线看| 欧美一区二区三区四区夜夜大片 | 中文字幕乱码久久午夜不卡 | 免费看国产精品一二区视频| 色网站在线看| 午夜精品免费在线| 在线观看免费视频高清游戏推荐| 国产精东传媒成人av电影| 一区二区欧美日韩视频| 日韩激情一区二区三区| 久久国产精品99久久人人澡| 狠狠色综合欧美激情| 蜜桃视频在线观看免费视频网站www| 亚洲成人综合在线| 加勒比av中文字幕| 精品福利久久久| 午夜精品一区二区三区在线播放| 91麻豆国产视频| 国产日产欧美一区二区三区| 欧美一区二区中文字幕| 欧美经典一区| 久久大大胆人体| 怡红院男人天堂| 久久综合中文字幕| 欧美不卡在线播放| 亚洲国产一区二区三区网站| 中文字幕精品视频| 亚洲av无码精品一区二区| av激情亚洲男人天堂| 黄色录像特级片| 韩国三级大全久久网站| 日日骚久久av| 日韩欧美一级大片| 久久这里只有精品视频网| 男人日女人视频网站| 中文无码日韩欧| 久久99热精品这里久久精品| 国产一区二区视频免费观看 | 久久久久亚洲av片无码| 日本欧美一区二区三区| 人偷久久久久久久偷女厕| 在线视频超级| 亚洲欧美另类国产| 综合网在线观看| 久久婷婷色综合| 日韩视频第二页| 亚洲宅男一区| 国产精品扒开腿做| 91涩漫在线观看| 欧美性猛交xxxx乱大交退制版| 日韩人妻无码精品综合区| 久久精品电影| 亚洲一区bb| 成人污污www网站免费丝瓜| 久久精品最新地址| h狠狠躁死你h高h| 亚洲午夜在线视频| 黄色网址在线视频| 日日夜夜一区二区| 亚洲午夜高清视频| 日韩精品视频一区二区三区| 色综合天天综合网国产成人网 | 成人午夜免费视频| 欧美 丝袜 自拍 制服 另类| 日韩免费电影在线观看| 国产第一区电影| 77777影视视频在线观看| 91麻豆精品91久久久久同性| 妺妺窝人体色www婷婷| 成人av资源在线观看| 欧美日韩成人免费视频| 国产精品片aa在线观看| 国产日韩欧美日韩大片| 人人超在线公开视频| 日韩电影中文字幕一区| 久操视频在线免费观看| 亚洲欧美日本韩国| 国产二级一片内射视频播放 | 欧美好骚综合网| 亚洲一区二区三区sesese| 超碰97国产精品人人cao| 精品亚洲一区二区三区| 91无套直看片红桃| 亚洲高清免费一级二级三级| 受虐m奴xxx在线观看| 狠狠色丁香婷婷综合久久片| 日本中文字幕亚洲| 成人精品中文字幕| 国产伦精品一区二区三区视频免费| av电影一区| 麻豆国产va免费精品高清在线| 先锋av资源站| 欧美浪妇xxxx高跟鞋交| 日本va欧美va国产激情| 亚洲婷婷在线视频| 人人人妻人人澡人人爽欧美一区| 国产麻豆精品在线| 天堂社区在线视频| 极品av少妇一区二区| 神马影院午夜我不卡| 精品国内亚洲2022精品成人| 国产欧美日韩精品丝袜高跟鞋| 92久久精品| 久久综合伊人77777蜜臀| 欧美一区二区三区少妇| 日韩久久久久久| 中文字幕人成人乱码亚洲电影| 一二三区精品福利视频| 精品在线观看一区| 97se亚洲国产综合自在线不卡| 99re6在线观看| 日韩极品在线观看| 欧美a v在线播放| 欧美激情综合色综合啪啪| 先锋影音日韩| 九九久久精品| 九九九九久久久久| 亚洲日本va中文字幕| 国产日产久久高清欧美一区| 这里有精品可以观看| 欧美精品www在线观看| 成人免费网址| www国产亚洲精品久久网站| 国产在线观看网站| 日韩精品在线播放| 秋霞欧美在线观看| 日韩欧美一级二级三级久久久| 亚洲天堂久久久久| 在线视频一区二区免费| 欧美一区二区三区网站| 精品福利在线观看| 日本在线观看视频网站| 亚洲综合免费观看高清完整版| 在线观看亚洲网站| 中文字幕日本不卡| 国产又粗又长又黄的视频| 中文字幕av资源一区| 99久久精品免费视频| 91麻豆精东视频| 国产亚洲无码精品| 91影院在线观看| 黄色国产在线观看| 久久色中文字幕| 制服 丝袜 综合 日韩 欧美| 久久亚洲欧美国产精品乐播| 中文字幕在线看高清电影| 91视频一区二区| 巨胸大乳www视频免费观看| 91在线免费播放| 波多野吉衣中文字幕| 日本一区二区三区四区 | 亚洲精品自拍动漫在线| 老熟妻内射精品一区| 亚洲欧美日韩久久精品| 欧美日韩精品在线观看视频| 亚洲尤物视频在线| 久久狠狠高潮亚洲精品| 欧美性高跟鞋xxxxhd| 日本丰满少妇做爰爽爽| 91麻豆精品国产91久久久资源速度| 国产女人18毛片水18精| 欧美成人aa大片| 婷婷五月综合久久中文字幕| 亚洲欧美国产另类| 在线观看h片| 欧美另类第一页| 小早川怜子影音先锋在线观看| 国产精品成人aaaaa网站| 欧美成人黄色| 国产精品免费视频一区二区| 亚洲精品aaaaa| 亚洲精品在线观看免费| 欧美在线黄色| www.com毛片| 久久国内精品自在自线400部| 中文字幕第六页| 99久久久久久99| 人成免费在线视频| 亚洲国产日产av| 天天综合久久综合| 日韩一区二区中文字幕| 午夜视频免费在线| 久久综合伊人77777蜜臀| 天堂电影一区| 91最新国产视频| 亚洲婷婷丁香| 青青草视频国产| 天堂va蜜桃一区二区三区| 亚洲国产午夜精品| 久久久久久夜精品精品免费| 国精产品一区一区二区三区mba| 午夜久久福利影院| 亚洲综合一区中| 亚洲精品成人av| 久久99精品久久久久久野外| 欧美在线视频网站| 精品一区二区三区视频在线播放 | 欧美日韩亚洲网| 国产精品伦理一区| 亚洲精品99久久久久| 黄色在线免费看| 国产成人精品综合久久久| 日韩一区二区三区色 | 欧美精品入口| 中文字幕国产传媒| 99免费精品视频| 深夜福利影院在线观看| 欧美性色欧美a在线播放| 男人天堂综合网| 欧美xxxx18国产| 亚洲精品成人一区| 欧美日韩国产三区| 亚洲人成久久| 色婷婷狠狠18禁久久| 国产精品―色哟哟| 国产字幕在线观看| 精品视频中文字幕| 91九色在线播放| 99久久综合狠狠综合久久止 | 国产乱人伦精品一区| 中文字幕在线中文字幕日亚韩一区| 天堂一区二区在线免费观看| 免费无码一区二区三区| 亚洲图片欧美一区| 国产suv精品一区二区69| 日韩中文字幕免费视频| 韩国成人在线| 色噜噜色狠狠狠狠狠综合色一 | 黄色成人av在线| 97人妻精品一区二区三区软件| 一本大道久久加勒比香蕉| 韩国成人漫画| 欧美精品一区三区在线观看| 国产一级久久| 亚洲av无码成人精品国产| 无码av中文一区二区三区桃花岛| 亚洲成a人片77777精品| 欧美尺度大的性做爰视频| 91精品一久久香蕉国产线看观看 | 国产精品久久麻豆| 91精品国产综合久久男男| 久久神马影院| www.com污| 亚洲欧美一区二区三区极速播放 | 九九久久国产精品| 欧美专区一区| 国产一区二区三区在线免费| 国产精品一区二区果冻传媒| 免费在线视频一区二区| 亚洲成人网久久久| 午夜影院在线播放| 日韩欧美视频第二区| 蜜臀av一区二区在线免费观看| 国产三级黄色片| 在线播放视频一区| 秋霞在线午夜| 极品尤物一区二区三区| 久久国产日韩| 成人免费视频入口| 91精品国模一区二区三区| 污污网站在线看| 久久大片网站| 青青草成人在线观看| 亚洲一区电影在线观看| 日韩一区二区精品| 国模私拍一区二区国模曼安| 日本成人看片网址| 九色综合狠狠综合久久| 青青草偷拍视频| 亚洲国产日韩精品在线| 日日av拍夜夜添久久免费| 正在播放精油久久| gogo大胆日本视频一区| 综合网在线观看| 久久影视免费观看| 久久精品色综合| 午夜免费看视频| 香蕉成人啪国产精品视频综合网| 欧美色综合一区二区三区| 国产精品亚洲自拍| 国产精品分类| 亚洲无人区码一码二码三码的含义| 在线综合视频播放| 一区二区精品伦理...| 午夜精品一区二区在线观看| 国产伦精一区二区三区| 亚洲 欧美 成人| 免费91在线视频| 精品久久精品| 超碰caoprom| 69堂成人精品免费视频| 日本乱码一区二区三区不卡| 一区二区三区欧美在线| av一区二区久久| 国产精品区在线观看| 欧美有码在线观看视频| 亚洲一级淫片|