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

分布式協調框架Zookeeper核心設計理解與實戰

大數據 分布式
想起很久以前在某個客戶現場,微服務 B 突然無法調用到微服務 A,為了使服務盡快正常恢復,重啟了微服務 B 。雖然故障原因找到了,但對于 Zookeeper 的理解還是不夠深刻,于是重新學習了 Zookeeper 的核心設計,并記錄于此文共勉。

[[413943]]

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

一、前言

想起很久以前在某個客戶現場,微服務 B 突然無法調用到微服務 A,為了使服務盡快正常恢復,重啟了微服務 B 。

但客戶不依不饒詢問這個問題出現的原因,于是我還大老遠從杭州飛到深圳,現場排查問題。

最后的結論是,zk 在某時刻出現主備切換,此時微服務 A(基于 dubbo)需要重新往 zk上注冊,但是端口號變了。

但是微服務 B 本地有微服務 A rpc 接口的緩存,緩存里面還是舊的端口,所以調用不到。

解決方法就是,把微服務的 rpc 端口號改成固定的。

雖說原因找到了,但對于 Zookeeper 的理解還是不夠深刻,于是重新學習了 Zookeeper 的核心設計,并記錄于此文共勉。

二、Zookeeper 核心架構設計

1、Zookeeper 特點

(1)Zookeeper 是一個分布式協調服務,是為了解決多個節點狀態不一致的問題,充當中間機構來調停。如果出現了不一致,則把這個不一致的情況寫入到 Zookeeper 中,Zookeeper 會返回響應,響應成功,則表示幫你達成了一致。

比如,A、B、C 節點在集群啟動時,需要推舉出一個主節點,這個時候,A、B、C 只要同時往 Zookeeper 上注冊臨時節點,誰先注冊成功,誰就是主節點。

(2)Zookeeper 雖然是一個集群,但是數據并不是分散存儲在各個節點上的,而是每個節點都保存了集群所有的數據。

其中一個節點作為主節點,提供分布式事務的寫服務,其他節點和這個節點同步數據,保持和主節點狀態一致。

(3)Zookeeper 所有節點的數據狀態通過 Zab 協議保持一致。當集群中沒有 Leader 節點時,內部會執行選舉,選舉結束,Follower 和 Leader 執行狀態同步;當有 Leader 節點時,Leader 通過 ZAB 協議主導分布式事務的執行,并且所有的事務都是串行執行的。

(4)Zookeeper 的節點個數是不能線性擴展的,節點越多,同步數據的壓力越大,執行分布式事務性能越差。推薦3、5、7 這樣的數目。

2、Zookeeper 角色的理解

Zookeeper 并沒有沿用 Master/Slave 概念,而是引入了 Leader,Follower,Observer 三種角色。

通過 Leader 選舉算法來選定一臺服務器充當 Leader 節點,Leader 服務器為客戶端提供讀、寫服務。

Follower 節點可以參加選舉,也可以接受客戶端的讀請求,但是接受到客戶端的寫請求時,會轉發到 Leader 服務器去處理。

Observer 角色只能提供讀服務,不能選舉和被選舉,所以它存在的意義是在不影響寫性能的前提下,提升集群的讀性能。

3、Zookeeper 同時滿足了 CAP 嗎?

答案是否,CAP 只能同時滿足其二。

Zookeeper 是有取舍的,它實現了 A 可用性、P 分區容錯性、C 的寫入一致性,犧牲的是 C的讀一致性。

也就是說,Zookeeper 并不保證讀取的一定是最新的數據。如果一定要最新,需要使用 sync 回調處理。

三、核心機制一:ZNode 數據模型

Zookeeper 的 ZNode 模型其實可以理解為類文件系統,如下圖:

1、ZNode 并不適合存儲太大的數據

為什么是類文件系統呢?因為 ZNode 模型沒有文件和文件夾的概念,每個節點既可以有子節點,也可以存儲數據。

那么既然每個節點可以存儲數據,是不是可以任意存儲無限制的數據呢?答案是否定的。在 Zookeeper 中,限制了每個節點只能存儲小于 1 M 的數據,實際應用中,最好不要超過 1kb。

