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

NameNode是用了什么神秘技術來支撐元數據百萬并發讀寫的

大數據
我們都知道,HDFS 是大數據存儲的基石,所有的離線數據都存儲在 HDFS 上,而 NameNode 是存儲所有元數據的地方(所謂元數據就是描述數據的數據,比如文件的大小,文件都存儲在哪些 DataNode 上,文件在目錄樹的位置等),所以 NameNode 便成為了 HDFS 最關鍵的部分。

 [[390083]]

本文轉載自微信公眾號「KK架構師」,作者wangkai。轉載本文請聯系KK架構師公眾號。  

本文大綱 

一、HDFS 是大數據的基石

我們都知道,HDFS 是大數據存儲的基石,所有的離線數據都存儲在 HDFS 上,而 NameNode 是存儲所有元數據的地方(所謂元數據就是描述數據的數據,比如文件的大小,文件都存儲在哪些 DataNode 上,文件在目錄樹的位置等),所以 NameNode 便成為了 HDFS 最關鍵的部分。

在離線數倉中,會存在很多離線任務,這些離線任務都要往 HDFS 寫數據,每次寫數據都會經過 NameNode 來保存元數據信息,那么 NameNode 勢必會承擔非常多的請求。NameNode 作為 HDFS 的核心,肯定自身要保證高可用,數據不能一直在內存中,要寫到磁盤里。

所以一個關鍵的問題來了,NameNode 是用了什么神秘的技術,在保證自身高可用的同時,還能承擔巨額的讀寫請求?

二、NameNode 高可用是如何實現的

下面直接來一個 NameNode 高可用的架構圖:

然后解釋下如何保證高可用的:

(1)NameNode 只有一個時的單點故障問題

如果我們只部署了一個 NameNode,那么這個 NameNode 是有單點故障的問題的。如何解決,再加一個 NameNode 即可;

(2)當有兩個 NameNode ,切換時,數據如何保持同步

兩個 NameNode 一起工作,某一個 NameNode 掛掉了,另一個 NameNode 接替工作,這件事成立的必要前提是,兩個 NameNode 的數據得時時刻刻保持一致。

那么如何保持數據一致,是不是可以在兩個 NameNode 之間搞個共享的文件系統?仔細想想也不行,這樣的話,單點故障問題就轉移到這個文件系統上了。

(3)使用多節點的 JournalNode 作為主備 NameNode 的數據同步介質

這里引入了 JournalNode 集群,JournalNode 的每個節點的數據都是一樣的,并且時刻保持一致。并且只要超過半數的節點存活,整個 JournalNode 集群都可以正常提供服務。

所以,一般會使用奇數個節點來搭建。(為什么一般不用偶數個呢?因為 3 個節點構成的集群,可以容忍掛掉一臺機器;而 4 個節點構成的集群,也只能容忍掛掉一臺機器。同樣是只能掛掉一臺,為何不選 3 個節點的呢,還能節省資源)。

使用 JournalNode 集群,一個 NameNode 實時的往集群寫,另一個 NameNode 也實時的讀集群數據,這樣兩個 NameNode 數據就可以保持一致了。

(4)一個 NameNode 掛掉,另一個 NameNode 如何立馬感知并接替工作

首先不能人工參與切換。那如何實時監聽呢?

首先要再引入一個關鍵組件:Zookeeper。當兩個 NameNode 同時啟動后,他們都會去 Zookeeper 上注冊,誰注冊成功了,誰就能獲得鎖,成為 Active 狀態的 NameNode。

另外還需要一個組件:ZKFC,它會實時監控 Zookeeper 進程狀態,并且會以心跳的方式實時的告訴 Zookeeper NameNode 的狀態。如果一個 NameNode 進程掛了,就會把 Zookeeper 上的鎖給另外一個 NameNode,讓它成為 Active 的來工作。

三、NameNode 如何既高可用,還能高并發

1、雙緩沖技術

NameNode 為了實現高可用,首先自己內存里的數據需要寫到磁盤,然后還需要往 JournalNode 里寫數據。

