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

spark 自己的分布式存儲系統 - BlockManager

存儲 存儲軟件 大數據 Spark 分布式
BlockManager 是 spark 中至關重要的一個組件, 在 spark的的運行過程中到處都有 BlockManager 的身影, 只有搞清楚 BlockManager 的原理和機制,你才能更加深入的理解 spark。 今天我們來揭開 BlockaManager 的底層原理和設計思路,

整體架構

BlockManager 是 spark 中至關重要的一個組件, 在 spark的的運行過程中到處都有 BlockManager 的身影, 只有搞清楚 BlockManager 的原理和機制,你才能更加深入的理解 spark。 今天我們來揭開 BlockaManager 的底層原理和設計思路,

BlockManager 是一個嵌入在 spark 中的 key-value型分布式存儲系統,是為 spark 量身打造的,

BlockManager 在一個 spark 應用中作為一個本地緩存運行在所有的節點上, 包括所有 driver 和 executor上。 BlockManager 對本地和遠程提供一致的 get 和set 數據塊接口, BlockManager 本身使用不同的存儲方式來存儲這些數據, 包括 memory, disk, off-heap。

 

上面是一個整體的架構圖, BlockManagerMaster擁有BlockManagerMasterEndpoint 的actor和所有BlockManagerSlaveEndpoint的ref, 可以通過這些引用對 slave 下達命令

executor 節點上的BlockManagerMaster 則擁有BlockManagerMasterEndpoint的ref和自身BlockManagerSlaveEndpoint的actor。可以通過 Master的引用注冊自己。

在master 和 slave 可以正常的通信之后, 就可以根據設計的交互協議進行交互, 整個分布式緩存系統也就運轉起來了,

初始化

我們知道, sparkEnv 啟動的時候會啟動各個組件, BlockManager 也不例外, 也是這個時候啟動的,