原因有以下四點:

  • 同步壓力:Zookeeper 的每個節點都存儲了 Zookeeper 的所有數據,每個節點的狀態都要保持和 Leader 一致,同步過程至少要保證半數以上的節點同步成功,才算最終成功。如果數據越大,則寫入的難度也越大。
  • 請求阻塞:Zookeeper 為了保證寫入的強一致性,會嚴格按照寫入的順序串行執行,某個時刻只能執行一個事務。如果上一個事務執行耗時比較長,會阻塞后面的請求;
  • 存儲壓力:正是因為每個 Zookeeper 的節點都存儲了完整的數據,每個 ZNode 存儲的數據越大,則消耗的物理內存也越大;
  • 設計初衷:Zookeeper 的設計初衷,不是為了提供大規模的存儲服務,而是提供了這樣的數據模型解決一些分布式問題。

2、ZNode 的分類

(1)按生命周期分類

按照聲明周期,ZNode 可分為永久節點和臨時節點。

很好理解,永久節點就是要顯示的刪除,否則會一直存在;臨時節點,是和會話綁定的,會話創建的所有節點,會在會話斷開連接時,全部被 Zookeeper 系統刪除。

(2)按照是否帶序列號分類

帶序列號的話,比如在代碼中創建 /a 節點,創建之后其實是 /a000000000000001,再創建的話,就是 /a000000000000002,依次遞增

不帶序號,就是創建什么就是什么

(3)所以,一共有四種 ZNode:

  • 永久的不帶序號的
  • 永久的帶序號的
  • 臨時的不帶序號的
  • 臨時的帶序號的

(4)注意的點

臨時節點下面不能掛載子節點,只能作為其他節點的葉子節點。

3. 代碼實戰

ZNode 的數據模型其實很簡單,只有這么多知識。下面用代碼來鞏固一下。

這里我們使用 curator 框架來做 demo。(當然,你可以選擇使用 Zookeeper 官方自帶的 Api)

引入 pom 坐標:

  1. <!-- curator-framework --> 
  2. <dependency> 
  3.     <groupId>org.apache.curator</groupId> 
  4.     <artifactId>curator-framework</artifactId> 
  5.     <version>4.2.0</version> 
  6. </dependency> 
  7. <!-- curator-recipes --> 
  8. <dependency> 
  9.     <groupId>org.apache.curator</groupId> 
  10.     <artifactId>curator-recipes</artifactId> 
  11.     <version>4.2.0</version> 
  12. </dependency> 

代碼:

  1. public class ZkTest { 
  2.  
  3.     // 會話超時 
  4.     private final int SESSION_TIMEOUT = 30 * 1000; 
  5.  
  6.     // 連接超時 、 有啥區別 
  7.     private static final int CONNECTION_TIMEOUT = 3 * 1000; 
  8.  
  9.     private static final String CONNECT_ADDR = "localhost:2181"
  10.  
  11.     private CuratorFramework client = null
  12.  
  13.     public static void main(String[] args) throws Exception { 
  14.         // 創建客戶端 
  15.         RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10); 
  16.         CuratorFramework client = CuratorFrameworkFactory.builder() 
  17.                 .connectString(CONNECT_ADDR) 
  18.                 .connectionTimeoutMs(CONNECTION_TIMEOUT) 
  19.                 .retryPolicy(retryPolicy) 
  20.                 .build(); 
  21.         client.start(); 
  22.         System.out.println(ZooKeeper.States.CONNECTED); 
  23.         System.out.println(client.getState()); 
  24.  
  25.         // 創建節點 /test1 
  26.         client.create() 
  27.                 .forPath("/test1""curator data".getBytes(StandardCharsets.UTF_8)); 
  28.  
  29.         System.out.println(client.getChildren().forPath("/")); 
  30.  
  31.         // 臨時節點 
  32.         client.create().withMode(CreateMode.EPHEMERAL) 
  33.                 .forPath("/secondPath""hello world".getBytes(StandardCharsets.UTF_8)); 
  34.         System.out.println(new String(client.getData().forPath("/secondPath"))); 
  35.  
  36.         client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL) 
  37.                 .forPath("/abc""hello".getBytes(StandardCharsets.UTF_8)); 
  38.         // 遞歸創建 
  39.         client.create() 
  40.                 .creatingParentContainersIfNeeded() 
  41.                 .forPath("/secondPath1/sencond2/sencond3"); 
  42.  
  43.  
  44.         Thread.sleep(10000); 
  45.     } 

