精品欧美一区二区三区在线观看 _久久久久国色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成人免费在线视频| 国产精品亚洲一区| 亚洲 欧美 成人| 日韩欧美网站| 精品国产123| 欧美黄色一级片视频| 日本高清视频在线观看| 成人精品一区二区三区四区| 日本成熟性欧美| 日本精品人妻无码77777| 免费福利视频一区| 欧美三级乱人伦电影| 国产精品久久久久久久乖乖| 国产精品视频一区二区久久| 成人性生交大片免费看中文网站| 国产精品aaaa| 欧美成人三级视频| 国产精品一区二区av日韩在线| 日韩一区二区三区在线观看| 欧美日韩大尺度| av成人 com a| 亚洲欧美另类综合偷拍| 欧美日韩一区二区三| 性做久久久久久久| 久久精品国产亚洲一区二区三区 | 成人中文字幕在线观看| 青青草免费观看视频| 国产精品豆花视频| 久久精品国产69国产精品亚洲 | 日韩在线黄色| 精品免费视频.| 伊人网在线综合| 88xx成人网| 日本精品一区二区三区四区的功能| 精品人妻大屁股白浆无码| 尤物网在线观看| 久久夜色精品一区| 精品欧美一区二区精品久久| 精品人妻无码一区二区色欲产成人 | 人人妻人人澡人人爽欧美一区双| 免费黄色网页在线观看| 国产日产精品一区| 欧美一卡2卡3卡4卡无卡免费观看水多多| 亚洲国产日韩在线观看| 国产精品一区不卡| 亚洲va久久久噜噜噜久久天堂| 国产成人av免费| 日韩成人午夜精品| 国产精品高潮呻吟久久av无限| 在线观看亚洲天堂| 亚洲综合不卡| 欧美有码在线观看视频| 久久久国产精品成人免费| 精品9999| 69久久夜色精品国产69乱青草| 久久夜色精品亚洲| 国产欧美日韩一区二区三区在线| 91黑丝在线观看| 日韩三级免费看| 妖精视频成人观看www| 91精品国产高清自在线看超| 国产成人精品片| 久久精品1区| 国产精品久久久久国产a级| 一级黄色av片| 美女视频网站久久| 91色在线观看| 亚洲精品网站在线| 不卡的av电影| 欧美极品jizzhd欧美| 国产黄色片在线观看| 亚洲欧洲精品一区二区精品久久久 | 日本一二三区在线视频| 久久蜜桃香蕉精品一区二区三区| 欧美日韩一区在线播放| 青青影院在线观看| 色小子综合网| 亚洲色图14p| 亚洲人成网亚洲欧洲无码| 亚洲欧美激情在线视频| 国产精品美女高潮无套| 99免费精品| 欧美肥臀大乳一区二区免费视频| 精品少妇theporn| 欧美亚洲自偷自偷| 国产美女精品视频免费观看| 国产精品久久久久久久免费 | 国产精品高清在线观看| 国产又大又长又粗| 懂色一区二区三区免费观看| 蜜桃狠狠色伊人亚洲综合网站| 1024国产在线| 亚洲精品欧美综合四区| 免费国产黄色网址| 国产成人精选| 亚洲电影av在线| 懂色av粉嫩av浪潮av| 红桃视频亚洲| 国产精品一区二区三区成人| 日韩一级在线播放| 国产精品久久久久久久久晋中 | 亚洲人成网站在线播| 中文乱码字幕高清一区二区| 一区二区三区福利| 成人激情视频在线播放| 男女污视频在线观看| 亚洲麻豆国产自偷在线| 精品视频在线观看一区| 懂色av色香蕉一区二区蜜桃| 亚洲欧美日韩在线高清直播| 久久国产露脸精品国产| 日韩av中文字幕一区二区三区| 97在线中文字幕| 草碰在线视频| 精品人伦一区二区三区蜜桃免费| 无人码人妻一区二区三区免费| 日韩激情网站| 久久久久久久久91| 国产精品久久免费| 国产三级欧美三级| 啊啊啊一区二区| 99re6热只有精品免费观看| 日韩在线观看免费网站| 日韩三级一区二区| 99久久精品国产精品久久| 国产日韩欧美大片| 少妇精品视频在线观看| 国产亚洲xxx| 中文字幕在线看人| 99国产一区二区三精品乱码| 国产美女主播在线| 一区中文字幕电影| 九九久久久久久久久激情| 一级片在线免费观看视频| 国产日产亚洲精品系列| 日本毛片在线免费观看| 久久a爱视频| 久久久久久久久久久人体| 99在线观看免费| 亚洲视频一区在线| 999在线精品视频| 香港欧美日韩三级黄色一级电影网站| 国产精品永久免费视频| 日本不卡视频| 欧美三级日韩三级| 男人的午夜天堂| 黑人巨大精品欧美一区| 黄色影视在线观看| 精品久久国产一区| 欧美裸身视频免费观看| 亚洲av色香蕉一区二区三区| 一区二区三区高清在线| 99精品一区二区三区无码吞精 | 成人一区二区三| 精品国产一区一区二区三亚瑟 | 亚洲国产精品国自产拍av| 国产又黄又猛视频| 日韩精品欧美| 成人综合国产精品| 手机在线免费看av| 亚洲第一精品福利| 久久免费激情视频| 久久综合久久综合久久| 黄色成人av网站| 亚洲新中文字幕| 日日夜夜狠狠操| 国产日韩av一区| 五月婷婷之婷婷| 欧美96在线丨欧| 狠狠色噜噜狠狠色综合久 | 亚洲制服一区| 国产精品国产三级国产aⅴ9色| 国产福利片在线| 7777女厕盗摄久久久| 欧美片一区二区| 91影院在线观看| 婷婷丁香激情网| 在线成人超碰| 久久99精品久久久久久三级| 99re66热这里只有精品4| 日韩亚洲欧美中文高清在线| 黄频网站在线观看| 欧美影院一区二区| 青青草原国产视频| 91一区二区在线观看| 少妇一级淫免费放| 国产精品一区二区三区网站| 国产精品日韩精品| 巨大荫蒂视频欧美另类大| 91精品国产aⅴ一区二区| 日韩av一二三区| 亚洲国产精品激情在线观看 | 成人中文字幕在线| 日韩久久一级片| 欧美1区2区| 日韩av一区二区三区在线观看| 精品视频在线观看免费观看| 国产91精品久久久| 超碰在线网址| 国产一区二区三区在线观看网站| 国产极品久久久| 欧美色综合久久| 精品国产乱码一区二区| 亚洲欧洲日产国码二区| 性少妇bbw张开| 成人一区二区三区中文字幕| 亚洲最大成人在线观看| 夜夜嗨av一区二区三区网站四季av| 亚洲免费精品视频| 久久97视频| 国产精品一区二区三区在线观| 日本成人一区二区| 日韩免费中文字幕| zzzwww在线看片免费| 久久精品国产亚洲精品2020| 国产片在线观看| 日韩av在线看| 老司机午夜福利视频| 91麻豆精品国产自产在线 | 日产精品一线二线三线芒果| 国产欧美三级电影| 亚洲综合中文字幕在线| 亚洲欧美专区| 91精品久久久久久久久不口人| 三级成人黄色影院| 91精品国产精品| segui88久久综合| 欧美激情精品久久久久久变态| 欧美jizzhd欧美| 色777狠狠综合秋免鲁丝| 福利在线观看| 国产一区二区成人| 日本aaa在线观看| 日韩av在线天堂网| 深爱激情五月婷婷| 亚洲护士老师的毛茸茸最新章节| 成人午夜免费在线观看| 欧美大片顶级少妇| 亚洲精品视频专区| 精品成人私密视频| 好吊色视频一区二区| 亚洲成年网站在线观看| 男人天堂手机在线观看| 亚洲精品一区二区三区精华液| 成人久久久精品国产乱码一区二区 | 中文字幕中文在线| 麻豆精品久久精品色综合| 少妇一级淫免费播放| 久久99国产精品成人| 国产又粗又长又爽又黄的视频| 国产精品亚洲午夜一区二区三区 | 欧美高清第一页| 日本h片在线| 久久久久亚洲精品| 黄视频免费在线看| 国产精品1234| 欧美成人三级| 97人人澡人人爽| 青青一区二区| 日韩欧美激情一区二区| 成人影视亚洲图片在线| 中文字幕中文字幕99| 亚洲九九在线| 欧美精品久久久久久久久久久| 亚洲中字在线| mm131亚洲精品| 国产精品99久久久| 玖玖爱在线精品视频| 久久久久久99精品| 欧美激情精品久久久久久免费| 一区二区三区在线影院| 日韩久久久久久久久| 91福利视频久久久久| 国产又大又长又粗| 亚洲国产精久久久久久| 成人精品一区| 欧美精品久久久久| 8av国产精品爽爽ⅴa在线观看| 91美女高潮出水| 欧美影院天天5g天天爽| 新呦u视频一区二区| 欧美日韩视频| 欧美少妇性生活视频| 国产另类ts人妖一区二区| 五级黄高潮片90分钟视频| 国产精品乱码久久久久久| 精品少妇久久久| 欧美日韩亚洲综合一区 | 这里只有精品在线播放| 欧美黄色视屏| 国产精品久久久av久久久| 三级欧美日韩| 亚洲精品人成| 日韩一区二区免费看| 中文字幕国产免费| av动漫一区二区| 日韩a级片在线观看| 91成人在线免费观看| 成人久久久精品国产乱码一区二区| 一区二区欧美在线| 黄在线观看免费网站ktv| 91免费看片在线| 香蕉久久精品日日躁夜夜躁| 日本三级中文字幕在线观看| 日本成人在线一区| 亚洲av成人片色在线观看高潮| 亚洲丝袜制服诱惑| 成人一二三四区| 亚洲国产精品字幕| 国产黄色小视频在线| 国产极品jizzhd欧美| 免费成人蒂法| 国产aaa免费视频| 狠狠色丁香婷婷综合| 美国美女黄色片| 欧美视频中文字幕在线| 人成网站在线观看| 九九久久久久久久久激情| 欧洲美女精品免费观看视频 | 国产精品一区二区婷婷| 51视频国产精品一区二区| 91麻豆精品激情在线观看最新 | 朝桐光av在线| 在线不卡a资源高清| 国产黄在线观看| 国产精品18久久久久久麻辣| 牛牛影视一区二区三区免费看| 欧美视频在线第一页| 国产精品亚洲综合一区在线观看| 免费成人美女女在线观看| 欧美日韩一级二级三级| а天堂8中文最新版在线官网| 欧美亚洲另类视频| 欧美在线导航| 国产极品粉嫩福利姬萌白酱| av福利精品导航| 五月天综合激情网| 亚洲精品美女在线观看| 电影在线观看一区| 精品欧美日韩| 久久精品一区| 免费看91的网站| 欧美亚洲精品一区| 91xxx在线观看| 国产精自产拍久久久久久蜜| 日韩黄色大片| 色偷偷中文字幕| 亚洲精品综合在线| 亚洲国产精品视频在线| 亚洲91av视频| 四虎5151久久欧美毛片| 成年人网站大全| 国产精品天天看| 国产人妖在线播放| 欧美日韩国产第一页| 哺乳挤奶一区二区三区免费看| 日本a视频在线观看| 91丨porny丨国产| 国产在线观看第一页| 中文字幕日韩有码| 欧美日韩午夜电影网| 欧美精品久久久久久久久久久| 99精品视频中文字幕| 波多野结衣一区二区在线| 色妞欧美日韩在线| 日韩中文字幕无砖| 国产美女无遮挡网站| 中日韩免费视频中文字幕| 99精品在线视频观看| 97在线精品视频| 成人高清电影网站| 深夜做爰性大片蜜桃| 亚洲成av人**亚洲成av**| 美女做暖暖视频免费在线观看全部网址91 | 亚洲一区欧美在线| 亚洲最新av在线| 亚洲午夜免费| 国产成人无码一二三区视频| 国产精品国产成人国产三级 | 国产婷婷一区二区三区| 久久久久久久综合日本| 91丨porny丨在线中文| 97香蕉久久夜色精品国产| 日韩欧美视频在线播放| 久久性爱视频网站| 欧美日韩一区二区在线观看| 成人超碰在线| 亚洲午夜久久久影院伊人| 成人精品视频网站| 在线观看中文字幕av| 久久久亚洲影院| 999精品视频| 三级男人添奶爽爽爽视频| 制服丝袜日韩国产| 不卡一二三区| 99久久免费观看| 中文字幕成人av| 少妇精品视频一区二区| 国产日韩精品入口|