所以既然要寫磁盤,還是往兩個地方寫磁盤,那必然性能會跟不上的。

所以這里 NameNode 引入了一個技術,也是本篇文章的重點:雙緩沖技術。

雙緩沖的設計理念如下圖:

客戶端不是直接寫磁盤,而是往一個內存結構(Buffer1)里面寫數據。當 Buffer1 達到一定閾值后,Buffer 1 和 Buffer 2 交換內存數據。此時 Buffer1 數據為空,Buffer2 開始在后臺默默寫磁盤。

這樣的好處很明顯的,前端只需要進行內存寫 Buffer1 就行,性能特別高;而 Buffer2 在后臺默默的同步日志到磁盤即可。

這樣磁盤寫,就轉化成為了內存寫,速度大大提高了。

2、如何實現雙緩沖

然而,在真實環境不只一個客戶端是這樣子的:

大數據情況下是 N 個客戶端同時并發寫的,在高并發的情況下,我們必然要去協調多個線程動作的一致性,比如往 Buffer1 的寫動作,Buffer1 與 Buffer2 數據交換的動作,Buffer2 寫磁盤的動作。

那么我們該如何實現這樣一個巧妙的雙緩沖呢?下面的代碼是我從 Hadoop 源碼里抽離出來的關鍵實現:

  1. package org.apache.hadoop; 
  2.  
  3. import java.util.LinkedList; 
  4.  
  5. public class FSEditLog2 { 
  6.     private long txid=0L; 
  7.     private DoubleBuffer editLogBuffer=new DoubleBuffer(); 
  8.     //是否正在刷寫磁盤 
  9.     private volatile Boolean isSyncRunning = false
  10.     private volatile Boolean isWaitSync = false
  11.  
  12.     private volatile Long syncMaxTxid = 0L; 
  13.  
  14.     //每個線程都對應自己的一個副本 
  15.     private ThreadLocal<Long> localTxid=new ThreadLocal<Long>(); 
  16.  
  17.     public void logEdit(String content){//mkdir /a 
  18.         synchronized (this){//加鎖的目的就是為了事務ID的唯一,而且是遞增 
  19.             txid++; 
  20.             localTxid.set(txid); 
  21.             EditLog log = new EditLog(txid, content); 
  22.             editLogBuffer.write(log); 
  23.         } 
  24.         logSync(); 
  25.     } 
  26.  
  27.     private  void logSync(){ 
  28.         synchronized (this){ 
  29.             if(isSyncRunning){ //是否有人正在把數據同步到磁盤上面 
  30.                 long txid = localTxid.get(); 
  31.                 if(txid <= syncMaxTxid){ 
  32.                     //直接return,不接著干了? 
  33.                     return
  34.                 } 
  35.                 if(isWaitSync){ 
  36.                     return
  37.                 } 
  38.                 isWaitSync = true
  39.  
  40.                 while(isSyncRunning){ 
  41.                     try { 
  42.                         wait(2000); 
  43.                     }catch (Exception e){ 
  44.                         e.printStackTrace(); 
  45.                     } 
  46.                 } 
  47.                 isWaitSync = false
  48.             } 
  49.  
  50.             editLogBuffer.setReadyToSync(); 
  51.             if(editLogBuffer.syncBuffer.size() > 0) { 
  52.                 syncMaxTxid = editLogBuffer.getSyncMaxTxid(); 
  53.             } 
  54.  
  55.             isSyncRunning = true
  56.  
  57.         } //釋放鎖 
  58.  
  59.         editLogBuffer.flush(); 
  60.         synchronized (this) { 
  61.             isSyncRunning = false
  62.             notify(); 
  63.         } //釋放鎖 
  64.     } 
  65.  
  66.  
  67.     /** 
  68.      * 把日志抽象成類 
  69.      */ 
  70.     class EditLog{ 
  71.         //順序遞增 
  72.         long txid; 
  73.         //操作內容  mkdir /a 
  74.         String content; 
  75.  
  76.         //構造函數 
  77.         public EditLog(long txid,String content){ 
  78.             this.txid = txid; 
  79.             this.content = content; 
  80.         } 
  81.  
  82.         //為了測試方便 
  83.         @Override 
  84.         public String toString() { 
  85.             return "EditLog{" + 
  86.                     "txid=" + txid + 
  87.                     ", content='" + content + '\'' + 
  88.                     '}'
  89.         } 
  90.     } 
  91.  
  92.  
  93.     /** 
  94.      * 雙緩存方案 
  95.      */ 
  96.     class DoubleBuffer{ 
  97.         //內存1 
  98.         LinkedList<EditLog> currentBuffer = new LinkedList<EditLog>(); 
  99.         //內存2 
  100.         LinkedList<EditLog> syncBuffer= new LinkedList<EditLog>(); 
  101.  
  102.         /** 
  103.          * 把數據寫到當前內存1 
  104.          * @param log 
  105.          */ 
  106.         public void write(EditLog log){ 
  107.             currentBuffer.add(log); 
  108.         } 
  109.  
  110.         /** 
  111.          * 交換內存 
  112.          */ 
  113.         public void setReadyToSync(){ 
  114.             LinkedList<EditLog> tmp= currentBuffer; 
  115.             currentBuffer = syncBuffer; 
  116.             syncBuffer = tmp; 
  117.         } 
  118.  
  119.         /** 
  120.          * 獲取內存2里面的日志的最大的事務編號 
  121.          * @return 
  122.          */ 
  123.         public Long getSyncMaxTxid(){ 
  124.             return syncBuffer.getLast().txid; 
  125.         } 
  126.  
  127.  
  128.         /** 
  129.          * 刷寫磁盤 
  130.           */ 
  131.         public void flush(){ 
  132.             for(EditLog log:syncBuffer){ 
  133.                 //把數據寫到磁盤上 
  134.                 System.out.println("存入磁盤日志信息:"+log); 
  135.             } 
  136.  
  137.             //把內存2里面的數據要清空 
  138.             syncBuffer.clear(); 
  139.         } 
  140.     } 

主要的業務邏輯就是 40 行,但是真的很巧妙。

1、EditLog

我們先看這個 EditLog 內部類,這是對 EditLog 日志的一個封裝,就兩個屬性 txid 和 content,分別是日志的事務id(保證唯一性)和 內容。

2、DoubleBuffer

再看這個 DoubleBuffer 雙緩沖類,很簡單,就是在內存里面維護了兩個有序的 LinkedList,分別是當前寫編輯日志的緩沖和同步到磁盤的緩沖,其中的元素就是 EditLog 類。

write 方法就是把一條編輯日志寫到當前緩沖里。

setReadyToSync 方法,就是交換兩個緩沖,也是最簡單的剛學習 Java 就學習過的兩個變量交換值的方法。

getSyncMaxTxid 方法,獲得正在同步的那個緩沖去里的最大的事務id。

flush 方法,遍歷同步的緩沖的每一條編輯日志,寫到磁盤,并最終清空緩沖區內容。

3、主類的一些屬性說明

(1)全局的事務id

private long txid=0L;

(2)雙緩沖結構

private DoubleBuffer editLogBuffer=new DoubleBuffer();

(3)控制變量

private volatile Boolean isSyncRunning = false; // 是否正在同步數據到磁盤

private volatile Boolean isWaitSync = false; // 是否有線程在等待同步數據到磁盤完成

private volatile Long syncMaxTxid = 0L; // 當前同步的最大日志事務id

private ThreadLocallocalTxid=new ThreadLocal(); // 每個線程的線程副本,用來放本線程當前寫入的日志事務id

(4)主邏輯 logEdit 方法

這個方法是對外暴露的方法,客戶端往雙緩沖寫數據就是用的這個方法。

假設當前有一個線程1 進到了 logEdit 方法,首先直接把當前類實例加鎖,避免別的線程進來,以此來保證編輯日志事務id的唯一自增性。

  1. // 全局事務遞增 
  2. txid++; 
  3. // 往線程本身的變量里設置事務id值 
  4. localTxid.set(txid); 
  5. // 構造 EditLog 變量 
  6. EditLog log = new EditLog(txid, content); 
  7. // 寫入當前的 Buffer 
  8. editLogBuffer.write(log); 

當它執行完了這些之后,釋放鎖,開始執行 logSync() 方法。此時由于釋放了鎖,于是很多線程開始拿到鎖,進入了這個方法中。

假設有五個線程進來了分別寫了一條日志,于是現在雙緩沖是這樣子的:

好,然后線程1 開始進入 logSync 方法,第一步就是使用當前類的實例加了鎖,保證只有一個線程進來。

檢查 isSyncRunning 變量是否為 true,目前是 false,跳過這個方法。

開始執行這個 editLogBuffer.setReadyToSync(); 方法,于是雙緩沖的數據直接被交換了。

然后獲得了全局最大的id,當前是 5,賦值給了 syncMaxTxid 變量

  1. if(editLogBuffer.syncBuffer.size() > 0) { 
  2.     syncMaxTxid = editLogBuffer.getSyncMaxTxid(); 

然后 isSyncRunning = true; 把這個變量置為 true,表示正在同步數據到磁盤。此時釋放鎖。

然后 線程 1 開始執行數據同步到磁盤的動作:editLogBuffer.flush() ,這個動作肯定耗費的時間比較久,基本是在 ms 級別。

此時我們假設 線程2 爭搶到了鎖,進入到了 logSync 方法。

  1. // 線程2 判斷 是否有人正在把數據同步到磁盤上面,這個值被線程 1 改為 true 了 
  2. // 進入到 if 方法 
  3. if(isSyncRunning){  
  4.     // 獲得到自己線程的事務id,為 2 
  5.     long txid = localTxid.get(); 
  6.     // 2 是否小于 5 ?小于,直接返回,因為此時 5 已經正在被同步到磁盤了 
  7.     if(txid <= syncMaxTxid){ 
  8.         return
  9.     } 
  10.     if(isWaitSync){ 
  11.         return
  12.     } 
  13.     isWaitSync = true
  14.  
  15.     while(isSyncRunning){ 
  16.         try { 
  17.             wait(2000); 
  18.         }catch (Exception e){ 
  19.             e.printStackTrace(); 
  20.         } 
  21.     } 
  22.     isWaitSync = false

線程2 由于自身的編輯日志的事務id 小于當前正在同步的最大的事務id,所以直接返回了,然后線程3 ,線程4,線程5 進來都是這樣,直接 return 返回。

假設線程6 此時進來,當前雙緩沖狀態是這樣的

下面線程 6 干的活,參考下面代碼里的注釋:

  1. // 線程6 判斷是否有人正在把數據同步到磁盤上面,這個值被線程 1 改為 true 了 
  2. // 進入到 if 方法 
  3. if(isSyncRunning){  
  4.     // 獲得到自己線程的事務id,為 6 
  5.     long txid = localTxid.get(); 
  6.     // 6 是否小于 5 ,不小于繼續執行 
  7.     if(txid <= syncMaxTxid){ 
  8.         return
  9.     } 
  10.     // 這個值為 false,繼續執行 
  11.     if(isWaitSync){ 
  12.         return
  13.     } 
  14.     // 把 isWaitSync 設置為 true 
  15.     isWaitSync = true
  16.  
  17.     // 這個值被線程1置為了 true,所以這里在死循環 
  18.     while(isSyncRunning){ 
  19.         try { 
  20.             // 等待 2s,wait 會釋放鎖,同時線程 6 進入睡眠中 
  21.             wait(2000); 
  22.         }catch (Exception e){ 
  23.             e.printStackTrace(); 
  24.         } 
  25.     } 
  26.     isWaitSync = false

可以看到 線程 6 在 while 循環里無限等待數據同步到磁盤完畢。然后由于線程 6 把 isWaitSync 值改為了 true,線程 6 在等待期間釋放鎖,被其他線程搶到之后,其他線程由于 isWaitSync 為true,直接返回了。

當過了一會兒,線程1 把第二個 Buffer 同步到磁盤完畢后,線程1 會執行這些代碼

  1. synchronized (this) { 
  2.     isSyncRunning = false
  3.     notify(); 
  4. } //釋放鎖 

把 isSyncRunning 變量置為 false,同時調用 notify(),通知線程 6 ,你可以繼續參與鎖的競爭了。

然后線程6 ,從 wait 中醒來,重新參與鎖競爭,繼續執行接下來的代碼。此時 isSyncRunning 已經為 false,所以它跳出了 while 循環,把 isWaitSync 置為了 false。

然后它開始執行:交換緩沖區,給最大的事務id(此時為6 )賦值,把 isSyncRunning 賦值為 true。

  1. editLogBuffer.setReadyToSync(); 
  2. if(editLogBuffer.syncBuffer.size() > 0) { 
  3.     syncMaxTxid = editLogBuffer.getSyncMaxTxid(); 
  4.  
  5. isSyncRunning = true

執行完了之后,釋放鎖,開始執行Buffer2 的同步。然后所有的線程就按照上面的方式有序的工作。

這段幾十行的代碼很精煉,值得反復推敲,總結下來如下:

(1)寫緩沖到內存 和 同步數據到磁盤分開,互不影響和干擾;

(2)使用 synchronize ,wait 和 notify 來保證多線程有序進行工作;

(3)當在同步數據到磁盤中的時候,其他爭搶到鎖進來準備同步數據的線程只能等待;

(4)線程使用 ThreadLocal 變量,來記錄自身當前的事務id,如果小于當前正在同步的最大事務id,則不同步;

(5)有線程在等待同步數據的時候,其他線程寫完 editLog 到內存后直接返回;

四、最后的總結

本文詳細探討了 HDFS 在大數據中基石的地位,以及如何保障 NameNode 高可用的運行。

NameNode 在高可用運行時,同時是如何保證高并發讀寫操作的。雙緩沖在其中起到了核心的作用,把寫數據和同步數據到磁盤分離開,互不影響。

同時我們還剝離了一段核心雙緩沖的實現代碼,仔細分析了實現原理。這短短的幾十行代碼,可謂綜合利用了多線程高并發的知識,耐人尋味。

 

責任編輯:武曉燕 來源: KK架構師
相關推薦

2019-09-23 08:46:04

零拷貝 CPU內存

2019-02-27 09:46:05

數據庫架構并發

2025-11-14 00:25:00

微服務架構并發

2011-08-23 17:12:22

MySQL支撐百萬級流

2019-09-23 13:03:42

NameNode元數據文件

2019-05-06 11:12:18

Redis高并發單線程

2021-04-25 19:00:55

大數據視頻分析人工智能

2017-11-10 09:16:07

直播彈幕系統

2019-12-31 10:33:57

Netty高性能內存

2023-10-25 11:20:09

快手電商混合云容器云

2019-10-16 17:03:22

架構技術棧微信半月刊

2019-07-18 08:10:01

Java開發代碼

2022-08-19 06:42:11

數據庫高并系統

2019-10-11 10:23:13

ClassLoaderJavaJVM

2022-01-14 11:54:15

區塊鏈元宇宙技術

2019-05-07 09:44:45

Redis高并發模型

2025-02-10 08:20:09

2020-11-01 19:00:55

開源區塊鏈區塊鏈技術

2020-10-30 16:20:38

Redis單線程高并發

2022-07-03 14:06:27

元宇宙交互技術AR
點贊
收藏

51CTO技術棧公眾號

五月天婷婷激情网| 亚洲a∨无码无在线观看| 污片在线免费观看| 国产高清亚洲一区| 97在线视频一区| 中文字幕第20页| 国产传媒在线| 26uuu色噜噜精品一区二区| 国产精品极品美女在线观看免费 | 亚洲精品v天堂中文字幕| 蜜桃网站在线观看| 国产精品丝袜黑色高跟鞋| 你懂的国产精品| 亚洲国产成人精品久久| 中文字幕乱码人妻综合二区三区| 岛国大片在线观看| 国产一区二区在线观看免费| 欧美激情视频在线观看| 国产中文字幕一区二区| 91成人在线| 一区二区三区美女视频| 久久久精品国产一区二区三区| 久久精品视频2| 91视频精品| 亚洲缚视频在线观看| 一区二区三区韩国| 色帝国亚洲欧美在线| 91色|porny| 成人黄色午夜影院| wwwwww国产| 一个色综合网| 亚洲欧美制服另类日韩| 伊人国产精品视频| 欧洲av一区二区| 亚洲国产wwwccc36天堂| 明星裸体视频一区二区| 96亚洲精品久久久蜜桃| 国产农村妇女精品一二区 | 婷婷免费在线视频| 波多野结衣中文一区| 国产精品久久久久久久7电影| 极品颜值美女露脸啪啪| 久久爱www成人| 精品国产乱码久久久久久牛牛| 国产高清视频网站| 女人高潮被爽到呻吟在线观看| 综合久久给合久久狠狠狠97色 | 亚洲精品综合网| 另类欧美日韩国产在线| 色综合久久悠悠| 激情综合丁香五月| 97一区二区国产好的精华液| 欧美日韩第一区日日骚| 99色精品视频| 国产黄色大片在线观看| 亚洲欧洲三级电影| 丝袜美腿玉足3d专区一区| 少妇高潮一区二区三区69| 国产激情偷乱视频一区二区三区| 国产精品美乳一区二区免费| 六月丁香在线视频| 欧美日本一区二区视频在线观看 | 99re在线观看视频| 国产又黄又粗又猛又爽| 青娱乐精品在线视频| 欧美在线视频网站| 欧产日产国产v| 亚洲国产精品日韩专区av有中文| 中文字幕亚洲欧美日韩高清| 91视频免费观看网站| 欧美三级午夜理伦三级小说| 精品电影一区二区| 色悠悠在线视频| 国产一区在线电影| 337p日本欧洲亚洲大胆精品 | 成人久久视频在线观看| 不卡日韩av| 亚洲av无码一区二区三区dv | 国产精品视频一区二区三区四| 天天操夜夜操视频| 欧美专区一区二区三区| 日韩免费在线视频| 日韩乱码一区二区三区| 日本不卡一区二区| 成人有码在线视频| www.看毛片| 成人黄色av网站在线| 好吊色欧美一区二区三区视频| 亚洲欧美另类日韩| 99久久精品免费观看| 久久国产精品99久久久久久丝袜| 神马精品久久| 国产三级欧美三级日产三级99| 日韩性感在线| 蜜桃视频在线观看免费视频网站www| 一区在线观看免费| 一区二区三区三区在线| 国产三级视频在线| 国产精品夫妻自拍| xxxxxx在线观看| 成人国产电影在线观看| 日韩欧美亚洲综合| 高潮一区二区三区| 网站一区二区| 亚洲久久久久久久久久| 欧美亚洲色综久久精品国产| 999精品一区| 欧美乱大交做爰xxxⅹ性3| 日本一级淫片免费放| 日韩在线观看一区二区| 91免费版网站入口| 手机在线观看免费av| 欧美韩国日本不卡| 久久福利一区二区| 中文字幕人成乱码在线观看| 欧美日韩在线一区二区| 日本人妻一区二区三区| sdde在线播放一区二区| 欧美激情第99页| 国产免费www| 国产精品一卡二卡在线观看| 欧美精品一区在线| 国产黄网站在线观看| 午夜精品久久一牛影视| 一级黄色特级片| 国产+成+人+亚洲欧洲在线 | 无码人妻aⅴ一区二区三区| 欧美精选视频在线观看| 高清欧美一区二区三区| 久久久国产精品成人免费| 激情综合色播五月| 蜜桃麻豆91| 香蕉成人app免费看片| 欧美性开放视频| 欧美体内she精高潮| 国产不卡一二三区| 韩国一区二区电影| 91美女精品网站| 91在线视频在线| 五月天激情图片| 成人全视频在线观看在线播放高清 | 超级白嫩亚洲国产第一| 在线播放中文字幕一区| 老鸭窝一区二区| 国模 一区 二区 三区| 国产精品专区h在线观看| 无码精品视频一区二区三区| 尤物在线观看一区| 老司机久久精品| 欧美精品色图| 国产999在线观看| 天堂а√在线8种子蜜桃视频| 亚洲精品伦理在线| 三上悠亚在线一区| 国产精品亚洲片在线播放| 高清在线视频日韩欧美| 成人激情四射网| ●精品国产综合乱码久久久久| 狠狠操精品视频| 伊人久久综合影院| 欧美亚洲另类激情另类| 蜜桃91麻豆精品一二三区| 亚洲精品视频观看| 亚洲高清av一区二区三区| 天天天综合网| 成人a在线视频| 日本成a人片在线观看| 欧美婷婷六月丁香综合色| 日韩 中文字幕| 男女精品网站| 欧美在线播放一区| 新片速递亚洲合集欧美合集| 日韩国产一区三区| 国产做受高潮漫动| 99久精品国产| 黄色免费视频大全| 曰本一区二区三区视频| 日产精品久久久一区二区福利| 五月激情六月婷婷| 日韩欧美国产视频| 国产精品第七页| 亚洲一级在线| 午夜欧美一区二区三区免费观看| 视频在线日韩| 久久久精品网站| www.综合色| 第一福利永久视频精品| 乐播av一区二区三区| 视频一区二区中文字幕| 亚洲精品国产精品久久| 日本欧美在线| 欧美激情精品久久久久久变态| 丰满人妻一区二区| 欧美午夜精品久久久久久人妖| xxxxx在线观看| 蜜桃久久久久久| 国产成人永久免费视频| 精品国产中文字幕第一页| 91精品久久久久久久久久| 香蕉视频在线播放| 5月丁香婷婷综合| 久久精品免费在线| 国产无一区二区| 五月花丁香婷婷| 亚洲国产专区| 相泽南亚洲一区二区在线播放 | 在线观看日韩国产| 999精品在线视频| 成人一区在线观看| 亚洲熟妇av一区二区三区| 欧美日韩一二| 国内精品国语自产拍在线观看| av一区在线| 欧美日韩国产二区| 春暖花开成人亚洲区| 日韩欧美亚洲国产另类| 亚洲精品男人天堂| 亚洲欧美日韩国产综合在线| 朝桐光av一区二区三区| 久久国产夜色精品鲁鲁99| aa视频在线播放| 97在线精品| 久久精品中文字幕一区二区三区 | 国产男女无套免费网站| 精品久久久久久久久久国产| 国产精久久一区二区三区| 国产福利一区二区三区在线视频| 日本老熟妇毛茸茸| 国内自拍视频一区二区三区| 天天综合色天天综合色hd| 成人精品动漫一区二区三区| 国产精自产拍久久久久久| 日本乱码一区二区三区不卡| 久久影视电视剧免费网站清宫辞电视 | 高清一区二区三区视频| 高清亚洲高清| 日韩av三级在线观看| 福利成人导航| 久久九九精品99国产精品| 国产视频网站在线| 精品1区2区在线观看| 国产一区二区在线不卡| 在线观看区一区二| aaaaaa毛片| 丰满岳妇乱一区二区三区| 久久精品一区二区三| 国产天堂亚洲国产碰碰| 日韩成人av一区二区| 国产成人av一区二区三区在线观看| 538在线视频观看| 久久在线精品| 妺妺窝人体色www在线小说| 一区福利视频| 日韩一级特黄毛片| 欧美激情第二页| 免费看av软件| 欧美久久精品一级c片| 欧美一区亚洲二区| 蜜臀av免费一区二区三区| 久久精品第九区免费观看 | 日韩女优在线视频| 国产黄色精品视频| 深夜福利网站在线观看| 国产一区二区三区精品视频| 天堂在线中文在线| 激情综合一区二区三区| www.污网站| 国内一区二区视频| 男人舔女人下面高潮视频| 免费精品视频| 国产精品无码av无码| 日韩国产在线观看一区| 校园春色 亚洲色图| 蜜桃视频一区| 黄色三级视频在线| 另类小说视频一区二区| 一本一道久久a久久综合蜜桃| 美女视频黄a大片欧美| 日本一二区免费| 国产一区二区不卡| 在线观看亚洲免费视频| 99精品视频在线免费观看| 性生活一级大片| 粉嫩av一区二区三区粉嫩| 精品国产一区在线| 久久久亚洲欧洲日产国码αv| av网站免费在线看| 国产精品国产三级国产普通话三级| 中文字幕无码日韩专区免费| 亚洲永久精品大片| 欧美三级一区二区三区| 极品白浆推特女神在线观看| 日韩一级视频免费观看在线| 天天av天天翘| 久久精品国产清自在天天线| 国产精品原创| 成人写真福利网| 久久99视频| 国产精品久久久久久久久电影网| 99在线观看免费视频精品观看| 色播五月综合网| 99精品欧美一区二区三区小说| 蜜桃av.com| 色婷婷综合在线| 亚洲精品国产av| 色一情一乱一区二区| 激情国产在线| 成人欧美一区二区三区视频 | jizzyou欧美16| 精品91免费| 欧美a级片一区| 999在线观看| 久久久久久免费| www.av视频在线观看| 91精品国产高清一区二区三区蜜臀| 午夜视频www| 色综合天天狠天天透天天伊人| 韩国精品主播一区二区在线观看| 国产欧美日韩一区| 一区二区中文字| 欧美成人黄色网址| 久久综合精品国产一区二区三区| 久草免费新视频| 欧美视频完全免费看| 欧洲天堂在线观看| 91高清在线免费观看| 日韩一区二区三区色| 在线观看欧美亚洲| 日韩电影一区二区三区四区| 日韩av一二区| 精品国产福利在线| 黄色aaa毛片| 欧美高清视频一区二区| 亚洲福利合集| 91国在线高清视频| 国产激情视频一区二区在线观看 | 激情小视频在线| 欧美在线影院在线视频| 天天躁日日躁狠狠躁欧美| 麻豆tv在线播放| 成人精品小蝌蚪| 欧美成人aaa片一区国产精品| 91麻豆精品国产无毒不卡在线观看 | 欧美日韩破处视频| 在线不卡日本| 蜜桃av一区二区| 国产精品视频看看| 欧美精品在线观看一区二区| 麻豆网站在线看| 91精品视频免费观看| 一级欧洲+日本+国产| 色婷婷狠狠18禁久久| 亚洲一二三四在线观看| 老牛影视av牛牛影视av| 久久久亚洲影院你懂的| 老汉色老汉首页av亚洲| 免费黄色日本网站| 久久久99精品久久| 中文 欧美 日韩| 俺去亚洲欧洲欧美日韩| 久久国际精品| 蜜臀av色欲a片无码精品一区| 91亚洲精品久久久蜜桃网站| 天天干在线播放| 最好看的2019的中文字幕视频| 狂野欧美性猛交xxxx| 亚洲国产精品女人| 成人久久视频在线观看| 成人av网站在线播放| 日韩最新av在线| 免费一区二区三区在线视频| www.好吊操| 91偷拍与自偷拍精品| 亚洲中文字幕在线观看| 美女999久久久精品视频| 精品在线网站观看| 男人插女人下面免费视频| 亚洲人成在线播放网站岛国 | 懂色av一区二区三区蜜臀| 日本三级一区二区| 中文字幕精品一区二区精品| 国产亚洲字幕| www.爱色av.com| 《视频一区视频二区| 天天av天天翘| 成人做爰www免费看视频网站| 在线免费高清一区二区三区| www亚洲色图| 精品国产3级a| 美女久久久久久| 国产精品333| 亚洲色图在线播放| 欧美成人综合在线| 99re6在线| 日一区二区三区| 强乱中文字幕av一区乱码| 亚洲欧洲中文天堂| 成人福利一区| 15—17女人毛片| 狠狠做深爱婷婷久久综合一区|