四、核心機制二:Watcher 監聽機制

Watcher 監聽機制是 Zookeeper 解決各種分布式不一致疑難雜癥的獨家法門,也是學習 Zookeeper 必學的知識點。

1. 對于 Watcher 機制的理解

Zookeeper 提供了數據的發布與訂閱的功能,多個訂閱者可以同時監聽某一個對象,當這個對象自身狀態發生變化時(例如節點數據或者節點的子節點個數變化),Zookeeper 系統會通知這些訂閱者。

對于發布和訂閱這個概念的理解,我們可以用這個場景來理解:

比如前兩天的臺風,老板想發一個通知給員工:明天在家辦公。

于是老板會在釘釘群上 Ding 一個消息,員工自己打開釘釘查看。

在這個場景中,老板是發布者,員工是訂閱者,釘釘群就是 Zookeeper 系統。

老板并不一一給員工發消息,而是把消息發到群里,員工就可以感知到消息的變化。

訂閱者 員工 客戶端1
系統 釘釘群 Zookeeper系統
發布者 老板 客戶端2

2、 Watcher 機制的流程

客戶端首先將 Watcher 注冊到服務器上,同時將 Watcher 對象保存在客戶端的 Watcher 管理器中。當 Zookeeper 服務端監聽到數據狀態發生變化時,服務端會首先主動通知客戶端,接著客戶端的 Watcher 管理器會觸發相關的 Watcher 來回調響應的邏輯,從而完成整體的發布/訂閱流程。