啟動的時候會根據自己是在 driver 還是 executor 上進行不同的啟動過程,

  1. def registerOrLookupEndpoint( 
  2.         name: String, endpointCreator: => RpcEndpoint): 
  3.       RpcEndpointRef = { 
  4.       if (isDriver) { 
  5.         logInfo("Registering " + name
  6.         rpcEnv.setupEndpoint(name, endpointCreator) 
  7.       } else { 
  8.         RpcUtils.makeDriverRef(name, conf, rpcEnv) 
  9.       } 
  10.     } 

上圖是 sparkEnv 在 master上啟動的時候, 構造了一個 BlockManagerMasterEndpoint, 然后把這個Endpoint 注冊在 rpcEnv中, 同時也會啟動自己的 BlockManager

上圖是 sparkEnv 在executor上啟動的時候, 通過 setupEndpointRef 方法獲取到了  BlockManagerMaster的引用 BlockManagerMasterRef, 同時也會啟動自己的 BlockManager,

在 BlockManager 初始化自己的時候, 會向 BlockManagerMasterEndpoint 注冊自己, BlockManagerMasterEndpoint 發送 registerBlockManager消息,  BlockManagerMasterEndpoint 接受到消息, 把 BlockManagerSlaveEndpoint  的引用 保存在自己的  blockManagerInfo 數據結構中以待后用。

分布式協議

下面的一個表格是 master 和 slave 接受到各種類型的消息, 以及接受到消息后,做的處理。

  • BlockManagerMasterEndpoint  接受的消息

  • BlockManagerSlaveEndpoint 接受的消息

根據以上的協議, 相信我們可以很清楚的猜測整個交互的流程, 一般過程應該是這樣的, slave的 BlockManager  在自己接的上存儲一個 Block, 然后把這個 BlockId 匯報到master的BlockManager , 經過 cache, shuffle 或者 Broadcast后,別的節點需要上一步的Block的時候, 會到 master 獲取數據所在位置, 然后去相應節點上去 fetch。

存儲層

在RDD層面上我們了解到RDD是由不同的partition組成的,我們所進行的transformation和action是在partition上面進行的;而在storage模塊內部,RDD又被視為由不同的block組成,對于RDD的存取是以block為單位進行的,本質上partition和block是等價的,只是看待的角度不同。在Spark storage模塊中中存取數據的最小單位是block,所有的操作都是以block為單位進行的。

 

BlockManager對象被創建的時候會創建出MemoryStore和DiskStore對象用以存取block,如果內存中擁有足夠的內存, 就 使用 MemoryStore存儲,  如果 不夠, 就 spill 到 磁盤中, 通過 DiskStore進行存儲。

  • DiskStore 有一個DiskBlockManager,DiskBlockManager 主要用來創建并持有邏輯 blocks 與磁盤上的 blocks之間的映射,一個邏輯 block 通過 BlockId 映射到一個磁盤上的文件。 在 DiskStore 中會調用  diskManager.getFile 方法, 如果子文件夾不存在,會進行創建, 文件夾的命名方式為(spark-local-yyyyMMddHHmmss-xxxx, xxxx是一個隨機數), 所有的block都會存儲在所創建的folder里面。
  • MemoryStore 相對于DiskStore需要根據block id hash計算出文件路徑并將block存放到對應的文件里面,MemoryStore管理block就顯得非常簡單:MemoryStore內部維護了一個hash map來管理所有的block,以block id為key將block存放到hash map中。而從MemoryStore中取得block則非常簡單,只需從hash map中取出block id對應的value即可。

BlockManager 的 PUT 和GET接口

BlockManager 提供了 Put 接口和 Get 接口, 這兩個 api 屏蔽了底層的細節, 我們來看下底層是如何實現的

  • GET操作 如果 local 中存在就直接返回, 從本地獲取一個Block, 會先判斷如果是 useMemory, 直接從內存中取出, 如果是 useDisk, 會從磁盤中取出返回, 然后根據useMemory判斷是否在內存中緩存一下,方便下次獲取,  如果local 不存在, 從其他節點上獲取, 當然元信息是存在 drive上的,要根據我們上文中提到的 GETlocation 協議獲取 Block 所在節點位置, 然后到其他節點上獲取。
  • PUT操作 操作之前會加鎖來避免多線程的問題, 存儲的時候會根據 存儲級別, 調用對應的是 memoryStore 還是  diskStore, 然后在具體存儲器上面調用 存儲接口。 如果有 replication 需求, 會把數據備份到其他的機器上面。

blockManager 和 blockTransferService 關系

spark 歷史上使用過兩套網絡框架, 最開始的時候, rpc 調用使用的是 akka, 大文件傳輸使用的是 netty,  后面統一全部使用 netty,  這里的大文件傳輸其實走的是 netty,  在啟動 blockManager的時候會啟動一個 blockTransferService 服務, 這個服務就是用來傳輸大文件用的, 對應的具體類是  NettyBlockTransferService, 這個實例中也會有 BlocakManager的引用, 會啟動一個 NettyBlockRpcServer的 netty Handler, 也擁有 BlocakManager 的引用,  用來提供服務, BlocakManager 根據 BlockId 獲取一個 Block 然后包裝為一個 ManagedBuffer 對象,

當我們需要從遠端獲取一個 Block的時候,就需要 blockTransferService 傳輸大的字節數組,

首先需要從 driver上獲取到 Block的真正存儲位置, 然后調用 blockTransferService 的 fetchBlocks方法, 去其他真正存儲節點上去fetch數據, 會從 client 資源池中獲取一個client,  如果是一對一的進行fetch,  使用的是 OneForOneBlockFetcher, 這個Fetcher 是以 Chunks 為單位分別單獨fetch,  每個 Chunks 也就對應一個Block的數據, 根據配置,會進行重試直到***重試次數,發送 OpenBlocks消息,  里面會包裝對應的是哪個  BlockId,  其他節點服務端會根據 BlockId 從 blockManager中拿到數據, 然后用來傳輸, 使用的是 netty 的流式傳輸方式, 同時也會有回調函數,

如果是備份的時候同步上傳一個 Block,  其他節點服務端會根據,uploadBlock消息中包含的BlockId, 在本地的BlockManager 中冗余存儲一份,

ChunkFetch也有一個類似Stream的概念,ChunkFetch的對象是“一個內存中的Iterator[ManagedBuffer]”,即一組Buffer,每一個Buffer對應一個chunkIndex,整個Iterator[ManagedBuffer]由一個StreamID標識。Client每次的ChunkFetch請求是由(streamId,chunkIndex)組成的唯一的StreamChunkId,Server端根據StreamChunkId獲取為一個Buffer并返回給Client; 不管是Stream還是ChunkFetch,在Server的內存中都需要管理一組由StreamID與資源之間映射,即StreamManager類,它提供了getChunk和openStream兩個接口來分別響應ChunkFetch與Stream兩種操作,并且針對Server的ChunkFetch提供一個registerStream接口來注冊一組Buffer,比如可以將BlockManager中一組BlockID對應的Iterator[ManagedBuffer]注冊到StreamManager,從而支持遠程Block Fetch操作。

對于ExternalShuffleService(一種單獨shuffle服務進程,對其他計算節點提供本節點上面的所有shuffle map輸出),它為遠程Executor提供了一種OpenBlocks的RPC接口,即根據請求的appid,executorid,blockid(appid+executor對應本地一組目錄,blockid拆封出)從本地磁盤中加載一組FileSegmentManagedBuffer到內存,并返回加載后的streamId返回給客戶端,從而支持后續的ChunkFetch的操作。

Partition 與 Block 的關系

我們都知道, RDD 的運算是基于 partition, 每個 task 代表一個 分區上一個 stage 內的運算閉包, task 被分別調度到 多個 executor上去運行, 那么是在哪里變成了 Block 呢,  我們以 spark 2.11 源碼為準, 看看這個轉變過程,

一個 RDD 調度到 executor 上會運行調用 getOrCompute方法,

  1. SparkEnv.get.blockManager.getOrElseUpdate(blockId, storageLevel, elementClassTag, () => { 
  2.       readCachedBlock = false 
  3.       computeOrReadCheckpoint(partition, context) 
  4.     }) 

如果 Block 在 BlockManager 中存在, 就會從 BlockManager 中獲取,如果不存在, 就進行計算這個Block, 然后在 BlockManager 中進行存儲持久化, 方便下次使用,

當然獲取的時候是先從本地的 BlockManager 中獲取, 如果本地沒有, 然后再 從 remote 獲取, 先從 driver 上獲取到元數據 Block的位置, 然后去到真正的節點上fetch

如果沒有, 就進行計算, 然后根據存儲級別,存儲到計算節點本地的BlockManager 的內存或磁盤中,

這樣RDD的transformation、action就和block數據建立了聯系,雖然抽象上我們的操作是在partition層面上進行的,但是partition最終還是被映射成為block,因此實際上我們的所有操作都是對block的處理和存取。

blockManager 在 spark 中扮演的角色

blockManager 是非常非常重要的一個 spark 組件, 我們隨便舉幾個例子, 你就知道 BlockManager 多重要了 ,

  • spark  shuffle 的過程總用到了 BlockManager 作為數據的中轉站
  • spark broadcast 調度 task 到多個 executor 的時候, broadCast 底層使用的數據存儲層
  • spark streaming  一個 ReceiverInputDStream 接受到的數據也是先放在 BlockManager 中, 然后封裝為一個 BlockRdd 進行下一步運算的
  • 如果我們 對一個 rdd 進行了cache, cacheManager 也是把數據放在了 blockmanager 中, 截斷了計算鏈依賴, 后續task 運行的時候可以直接從 cacheManager 中獲取到 cacherdd ,不用再從頭計算。

spark cache  與  spark   broadcast task

我隨便舉兩個例子, 看看具體 spark cache 和 spark  broadcast 調度 task 的時候怎么用的 blockManager的

spark cache

rdd 計算的時候, 首先根據RDD id和partition index構造出block id (rdd_xx_xx), 接著從BlockManager中取出相應的block, 如果該block存在,表示此RDD在之前已經被計算過和存儲在BlockManager中,因此取出即可,無需再重新計算。 如果 block 不存在我們可以 計算出來, 然后吧 block 通過   doPutIterator 函數存儲在 節點上的 BlockManager上面, 匯報block信息到 driver, 下次如果使用同一個 rdd, 就可以直接從分布式存儲中 直接取出相應的 block

下面看一下源碼

  1. final def iterator(split: Partition, context: TaskContext): Iterator[T] = { 
  2.     if (storageLevel != StorageLevel.NONE) { 
  3.       getOrCompute(split, context) 
  4.     } else { 
  5.       computeOrReadCheckpoint(split, context) 
  6.     } 
  7.   } 

如果存儲級別不是 NONE類型就會調用 getOrCompute 這個我們已經看過了,  里面實際調用  SparkEnv.get.blockManager.getOrElseUpdate 方法, 如果 Block 在 BlockManager 中存在, 就會從 BlockManager 中獲取,如果不存在, 就進行計算這個Block, 然后在 BlockManager 中進行存儲持久化, 方便下次使用,

在  BlockManager 進行存儲后, 會調用下面的代碼把 匯報block信息到 driver,

  1. private def tryToReportBlockStatus( 
  2.      blockId: BlockId, 
  3.      status: BlockStatus, 
  4.      droppedMemorySize: Long = 0L): Boolean = { 
  5.    val storageLevel = status.storageLevel 
  6.    val inMemSize = Math.max(status.memSize, droppedMemorySize) 
  7.    val onDiskSize = status.diskSize 
  8.    master.updateBlockInfo(blockManagerId, blockId, storageLevel, inMemSize, onDiskSize) 
  9.  } 

實際上上想  masterEndpoint 的引用發送一條 UpdateBlockInfo消息,  master 會把這個 blockId 對應的 location 放在 driver 上,

同樣的如果一個 Block已經計算過了,會到 driver 上獲取到 location 信息

  1. private def getLocations(blockId: BlockId): Seq[BlockManagerId] = { 
  2.    val locs = Random.shuffle(master.getLocations(blockId)) 
  3.    val (preferredLocs, otherLocs) = locs.partition { loc => blockManagerId.host == loc.host } 
  4.    preferredLocs ++ otherLocs 
  5.  } 

spark   broadcast task

這個調度 task 到多個 task 上面過程代碼太多,我就不貼了, 直接說一下流程,

  • DAGScheduler 在  submitMissingTasks 方法提交 task的時候, 會把 task 包裝為一個 Broadcast 類型, 里面使用 TorrentBroadcastFactory 創建一個 TorrentBroadcast 的類型, 使用的是p2p的協議, 會減輕 master 的壓力,  這個里面會 調用 writeBlocks 里面把taskBinary  通過 blockManager.putSingle 放在 BlockManager 緩存中
  • ShuffleMapTask 或者 ResultTask,然后調用 runTask 方法, 里面實際上會調用 Broadcast 的value 方法, 里面最終調用了 BlockManager 的 getLocalBytes 或者 getRemoteBytes 方法

blockManager 在  spark streaming 中的應用

  • ReceiverTracker 在啟動的時候,會運行一個 job, 這個job 就是到 各個executor上去啟動 ReceiverSupervisorImpl, 然后啟動各個具體的數據接收器,  如果是SocketInputDStream, 就會啟動一個 SocketReceiver,
  • Receiver 接收到數據后, 先在 BlockGenerator 中緩存, 等到達一定的大小后,  調用 BlockManagerBasedBlockHandler 的 storeBlock方法持久化到 BlockManager 中, 然后把數據信息匯報到 ReceiverTracker上, 最終 匯總到   ReceivedBlockTracker 中的 timeToAllocatedBlocks中,
  • ReceiverInputDStream compute的時候,  receivedBlockTracker 會根據時間獲取到  BlockManager 中的元信息,里面最終對應的還是 BlockManager 的存儲位置, 最終獲取到數據進行計算,

測試 blockManager

我們做一個簡單的測試,兩端代碼的區別就是 一個 進行了cache ,一個沒有進行cache。

  1. val file = sc.textFile("/fusionlog/midsourcenew/2017-03-13-18-15_2.gz" 
  2. file.count()  
  3. file.count() 

我們從日志可以觀察出來, ***段代碼, 兩個 job 中都從 hdfs 中讀取文件, 讀取了兩次,

  1. val file = sc.textFile("/fusionlog/midsourcenew/2017-03-13-18-15_2.gz").cache() 
  2. file.count() 
  3. file.count() 

有以下日志

  1. MemoryStore: Block rdd_1_0 stored as values in memory (estimated size 1354.9 MB, free 4.9 GB) 
  2. BlockManager: Found block rdd_1_0 locally 

我們發現在***次讀取文件后, 把文件 cache 在了 blockManager 中, 下一個 job 運行的時候, 在本地 BlockManager 直接發現獲取到了 block , 沒有讀取 hdfs 文件 ,

在 spark ui 中也發現了 cache的 Block, 全部是在內存中緩存的, 

責任編輯:武曉燕 來源: spark技術分享
相關推薦

2017-04-14 09:48:25

分布式存儲系統

2018-09-29 14:08:04

存儲系統分布式

2017-10-16 10:24:47

LogDevice存儲系統

2017-10-19 08:45:15

存儲系統HBase

2017-10-12 09:36:54

分布式存儲系統

2018-11-20 09:19:58

存儲系統雪崩效應

2017-07-18 09:51:36

文件存儲系統

2017-10-17 08:33:31

存儲系統分布式

2017-12-18 10:47:04

分布式存儲數據

2019-10-15 10:59:43

分布式存儲系統

2019-05-13 15:20:42

存儲系統算法

2018-10-24 11:01:53

分布式存儲系統

2013-12-27 10:56:42

分布式對象存儲Sheepdog性能測試

2018-10-29 12:42:23

Ceph分布式存儲

2018-03-13 08:45:08

存儲系統DHT算法

2010-07-02 10:08:12

BigtableGoogle

2021-08-07 05:00:20

存儲系統

2014-02-19 11:37:57

分布式對象存儲Sheepdog

2025-01-26 11:54:39

分布式存儲系統

2021-07-04 07:07:06

Ceph分布式存儲架構
點贊
收藏

51CTO技術棧公眾號

91国偷自产一区二区使用方法| 麻豆国产精品官网| 亚洲人成在线免费观看| 五月婷婷丁香综合网| 黄色小网站在线观看| 成人毛片视频在线观看| 国产精品久久久久久久午夜| 唐朝av高清盛宴| 亚洲男人都懂第一日本| 欧美一区二区三区在线观看| 无码播放一区二区三区| 男人和女人做事情在线视频网站免费观看| 国产真实乱对白精彩久久| 国外成人在线播放| 亚洲色偷偷综合亚洲av伊人| 日本在线中文字幕一区| 欧美一区永久视频免费观看| 日韩精品一区二区三区久久| 中文国产字幕在线观看| 国产日本欧美一区二区| 国产免费一区二区三区| 97视频免费在线| 久久精品123| 欧美福利在线观看| 日本爱爱小视频| 在线日韩网站| 亚洲电影在线看| 911av视频| 亚洲www啪成人一区二区| 亚洲电影一级黄| 国产精品免费看久久久无码| 在线免费观看黄色av| 久久综合久久99| 国产精品一区二区av| 91肉色超薄丝袜脚交一区二区| 三级在线观看一区二区 | 国产在线观看黄| 岛国av在线一区| 91丨九色丨国产在线| 中文字幕乱码人妻无码久久| 久久精品日产第一区二区| 久久久久久久一区二区| 免费一级片视频| 中文精品电影| 欧美精品免费在线| 1024手机在线视频| 欧美在线91| 久久成人18免费网站| 911国产在线| 国产二区精品| zzjj国产精品一区二区| 最近中文字幕免费| blacked蜜桃精品一区| 亚洲欧美国产视频| 精品欧美一区二区久久久| 蜜臀91精品国产高清在线观看| 精品亚洲国产成av人片传媒| 鲁大师私人影院在线观看| 日韩av系列| 亚洲精品一区二区在线| 成人片黄网站色大片免费毛片| 国产99久久精品一区二区300| 精品无人国产偷自产在线| 伊人网在线视频观看| 成人免费在线播放| yellow中文字幕久久| 欧美视频www| 韩国av一区| 68精品国产免费久久久久久婷婷| 黄网在线观看视频| 丝袜脚交一区二区| 国产精品永久免费视频| 99久久精品日本一区二区免费| 国产精品白丝av| av电影在线观看完整版一区二区| 国语自产精品视频在线看抢先版图片| 日韩av综合在线| 久久九九电影| 国产日韩在线免费| 国产91免费在线观看| 91网站最新网址| 日韩片电影在线免费观看| 日本福利在线| 亚洲一区二区三区在线看| 欧美爱爱视频免费看| 高清成人在线| 欧美一级在线免费| 中文字幕在线免费看线人| 欧美亚洲精品在线| 欧美高跟鞋交xxxxxhd| 日本va欧美va国产激情| 蜜桃一区二区三区在线| 国产精品免费在线| 成人在线免费看| 一区二区三区在线视频免费观看| 女人天堂av手机在线| 欧美爱爱视频| 亚洲激情 国产| 国产精品麻豆免费版现看视频| 欧美激情aⅴ一区二区三区| 2019亚洲日韩新视频| 一级成人免费视频| a亚洲天堂av| 中文字幕一区二区三区在线乱码| 后进极品白嫩翘臀在线播放| 91福利国产成人精品照片| 丰满少妇中文字幕| 亚洲深夜福利在线观看| 久久高清视频免费| 人妻中文字幕一区二区三区| 福利一区在线观看| 亚洲精品成人三区| 精品极品在线| 日韩欧美色综合| 亚洲色图欧美色| 亚洲欧美日韩精品一区二区| 亚洲综合国产精品| 国产在线电影| 姬川优奈aav一区二区| 色婷婷一区二区三区在线观看| 亚洲人成网亚洲欧洲无码| 欧美精品videos| 国产一区二区三区中文字幕| 久久久久九九视频| av网站大全免费| 久久伊人影院| 日日狠狠久久偷偷四色综合免费| 久久99国产综合精品免费| 成人午夜伦理影院| eeuss中文| 久久精品资源| 国产亚洲精品一区二区| wwwwww国产| 成人在线一区二区三区| 一级特黄妇女高潮| avtt久久| 按摩亚洲人久久| 在线观看国产精品入口男同| 久久久91精品国产一区二区三区| 欧美不卡在线播放| 国产成人精品亚洲线观看| 豆花视频一区二区| 日韩激情在线视频| 日韩女同强女同hd| 白白色 亚洲乱淫| 嫩草影院中文字幕| 91在线一区| 欧美精品成人91久久久久久久| 性做久久久久久久| 夜夜嗨av一区二区三区网页| 中国特级黄色片| 国产精品多人| 国产一区自拍视频| 蜜桃av在线播放| 国产视频精品在线| www.com亚洲| 国产欧美久久久精品影院 | 麻豆国产精品视频| 夜夜爽99久久国产综合精品女不卡| 成人自拍视频网| 最近的2019中文字幕免费一页 | 水蜜桃一区二区| 成人做爰免费视频免费看| 国产亚洲综合久久| 一区二区的视频| 亚洲精品视频观看| www.555国产精品免费| 国产精品毛片| 午夜一区二区三区| japansex久久高清精品| 欧美国产日韩精品| 日本一级在线观看| 欧美三级中文字| 日本 欧美 国产| 丁香一区二区三区| 久久精品99国产| 久久综合国产| 国产精品美女xx| 都市激情亚洲一区| 精品国产欧美一区二区五十路| www.四虎在线观看| 欧美日韩一区二区免费在线观看| 丁香花五月婷婷| 国产成人午夜视频| av动漫在线观看| 亚洲成人免费| 精品一区二区日本| 欧美一级免费| 国内精品久久久久影院优| 成黄免费在线| 精品久久久久久久人人人人传媒 | 日韩欧美在线123| 精品成人av一区二区在线播放| 中文字幕精品在线不卡| 香蕉久久久久久av成人| 天堂成人国产精品一区| 欧美 国产 精品| 国产一区二区精品久| 97人人干人人| 草莓视频成人appios| 久久久久国产精品www| 成年网站在线| 亚洲激情电影中文字幕| 国产免费福利视频| 色婷婷国产精品综合在线观看| 波多野结衣亚洲一区二区| 久久一留热品黄| 成人啪啪18免费游戏链接| 蜜桃久久精品一区二区| 欧美日韩精品在线一区二区| 999国产精品999久久久久久| 精品国产乱码久久久久久108| 99精品国产九九国产精品| 热久久免费国产视频| 啪啪免费视频一区| xxx欧美精品| 国产特黄在线| 日韩电影第一页| 国产成人精品av在线观| 欧美日韩一区二区三区在线| 天堂网一区二区三区| 亚洲一区二区三区视频在线 | 色综合亚洲欧洲| 国产在线视频在线观看| 自拍偷拍国产亚洲| 91视频免费在观看| 久久久综合九色合综国产精品| 日本久久久久久久久久| 国产一区在线不卡| 亚洲免费黄色网| 蜜桃精品视频在线观看| 天堂中文视频在线| 视频在线观看一区二区三区| 黄色动漫网站入口| 国产亚洲精品久久久久婷婷瑜伽| 国产传媒久久久| 欧美黄色免费| 激情五月婷婷六月| 欧美午夜影院| 女人床在线观看| 午夜精彩国产免费不卡不顿大片| 在线无限看免费粉色视频| 日韩电影免费在线观看| 五月天色一区| 成人黄色av| 亚洲自拍的二区三区| 成人在线一区| 国产精品av免费| 亚洲乱码电影| 永久免费网站视频在线观看| 91精品国产调教在线观看| 国产精品jizz在线观看老狼| 亚洲国产不卡| 黄色激情在线视频| 亚洲久久成人| 国产二区视频在线播放| 久久久久综合| 亚洲综合日韩欧美| 激情五月激情综合网| 亚洲少妇一区二区| av网站免费线看精品| 人妻在线日韩免费视频| 久久久久国产精品厨房| 美国美女黄色片| 亚洲丝袜美腿综合| 免费中文字幕在线观看| 黄色成人av在线| 成人免费一区二区三区| 在线播放中文一区| 亚洲免费不卡视频| 日韩精品免费在线视频观看| 国产无套粉嫩白浆在线2022年| www亚洲精品| 欧美6一10sex性hd| 日韩美女在线观看| 只有精品亚洲| 久久久久久九九九九| 成人激情开心网| 国产亚洲精品久久久久久久| 日韩午夜激情| 日本肉体xxxx裸体xxx免费| 国产福利一区在线观看| 中文字幕av观看| 亚洲欧洲一区二区在线播放| 国产第100页| 欧美无人高清视频在线观看| wwwav网站| 亚洲最大中文字幕| 美女尤物在线视频| 国产精品大片wwwwww| 日韩不卡在线视频| 欧洲亚洲一区二区三区四区五区| 91久久夜色精品国产按摩| xxxx18hd亚洲hd捆绑| 奇米精品一区二区三区在线观看| 韩国三级hd中文字幕有哪些| 久久久99免费| 国产亚洲欧美精品久久久www| 在线免费一区三区| 亚洲精品字幕在线| 日韩亚洲国产中文字幕| 精品众筹模特私拍视频| 国产精品欧美一区二区| 久久1电影院| 欧美性受xxxx黑人猛交88| 久久精品五月| 精品熟女一区二区三区| 国产精品久久久久久久久动漫| 国产精品久久久免费视频| 5566中文字幕一区二区电影| 蜜芽tv福利在线视频| 久久久久久久久91| 在线不卡一区| 亚洲欧洲一区二区在线观看| 一本久久综合| 久久久男人的天堂| 亚洲精品美腿丝袜| 在线视频欧美亚洲| 99视频在线观看一区三区| 亚洲成在人线av| 久久精品一二三区| 国产成人在线免费视频| 男女啪啪999亚洲精品| 亚洲三级久久久| 长河落日免费高清观看| 亚洲成人精品在线观看| 国产绳艺sm调教室论坛| 正在播放欧美视频| 中文不卡1区2区3区| 国产精品毛片一区视频| 真实国产乱子伦精品一区二区三区| 国产v亚洲v天堂无码久久久| 99久久精品久久久久久清纯| 青青草手机视频在线观看| 欧美丰满少妇xxxbbb| а√天堂中文在线资源bt在线| 欧美孕妇与黑人孕交| 卡通动漫国产精品| 青青草国产精品视频| 国产91丝袜在线播放九色| 91在线播放观看| 3atv在线一区二区三区| 男人天堂手机在线| 成人欧美一区二区三区黑人| 99精品视频精品精品视频| 欧美日韩一区二区三区69堂| 欧美极品少妇xxxxⅹ高跟鞋 | 91精品网站| 亚洲精品中文字幕乱码| 免费高清视频在线观看| 一区二区三区在线看| 成人小说亚洲一区二区三区| 久久久久久久久久久成人| 国产精品自在| 亚洲人成色77777| 欧美激情中文字幕一区二区| 亚洲综合精品视频| 久久深夜福利免费观看| 日韩精品视频中文字幕| 97视频在线免费| ww亚洲ww在线观看国产| 日批视频免费在线观看| 中文字幕亚洲欧美一区二区三区| 日本久久久久| 久久这里只有精品18| www.视频一区| 亚洲va在线观看| 在线激情影院一区| 日本超碰一区二区| 欧美日韩一道本| 国产日韩亚洲欧美综合| 国产精品系列视频| 久久久久久久久91| 国产欧美日韩在线一区二区| 8x8x成人免费视频| 亚洲一区二区三区不卡国产欧美| 天天操天天干天天操| 国产精品吊钟奶在线| 伊人久久大香线蕉精品组织观看| 国产精品日日摸夜夜爽| 欧美日韩在线视频观看| 自拍视频在线| 国产精品一区二区三区免费观看| 久久午夜影视| 日韩影院一区二区| 精品小视频在线| 精品视频在线观看网站| 日本日本19xxxⅹhd乱影响| 中文子幕无线码一区tr| 高h放荡受浪受bl| 国产精品video| 亚洲网站视频| 又色又爽的视频| 亚洲国产精久久久久久| 久久久久黄色| 欧美s码亚洲码精品m码| 亚洲色图丝袜美腿| 欧美日韩影视| 99国产超薄丝袜足j在线观看| 久久久久久久波多野高潮日日|