監聽器 Watcher 的定義:

  1. public interface Watcher { 
  2. //   WatchedEvent 對象中有下面三個屬性,Zookeeper狀態,事件類型,路徑 
  3. //    final private KeeperState keeperState; 
  4. //    final private EventType eventType; 
  5. //    private String path; 
  6.     abstract public void process(WatchedEvent event); 

下面是監聽的大致流程圖:

稍稍解釋一下:

1、Client1 和 Client2 都關心 /app2 節點的數據狀態變化,于是注冊一個對于 /app2 的監聽器到 Zookeeper 上;

2、當 Client3 修改 /app2 的值后,Zookeeper 會主動通知 Client1 和 Client2 ,并且回調監聽器的方法。

當然這里的數據狀態變化有下面這些類型:

  • 節點被創建;
  • 節點被刪除;
  • 節點數據發生改變;
  • 節點的子節點個數發生改變。

3. 通過代碼來初步理解

我們還是用 Curator 框架來驗證一下這個監聽器。

代碼很簡單,這里我們使用 TreeCache 表示對于 /app2 的監聽,并且注冊了監聽的方法。

  1. public class CuratorWatcher { 
  2.  
  3.     public static void main(String[] args) throws Exception { 
  4.         CuratorFramework client = CuratorFrameworkFactory.builder().connectString("localhost:2181"
  5.                 .connectionTimeoutMs(10000) 
  6.                 .retryPolicy(new ExponentialBackoffRetry(1000, 10)) 
  7.                 .build(); 
  8.         client.start(); 
  9.  
  10.         String path = "/app2"
  11.  
  12.         TreeCache treeCache = new TreeCache(client, path); 
  13.         treeCache.start(); 
  14.  
  15.         treeCache.getListenable().addListener((client1, event) -> { 
  16.             System.out.println("event.getData()," + event.getData()); 
  17.             System.out.println("event.getType()," + event.getType()); 
  18.         }); 
  19.  
  20.         Thread.sleep(Integer.MAX_VALUE); 
  21.     } 

當 /app2 的狀態發生變化時,就會調用監聽的方法。

Curator 是對原生的 Zookeeper Api 有封裝的,原生的 Zookeeper 提供的 Api ,注冊監聽后,當數據發生改變時,監聽就被服務端刪除了,要重復注冊監聽。

Curator 則對這個做了相應的封裝和改進。

五、代碼實戰:實現主備選舉

這里我們主要想實現的功能是:

  • 有兩個節點,bigdata001,bigdata002 ,他們互相主備。
  • bigdata001 啟動時,往 zk 上注冊一個臨時節點 /ElectorLock(鎖),并且往 /ActiveMaster 下面注冊一個子節點,表示自己是主節點。
  • bigdata002 啟動時,發現臨時節點 /ElectorLock 存在,表示當前系統已經有主節點了,則自己往 /StandbyMaster 下注冊一個節點,表示自己是 standby。
  • bigdata001 退出時,釋放 /ElectorLock,并且刪除 /activeMaster 下的節點。
  • bigdata002 感知到 /ElectorLock 不存在時,則自己去注冊 /ElectorLock,并在 /ActiveMaster 下注冊自己,表示自己已經成為了主節點。

代碼還是用 Curator 框架實現的:

  1. package com.kkarch.zookeeper; 
  2.  
  3. import cn.hutool.core.util.StrUtil; 
  4. import lombok.extern.slf4j.Slf4j; 
  5. import org.apache.curator.framework.CuratorFramework; 
  6. import org.apache.curator.framework.recipes.cache.TreeCache; 
  7. import org.apache.curator.framework.recipes.cache.TreeCacheEvent; 
  8. import org.apache.zookeeper.CreateMode; 
  9.  
  10. import java.nio.charset.StandardCharsets; 
  11.  
  12. /** 
  13.  * 分布式選舉 
  14.  * 
  15.  * @Author wangkai 
  16.  * @Time 2021/7/25 20:12 
  17.  */ 
  18. @Slf4j 
  19. public class ElectorTest { 
  20.  
  21.     private static final String PARENT = "/cluster_ha"
  22.     private static final String ACTIVE = PARENT + "/ActiveMaster"
  23.     private static final String STANDBY = PARENT + "/StandbyMaster"
  24.     private static final String LOCK = PARENT + "/ElectorLock"
  25.  
  26.     private static final String HOSTNAME = "bigdata05"
  27.     private static final String activeMasterPath = ACTIVE + "/" + HOSTNAME; 
  28.     private static final String standByMasterPath = STANDBY + "/" + HOSTNAME; 
  29.  
  30.     public static void main(String[] args) throws Exception { 
  31.         CuratorFramework zk = ZkUtil.createZkClient("localhost:2181"); 
  32.         zk.start(); 
  33.  
  34.         // 注冊好監聽 
  35.         TreeCache treeCache = new TreeCache(zk, PARENT); 
  36.         treeCache.start(); 
  37.  
  38.         treeCache.getListenable().addListener((client, event) -> { 
  39.             if (event.getType().equals(TreeCacheEvent.Type.INITIALIZED) || event.getType().equals(TreeCacheEvent.Type.CONNECTION_LOST) 
  40.                     || event.getType().equals(TreeCacheEvent.Type.CONNECTION_RECONNECTED) || event.getType().equals(TreeCacheEvent.Type.CONNECTION_SUSPENDED)) { 
  41.                 return
  42.             } 
  43.             System.out.println(event.getData()); 
  44.             // 如果 Active 下有節點被移除了,沒有節點,則應該去競選成為 Active 
  45.             if (StrUtil.startWith(event.getData().getPath(), ACTIVE) && event.getType().equals(TreeCacheEvent.Type.NODE_REMOVED)) { 
  46.                 if (getChildrenNumber(zk, ACTIVE) == 0) { 
  47.                     createZNode(client, LOCK, HOSTNAME.getBytes(StandardCharsets.UTF_8), CreateMode.EPHEMERAL); 
  48.                     System.out.println(HOSTNAME + "爭搶到了鎖"); 
  49.                 } 
  50.             } 
  51.             // 如果有鎖節點被創建,則判斷是不是自己創建的,如果是,則切換自己的狀態為 ACTIVE 
  52.             else if (StrUtil.equals(event.getData().getPath(), LOCK) && event.getType().equals(TreeCacheEvent.Type.NODE_ADDED)) { 
  53.                 if (StrUtil.equals(new String(event.getData().getData()), HOSTNAME)) { 
  54.                     createZNode(zk, activeMasterPath, HOSTNAME.getBytes(StandardCharsets.UTF_8), CreateMode.EPHEMERAL); 
  55.                     if (checkExists(client, standByMasterPath)) { 
  56.                         deleteZNode(client, standByMasterPath); 
  57.                     } 
  58.                 } 
  59.             } 
  60.         }); 
  61.  
  62.         // 先創建 ACTIVE 和 STANDBY 節點 
  63.         if (zk.checkExists().forPath(ACTIVE) == null) { 
  64.             zk.create().creatingParentContainersIfNeeded().forPath(ACTIVE); 
  65.         } 
  66.         if (zk.checkExists().forPath(STANDBY) == null) { 
  67.             zk.create().creatingParentContainersIfNeeded().forPath(STANDBY); 
  68.         } 
  69.  
  70.         // 判斷 ACTIVE 下是否有子節點,如果沒有則去爭搶一把鎖 
  71.         if (getChildrenNumber(zk, ACTIVE) == 0) { 
  72.             createZNode(zk, LOCK, HOSTNAME.getBytes(StandardCharsets.UTF_8), CreateMode.EPHEMERAL); 
  73.         } 
  74.         // 如果有,則自己成為 STANDBY 狀態 
  75.         else { 
  76.             createZNode(zk, standByMasterPath, HOSTNAME.getBytes(StandardCharsets.UTF_8), CreateMode.EPHEMERAL); 
  77.         } 
  78.  
  79.  
  80.         Thread.sleep(1000000000); 
  81.  
  82.  
  83.     } 
  84.  
  85.     public static int getChildrenNumber(CuratorFramework client, String path) throws Exception { 
  86.         return client.getChildren().forPath(path).size(); 
  87.     } 
  88.  
  89.     public static void createZNode(CuratorFramework client, String path, byte[] data, CreateMode mode) { 
  90.         try { 
  91.             client.create().withMode(mode).forPath(path, data); 
  92.         } catch (Exception e) { 
  93.             log.error("創建節點失敗", e); 
  94.             System.out.println("創建節點失敗了"); 
  95.         } 
  96.     } 
  97.  
  98.     public static boolean checkExists(CuratorFramework client, String path) throws Exception { 
  99.         return client.checkExists().forPath(path) != null
  100.     } 
  101.  
  102.     public static void deleteZNode(CuratorFramework client, String path) { 
  103.         try { 
  104.             if (checkExists(client, path)) { 
  105.                 client.delete().forPath(path); 
  106.             } 
  107.         } catch (Exception e) { 
  108.             log.error("刪除節點失敗", e); 
  109.         } 
  110.     } 

 

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

2021-06-01 07:57:42

Zookeeper分布式系統

2012-11-06 13:58:26

分布式云計算分布式協同

2021-08-26 08:03:30

大數據Zookeeper選舉

2023-05-05 06:13:51

分布式多級緩存系統

2022-06-21 08:27:22

Seata分布式事務

2019-10-10 09:16:34

Zookeeper架構分布式

2024-01-05 07:28:50

分布式事務框架

2023-02-23 07:55:41

2021-10-25 10:21:59

ZK分布式鎖ZooKeeper

2017-10-24 11:28:23

Zookeeper分布式鎖架構

2015-05-18 09:59:48

ZooKeeper分布式計算Hadoop

2024-07-29 09:57:47

2017-12-05 09:43:42

分布式系統核心

2025-05-15 08:05:00

2020-11-16 12:55:41

Redis分布式鎖Zookeeper

2021-02-28 07:49:28

Zookeeper分布式

2021-07-16 07:57:34

ZooKeeperCurator源碼

2019-07-16 09:22:10

RedisZookeeper分布式鎖

2015-06-17 14:10:34

Redis分布式系統協調

2021-08-30 11:21:03

數據庫工具技術
點贊
收藏

51CTO技術棧公眾號

亚洲欧美视频在线观看| 欧美亚洲免费| 精品污污网站免费看| 日韩久久久久久久| 中文字幕福利视频| 国产精品99久久久久久动医院| 欧美欧美欧美欧美首页| 国产成年人在线观看| 国产普通话bbwbbwbbw| 欧美日韩理论| 日韩精品中文在线观看| 午夜视频在线瓜伦| 国产精品刘玥久久一区| 国产91丝袜在线播放0| 欧美理论电影在线播放| 一本加勒比波多野结衣| 巨胸喷奶水www久久久免费动漫| 中文字幕av免费专区久久| 91精品国产一区二区三区动漫| 久一视频在线观看| 欧美黑白配在线| 欧美日韩美少妇| 国产精品久久久久久久久电影网| 国产成人手机在线| 日本91福利区| 久久久久久成人精品| 无码国产69精品久久久久同性| 亚洲欧洲日韩精品在线| 午夜精品久久久久久久久久久| 日韩国产在线一区| 国产美女免费视频| 亚洲欧美日韩一区在线观看| 久久视频在线直播| 亚洲国产日韩一区无码精品久久久| 国产va免费精品观看精品| 亚洲va欧美va国产va天堂影院| 亚洲最大免费| 全色精品综合影院| 国产成人精品三级麻豆| 国产精品日韩在线观看| 国产超碰人人爽人人做人人爱| 国产精品久久久久久麻豆一区软件| 日韩午夜三级在线| 99sesese| 经典三级一区二区| 精品久久久久久中文字幕| 日韩精品久久久| 99久久婷婷国产一区二区三区| 另类天堂av| 国产综合在线视频| 欧美黑人猛猛猛| 欧美成免费一区二区视频| 精品国产亚洲一区二区三区在线观看| 国产一级做a爰片久久| 亚洲黄色网址| 精品成人av一区| 一区二区三区欧美在线| 日韩a在线看| 久久久无码精品亚洲日韩按摩| 精品久久久久久亚洲| 人成网站在线观看| 不卡一区中文字幕| 久久久综合亚洲91久久98 | 色国产精品一区在线观看| 黄色免费视频大全| 筱崎爱全乳无删减在线观看| 日韩欧美大尺度| 日本免费一级视频| se01亚洲视频| 欧美日韩国产高清一区二区| 久久久久久久久久久久久久久国产| 欧美一级免费| 日韩精品最新网址| 偷偷色噜狠狠狠狠的777米奇| 开心激情综合| 亚洲色图欧美制服丝袜另类第一页| 国产呦小j女精品视频| 国产麻豆精品久久| 久久五月情影视| 精品无码人妻一区二区三区| 99在线观看免费视频精品观看| 日本一区二区在线播放| 中文字幕免费高清在线观看| 国产综合色在线视频区| 国产精品18毛片一区二区| 人妻少妇精品无码专区| 久久先锋资源网| 中文字幕一区二区三区乱码| 少女频道在线观看免费播放电视剧| 婷婷国产v国产偷v亚洲高清| 欧美亚洲日本在线观看| 国产精品日韩精品在线播放| 亚洲高清福利视频| 日韩福利在线视频| 国产精品99一区二区| 欧美在线视频一区| 国产精品毛片一区二区在线看舒淇 | 懂色av成人一区二区三区| 26uuu成人网一区二区三区| 亚洲欧美久久234| 高清精品在线| 欧美精品一二三区| jizz欧美性20| 亚洲情侣在线| 国产成人精品国内自产拍免费看 | 日本欧美韩国| 日韩欧美国产麻豆| 手机看片福利视频| 日韩视频久久| 99国产精品久久久久老师| 成人高清免费在线播放| 亚洲mv在线观看| 伊人国产精品视频| 精品一区二区三| 国内揄拍国内精品| 国产视频在线观看视频| 久久久亚洲综合| 一二三四视频社区在线| 日韩欧乱色一区二区三区在线| 亚洲美女视频网站| 国产主播在线播放| 国产福利精品一区| 亚洲一区二区三区欧美| 成人美女视频| 亚洲福利视频在线| 免费网站看av| 国产美女视频一区| 在线观看成人av| 欧美日韩女优| 国产午夜精品一区二区三区| 日本一区二区网站| 成人毛片老司机大片| 法国空姐在线观看免费| 成人全视频在线观看在线播放高清| 日韩av有码在线| 黄色激情视频在线观看| 国产盗摄精品一区二区三区在线| 在线免费观看成人| 成人午夜亚洲| 中文字幕一精品亚洲无线一区| 久草视频一区二区| 91视频在线看| 国产白丝袜美女久久久久| eeuss国产一区二区三区四区| 精品中文字幕在线2019| 99免费在线视频| 一区二区三区自拍| 麻豆网站免费观看| 欧美国产专区| 超碰97国产在线| 久久一卡二卡| 亚洲国产精久久久久久| 日本黄色片视频| av午夜精品一区二区三区| 日韩精品一区在线视频| 香蕉免费一区二区三区在线观看| 久久天天躁狠狠躁夜夜av| 国产免费福利视频| 亚洲激情图片一区| 91亚洲一线产区二线产区| 欧美精品九九| 国产一区二区三区高清| 超碰成人av| 亚洲精品资源在线| 中文字幕理论片| 中文字幕中文在线不卡住| 三级性生活视频| 你懂的国产精品永久在线| 高清视频一区二区三区| 交100部在线观看| 国产午夜一区二区| 国产伦精品一区二区三区视频痴汉 | 欧美一区二区在线| 99只有精品| 欧美老少做受xxxx高潮| 无码精品一区二区三区在线| 色综合久久久网| 久久精品亚洲a| 成人永久免费视频| 欧美精品aaaa| 一区二区三区中文| 久久久一本精品99久久精品| 欧美极品在线| 午夜精品一区二区三区在线视| 你懂的视频在线播放| 9191国产精品| 国产 日韩 欧美 在线| 国产精品人妖ts系列视频| 中文字幕无码毛片免费看| 亚洲免费中文| 综合久久国产| 网曝91综合精品门事件在线| 成人乱色短篇合集| 黄色视屏在线免费观看| 久久精品国产久精国产一老狼| 人妻无码一区二区三区久久99| 91福利资源站| 久久亚洲成人av| 欧美国产禁国产网站cc| 黄页网站在线看| 天堂va蜜桃一区二区三区漫画版| 在线观看三级网站| 欧美美女在线| 国产精品白丝jk白祙| 成人精品三级| 欧美与欧洲交xxxx免费观看| 成人日韩欧美| 一区二区三区美女xx视频| 日本xxxxwww| 91精品婷婷国产综合久久性色| 精品不卡一区二区| 亚洲国产日韩综合久久精品| 亚洲aaa视频| 久久这里只有精品6| 女王人厕视频2ⅴk| 美女视频黄a大片欧美| 大肉大捧一进一出好爽视频| 午夜精品久久| 午夜啪啪免费视频| 成人同人动漫免费观看 | 亚洲国产日韩a在线播放性色| 亚洲一级黄色录像| 久久久久久日产精品| 丝袜熟女一区二区三区| 国产乱人伦精品一区二区在线观看| 手机看片福利盒子久久| 国产精品老牛| 精品久久一二三| 亚洲网站啪啪| 日本一本草久p| 亚洲色图国产| 综合久久国产| 91精品国产91久久综合| 亚洲乱码国产乱码精品天美传媒| 你微笑时很美电视剧整集高清不卡| 国产精品亚洲不卡a| 色播一区二区| 超碰97在线播放| 2020国产精品极品色在线观看| 92看片淫黄大片欧美看国产片| 在线观看欧美| 国产日韩在线看片| 亚洲天堂网站| 国产日韩欧美日韩大片| av亚洲一区| 国产精品视频网| 国产精品久久久久久久久免费高清| 国产成人在线一区| abab456成人免费网址| 国产精品视频一| 亚洲精品一区二区在线播放∴| 成人在线播放av| 精品三级国产| 俄罗斯精品一区二区三区| 国产精品nxnn| 久久人人97超碰人人澡爱香蕉| 亚洲专区视频| 色之综合天天综合色天天棕色| 成人影院天天5g天天爽无毒影院| 亚洲国产成人不卡| 91精品综合久久久久久久久久久 | 好吊色欧美一区二区三区视频| 大型av综合网站| 国产一区二区三区无遮挡| 免费日韩一区二区三区| 日本一区视频在线| 91久久夜色精品国产按摩| av磁力番号网| 亚洲人成免费| 国产熟人av一二三区| 老司机免费视频一区二区三区| 亚洲第一天堂久久| 成人黄色av网站在线| 亚洲天堂视频一区| 中文字幕va一区二区三区| 男人在线观看视频| 午夜视频一区二区三区| 国产成人精品777777| 欧美乱熟臀69xxxxxx| www.成人精品| 国产视频亚洲视频| 免费黄网站在线| 91精品国产成人www| 免费视频观看成人| 国产精品一区二区三区精品| 国产成人短视频在线观看| 干日本少妇视频| 亚洲综合日韩| 999久久久精品视频| 91香蕉视频mp4| 久久精品日韩无码| 精品久久久久久国产91| 亚洲在线视频播放| 日韩精品福利在线| 黄色免费在线网站| 日韩av电影在线播放| 另类视频一区二区三区| 欧美一区亚洲二区| 伊人久久成人| 中文字幕在线综合| 99久久久国产精品免费蜜臀| 日韩一卡二卡在线观看| 日韩欧美精品中文字幕| 精品国产九九九| 中文国产亚洲喷潮| 在线毛片观看| 97视频资源在线观看| 日韩成人精品一区| 狠狠爱免费视频| 高清不卡一区二区在线| 亚洲AV成人无码精电影在线| 黑人巨大精品欧美一区二区三区 | 精品国模一区二区三区欧美| 麻豆91av| 18成人免费观看视频| 久久6免费视频| 欧美国产在线观看| 日本三级小视频| 精品免费日韩av| 中文字幕在线观看网站| 国产精品欧美激情在线播放| 欧美在线关看| 欧美视频免费看欧美视频| 国产精品18久久久久久久久久久久 | 久久久爽爽爽美女图片| 日韩在线你懂得| 色综合666| 久久天堂精品| 亚洲成人网在线播放| 欧美日韩国产在线看| 三级网站免费观看| 久久久伊人欧美| 中文字幕久久精品一区二区| 日韩不卡一二区| 激情深爱一区二区| 欧美日韩黄色网| 91精品国产综合久久久久久久| av网站大全在线观看| 国产成人精品优优av| 精品久久成人| 能在线观看的av网站| 国产无一区二区| 羞羞色院91蜜桃| 丝袜亚洲欧美日韩综合| 欧美天堂一区二区| 中文字幕中文字幕在线中一区高清| 免费观看30秒视频久久| 国产精品麻豆一区| 欧美酷刑日本凌虐凌虐| 国产美女av在线| 成人自拍偷拍| 亚洲高清在线| 蜜桃精品成人影片| 精品日本高清在线播放| 欧美日韩国产中文字幕在线| 国产成人精品一区二区三区| 日韩夫妻性生活xx| 青娱乐精品在线| 亚洲国产欧美在线| 偷拍自拍在线| 国产精品久久久久99| 久久久久久影院| 性一交一黄一片| 欧美日韩在线视频观看| 69视频在线观看| 痴汉一区二区三区| 国产精品一二| 欧美xxxooo| 精品日本一线二线三线不卡| 蜜桃av.网站在线观看| 欧美一区二区三区四区在线观看地址| 日本欧洲一区二区| 国产盗摄一区二区三区在线| 亚洲国产精品一区二区三区| 亚洲日本网址| 国产在线无码精品| 99久久婷婷国产综合精品电影| 国产成人av免费| 久久99精品久久久久久琪琪| 国产suv精品一区| 狠狠热免费视频| 一区二区三区蜜桃| 日韩午夜影院| 亚洲mm色国产网站| 免费亚洲一区| 极品颜值美女露脸啪啪| 亚洲欧美精品一区二区| 国产精品日本一区二区不卡视频| 成 年 人 黄 色 大 片大 全| 中文文精品字幕一区二区| 99久久婷婷国产一区二区三区| 欧美一级免费看| 91精品电影| 日本黄色网址大全| 欧美一区二区视频在线观看2020| 黄频免费在线观看| 麻豆md0077饥渴少妇| 国产欧美日韩在线观看| 亚洲精品国产精| 成人妇女淫片aaaa视频|