婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳解Redis中的List類型

詳解Redis中的List類型

熱門標簽:十堰營銷電銷機器人哪家便宜 魔獸2青云地圖標注 山東外呼銷售系統招商 鄭州人工智能電銷機器人系統 日本中國地圖標注 北京400電話辦理收費標準 貴州電銷卡外呼系統 宿遷便宜外呼系統平臺 超呼電話機器人

本系列將和大家分享Redis分布式緩存,本章主要簡單介紹下Redis中的List類型,以及如何使用Redis解決博客數據分頁、生產者消費者模型和發布訂閱等問題。

Redis List的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括發送緩沖隊列等也都是用這個數據結構。

List類型主要用于隊列和棧,先進先出,后進先出等。

存儲形式:key--LinkListvalue>

首先先給大家Show一波Redis中與List類型相關的API:

using System;
using System.Collections.Generic;
using ServiceStack.Redis;

namespace TianYa.Redis.Service
{
 /// summary>
 /// Redis List的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,
 /// Redis內部的很多實現,包括發送緩沖隊列等也都是用這個數據結構。 
 /// /summary>
 public class RedisListService : RedisBase
 {
  #region Queue隊列(先進先出)

  /// summary>
  /// 入隊
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="value">入隊的值/param>
  public void EnqueueItemOnList(string listId, string value)
  {
   base._redisClient.EnqueueItemOnList(listId, value);
  }

  /// summary>
  /// 出隊
  /// /summary>
  /// param name="listId">集合Id/param>
  /// returns>出隊的值/returns>
  public string DequeueItemFromList(string listId)
  {
   return base._redisClient.DequeueItemFromList(listId);
  }

  /// summary>
  /// 出隊(阻塞)
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="timeOut">阻塞時間(超時時間)/param>
  /// returns>出隊的值/returns>
  public string BlockingDequeueItemFromList(string listId, TimeSpan? timeOut)
  {
   return base._redisClient.BlockingDequeueItemFromList(listId, timeOut);
  }

  /// summary>
  /// 從多個list中出隊(阻塞)
  /// /summary>
  /// param name="listIds">集合Id/param>
  /// param name="timeOut">阻塞時間(超時時間)/param>
  /// returns>返回出隊的 listId  Item/returns>
  public ItemRef BlockingDequeueItemFromLists(string[] listIds, TimeSpan? timeOut)
  {
   return base._redisClient.BlockingDequeueItemFromLists(listIds, timeOut);
  }

  #endregion Queue隊列(先進先出)

  #region Stack棧(后進先出)

  /// summary>
  /// 入棧
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="value">入棧的值/param>
  public void PushItemToList(string listId, string value)
  {
   base._redisClient.PushItemToList(listId, value);
  }

  /// summary>
  /// 入棧,并設置過期時間
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="value">入棧的值/param>
  /// param name="expireAt">過期時間/param>
  public void PushItemToList(string listId, string value, DateTime expireAt)
  {
   base._redisClient.PushItemToList(listId, value);
   base._redisClient.ExpireEntryAt(listId, expireAt);
  }

  /// summary>
  /// 入棧,并設置過期時間
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="value">入棧的值/param>
  /// param name="expireIn">過期時間/param>
  public void PushItemToList(string listId, string value, TimeSpan expireIn)
  {
   base._redisClient.PushItemToList(listId, value);
   base._redisClient.ExpireEntryIn(listId, expireIn);
  }

  /// summary>
  /// 出棧
  /// /summary>
  /// param name="listId">集合Id/param>
  /// returns>出棧的值/returns>
  public string PopItemFromList(string listId)
  {
   return base._redisClient.PopItemFromList(listId);
  }

  /// summary>
  /// 出棧(阻塞)
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="timeOut">阻塞時間(超時時間)/param>
  /// returns>出棧的值/returns>
  public string BlockingPopItemFromList(string listId, TimeSpan? timeOut)
  {
   return base._redisClient.BlockingPopItemFromList(listId, timeOut);
  }

  /// summary>
  /// 從多個list中出棧一個值(阻塞)
  /// /summary>
  /// param name="listIds">集合Id/param>
  /// param name="timeOut">阻塞時間(超時時間)/param>
  /// returns>返回出棧的 listId  Item/returns>
  public ItemRef BlockingPopItemFromLists(string[] listIds, TimeSpan? timeOut)
  {
   return base._redisClient.BlockingPopItemFromLists(listIds, timeOut);
  }

  /// summary>
  /// 從fromListId集合出棧并入棧到toListId集合
  /// /summary>
  /// param name="fromListId">出棧集合Id/param>
  /// param name="toListId">入棧集合Id/param>
  /// returns>返回移動的值/returns>
  public string PopAndPushItemBetweenLists(string fromListId, string toListId)
  {
   return base._redisClient.PopAndPushItemBetweenLists(fromListId, toListId);
  }

  /// summary>
  /// 從fromListId集合出棧并入棧到toListId集合(阻塞)
  /// /summary>
  /// param name="fromListId">出棧集合Id/param>
  /// param name="toListId">入棧集合Id/param>
  /// param name="timeOut">阻塞時間(超時時間)/param>
  /// returns>返回移動的值/returns>
  public string BlockingPopAndPushItemBetweenLists(string fromListId, string toListId, TimeSpan? timeOut)
  {
   return base._redisClient.BlockingPopAndPushItemBetweenLists(fromListId, toListId, timeOut);
  }

  #endregion Stack棧(后進先出)

  #region 賦值

  /// summary>
  /// 向list頭部添加value值
  /// /summary>
  public void PrependItemToList(string listId, string value)
  {
   base._redisClient.PrependItemToList(listId, value);
  }

  /// summary>
  /// 向list頭部添加value值,并設置過期時間
  /// /summary> 
  public void PrependItemToList(string listId, string value, DateTime expireAt)
  {
   base._redisClient.PrependItemToList(listId, value);
   base._redisClient.ExpireEntryAt(listId, expireAt);
  }

  /// summary>
  /// 向list頭部添加value值,并設置過期時間
  /// /summary>  
  public void PrependItemToList(string listId, string value, TimeSpan expireIn)
  {
   base._redisClient.PrependItemToList(listId, value);
   base._redisClient.ExpireEntryIn(listId, expireIn);
  }

  /// summary>
  /// 向list中添加value值
  /// /summary>  
  public void AddItemToList(string listId, string value)
  {
   base._redisClient.AddItemToList(listId, value);
  }

  /// summary>
  /// 向list中添加value值,并設置過期時間
  /// /summary> 
  public void AddItemToList(string listId, string value, DateTime expireAt)
  {
   base._redisClient.AddItemToList(listId, value);
   base._redisClient.ExpireEntryAt(listId, expireAt);
  }

  /// summary>
  /// 向list中添加value值,并設置過期時間
  /// /summary> 
  public void AddItemToList(string listId, string value, TimeSpan expireIn)
  {
   base._redisClient.AddItemToList(listId, value);
   base._redisClient.ExpireEntryIn(listId, expireIn);
  }

  /// summary>
  /// 向list中添加多個value值
  /// /summary> 
  public void AddRangeToList(string listId, Liststring> values)
  {
   base._redisClient.AddRangeToList(listId, values);
  }

  /// summary>
  /// 向list中添加多個value值,并設置過期時間
  /// /summary> 
  public void AddRangeToList(string listId, Liststring> values, DateTime expireAt)
  {
   base._redisClient.AddRangeToList(listId, values);
   base._redisClient.ExpireEntryAt(listId, expireAt);
  }

  /// summary>
  /// 向list中添加多個value值,并設置過期時間
  /// /summary> 
  public void AddRangeToList(string listId, Liststring> values, TimeSpan expireIn)
  {
   base._redisClient.AddRangeToList(listId, values);
   base._redisClient.ExpireEntryIn(listId, expireIn);
  }

  #endregion 賦值

  #region 獲取值

  /// summary>
  /// 獲取指定list中包含的數據數量
  /// /summary> 
  public long GetListCount(string listId)
  {
   return base._redisClient.GetListCount(listId);
  }

  /// summary>
  /// 獲取指定list中包含的所有數據集合
  /// /summary> 
  public Liststring> GetAllItemsFromList(string listId)
  {
   return base._redisClient.GetAllItemsFromList(listId);
  }

  /// summary>
  /// 獲取指定list中下標從startingFrom到endingAt的值集合
  /// /summary> 
  public Liststring> GetRangeFromList(string listId, int startingFrom, int endingAt)
  {
   return base._redisClient.GetRangeFromList(listId, startingFrom, endingAt);
  }

  #endregion 獲取值

  #region 刪除

  /// summary>
  /// 移除指定list中,listId/value,與參數相同的值,并返回移除的數量
  /// /summary> 
  public long RemoveItemFromList(string listId, string value)
  {
   return base._redisClient.RemoveItemFromList(listId, value);
  }

  /// summary>
  /// 從指定list的尾部移除一個數據,并返回移除的數據
  /// /summary> 
  public string RemoveEndFromList(string listId)
  {
   return base._redisClient.RemoveEndFromList(listId);
  }

  /// summary>
  /// 從指定list的頭部移除一個數據,并返回移除的數據
  /// /summary> 
  public string RemoveStartFromList(string listId)
  {
   return base._redisClient.RemoveStartFromList(listId);
  }

  #endregion 刪除

  #region 其它

  /// summary>
  /// 清理數據,保持list長度
  /// /summary>
  /// param name="listId">集合Id/param>
  /// param name="keepStartingFrom">保留起點/param>
  /// param name="keepEndingAt">保留終點/param>
  public void TrimList(string listId, int keepStartingFrom, int keepEndingAt)
  {
   base._redisClient.TrimList(listId, keepStartingFrom, keepEndingAt);
  }

  #endregion 其它

  #region 發布訂閱

  /// summary>
  /// 發布
  /// /summary>
  /// param name="channel">頻道/param>
  /// param name="message">消息/param>
  public void Publish(string channel, string message)
  {
   base._redisClient.PublishMessage(channel, message);
  }

  /// summary>
  /// 訂閱
  /// /summary>
  /// param name="channel">頻道/param>
  /// param name="actionOnMessage">/param>
  public void Subscribe(string channel, Actionstring, string, IRedisSubscription> actionOnMessage)
  {
   var subscription = base._redisClient.CreateSubscription();
   subscription.OnSubscribe = c =>
   {
    Console.WriteLine($"訂閱頻道{c}");
    Console.WriteLine();
   };
   //取消訂閱
   subscription.OnUnSubscribe = c =>
   {
    Console.WriteLine($"取消訂閱 {c}");
    Console.WriteLine();
   };
   subscription.OnMessage += (c, s) =>
   {
    actionOnMessage(c, s, subscription);
   };
   Console.WriteLine($"開始啟動監聽 {channel}");
   subscription.SubscribeToChannels(channel); //blocking
  }

  /// summary>
  /// 取消訂閱
  /// /summary>
  /// param name="channel">頻道/param>
  public void UnSubscribeFromChannels(string channel)
  {
   var subscription = base._redisClient.CreateSubscription();
   subscription.UnSubscribeFromChannels(channel);
  }

  #endregion 發布訂閱
 }
}

使用如下:

/// summary>
/// Redis List的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,
/// Redis內部的很多實現,包括發送緩沖隊列等也都是用這個數據結構。 
/// 隊列/棧/生產者消費者模型/發布訂閱
/// /summary>
public static void ShowList()
{
 using (RedisListService service = new RedisListService())
 {
  service.FlushAll();
  service.AddItemToList("article", "張三");
  service.AddItemToList("article", "李四");
  service.AddItemToList("article", "王五");
  service.PrependItemToList("article", "趙六");
  service.PrependItemToList("article", "錢七");

  var result1 = service.GetAllItemsFromList("article"); //一次性獲取所有的數據
  var result2 = service.GetRangeFromList("article", 0, 3); //可以按照添加順序自動排序,而且可以分頁獲取
  Console.WriteLine($"result1={JsonConvert.SerializeObject(result1)}");
  Console.WriteLine($"result2={JsonConvert.SerializeObject(result2)}");

  Console.WriteLine("=====================================================");

  //棧:后進先出
  service.FlushAll();
  service.PushItemToList("article", "張三"); //入棧
  service.PushItemToList("article", "李四");
  service.PushItemToList("article", "王五");
  service.PushItemToList("article", "趙六");
  service.PushItemToList("article", "錢七");

  for (int i = 0; i  5; i++)
  {
   Console.WriteLine(service.PopItemFromList("article")); //出棧
  }

  Console.WriteLine("=====================================================");

  //隊列:先進先出,生產者消費者模型 
  //MSMQ---RabbitMQ---ZeroMQ---RedisList 學習成本、技術成本
  service.FlushAll();
  service.EnqueueItemOnList("article", "張三"); //入隊
  service.EnqueueItemOnList("article", "李四");
  service.EnqueueItemOnList("article", "王五");
  service.EnqueueItemOnList("article", "趙六");
  service.EnqueueItemOnList("article", "錢七");

  for (int i = 0; i  5; i++)
  {
   Console.WriteLine(service.DequeueItemFromList("article")); //出隊
  }
  //分布式緩存,多服務器都可以訪問到,多個生產者,多個消費者,任何產品只被消費一次
 }
}

運行結果如下所示:

下面我們就來看下如何使用上面的API來解決一些具體的問題:

一、博客數據分頁

應用場景:

  博客網站每天新增的隨筆和文章可能都是幾千幾萬的,表里面是幾千萬數據。首頁要展示最新的隨筆,還有前20頁是很多人訪問的。

  這種情況下如果首頁分頁數據每次都去查詢數據庫,那么就會有很大的性能問題。

解決方案:

  每次寫入數據庫的時候,把 ID_標題 寫入到Redis的List中(后面搞個TrimList,只要最近的200個)。

  這樣的話用戶每次刷頁面就不需要去訪問數據庫了,直接讀取Redis中的數據。

  第一頁(當然也可以是前幾頁)的時候可以不體現總記錄數,只拿最新數據展示,這樣就能避免訪問數據庫了。

還有一種就是水平分表了,數據存到Redis的時候可以保存 ID_表名稱_標題

使用List主要是解決數據量大,變化快的數據分頁問題。

二八原則:80%的訪問集中在20%的數據,List里面只用保存大概的量就夠用了。

using TianYa.Redis.Service;

namespace MyRedis.Scene
{
 /// summary>
 /// 博客數據分頁
 /// 
 /// 應用場景:
 ///  博客網站每天新增的隨筆和文章可能都是幾千幾萬的,表里面是幾千萬數據。首頁要展示最新的隨筆,還有前20頁是很多人訪問的。
 ///  這種情況下如果首頁分頁數據每次都去查詢數據庫,那么就會有很大的性能問題。
 /// 
 /// 解決方案:
 ///  每次寫入數據庫的時候,把 ID_標題 寫入到Redis的List中(后面搞個TrimList,只要最近的200個)。
 ///  這樣的話用戶每次刷頁面就不需要去訪問數據庫了,直接讀取Redis中的數據。
 ///  第一頁(當然也可以是前幾頁)的時候可以不體現總記錄數,只拿最新數據展示,這樣就能避免訪問數據庫了。
 /// 
 /// 還有一種就是水平分表了,數據存到Redis的時候可以保存 ID_表名稱_標題
 /// 
 /// 使用List主要是解決數據量大,變化快的數據分頁問題。
 /// 二八原則:80%的訪問集中在20%的數據,List里面只用保存大概的量就夠用了。
 /// /summary>
 public class BlogPageList
 {
  public static void Show()
  {
   using (RedisListService service = new RedisListService())
   {
    service.AddItemToList("newBlog", "10001_IOC容器的實現原理");
    service.AddItemToList("newBlog", "10002_AOP面向切面編程");
    service.AddItemToList("newBlog", "10003_行為型設計模式");
    service.AddItemToList("newBlog", "10004_結構型設計模式");
    service.AddItemToList("newBlog", "10005_創建型設計模式");
    service.AddItemToList("newBlog", "10006_GC垃圾回收");

    service.TrimList("newBlog", 0, 200); //保留最新的201個(一個List最多只能存放2的32次方-1個)
    var result1 = service.GetRangeFromList("newBlog", 0, 9); //第一頁
    var result2 = service.GetRangeFromList("newBlog", 10, 19); //第二頁
    var result3 = service.GetRangeFromList("newBlog", 20, 29); //第三頁
   }
  }
 }
}

二、生產者消費者模型

分布式緩存,多服務器都可以訪問到,多個生產者,多個消費者,任何產品只被消費一次。(使用隊列實現)

其中一個(或多個)程序寫入,另外一個(或多個)程序讀取消費。按照時間順序,數據失敗了還可以放回去下次重試。

下面我們來看個例子:

Demo中添加了2個控制臺應用程序,分別模擬生產者和消費者:

using System;
using TianYa.Redis.Service;

namespace TianYa.Producer
{
 /// summary>
 /// 模擬生產者
 /// /summary>
 class Program
 {
  static void Main(string[] args)
  {
   Console.WriteLine("生產者程序啟動了。。。");
   using (RedisListService service = new RedisListService())
   {
    Console.WriteLine("開始生產test產品");
    for (int i = 1; i = 20; i++)
    {
     service.EnqueueItemOnList("test", $"產品test{i}");
    }

    Console.WriteLine("開始生產task產品");
    for (int i = 1; i = 20; i++)
    {
     service.EnqueueItemOnList("task", $"產品task{i}");
    }
    Console.WriteLine("模擬生產結束");

    while (true)
    {
     Console.WriteLine("************請輸入數據************");
     string testTask = Console.ReadLine();
     service.EnqueueItemOnList("test", testTask);
    }
   }
  }
 }
}
using System;
using System.Threading;
using TianYa.Redis.Service;

namespace TianYa.Consumer
{
 /// summary>
 /// 模擬消費者
 /// /summary>
 class Program
 {
  static void Main(string[] args)
  {
   Console.WriteLine("消費者程序啟動了。。。");
   using (RedisListService service = new RedisListService())
   {
    while (true)
    {
     var result = service.BlockingDequeueItemFromLists(new string[] { "test", "task" }, TimeSpan.FromHours(1));
     Thread.Sleep(100);
     Console.WriteLine($"消費者消費了 {result.Id} {result.Item}");
    }
   }
  }
 }
}

接下來我們使用.NET Core CLI來啟動2個消費者實例和1個生產者實例,運行結果如下所示:

像這種異步隊列在項目中有什么價值呢?

PS:此處事務是一個很大問題,真實項目中需根據實際情況決定是否采用異步隊列。

三、發布訂閱

發布訂閱:

  發布一個數據,全部的訂閱者都能收到。

  觀察者,一個數據源,多個接收者,只要訂閱了就可以收到的,能被多個數據源共享。

  觀察者模式:微信訂閱號---群聊天---數據同步。。。

下面我們來看個小Demo:

/// summary>
/// 發布訂閱
///  發布一個數據,全部的訂閱者都能收到。
///  觀察者,一個數據源,多個接收者,只要訂閱了就可以收到的,能被多個數據源共享。
///  觀察者模式:微信訂閱號---群聊天---數據同步。。。
/// /summary>
public static void ShowPublishAndSubscribe()
{
 Task.Run(() =>
 {
  using (RedisListService service = new RedisListService())
  {
   service.Subscribe("TianYa", (c, message, iRedisSubscription) =>
   {
    Console.WriteLine($"注冊{1}{c}:{message},Dosomething else");
    if (message.Equals("exit"))
     iRedisSubscription.UnSubscribeFromChannels("TianYa");
   });//blocking
  }
 });
 Task.Run(() =>
 {
  using (RedisListService service = new RedisListService())
  {
   service.Subscribe("TianYa", (c, message, iRedisSubscription) =>
   {
    Console.WriteLine($"注冊{2}{c}:{message},Dosomething else");
    if (message.Equals("exit"))
     iRedisSubscription.UnSubscribeFromChannels("TianYa");
   });//blocking
  }
 });
 Task.Run(() =>
 {
  using (RedisListService service = new RedisListService())
  {
   service.Subscribe("Twelve", (c, message, iRedisSubscription) =>
   {
    Console.WriteLine($"注冊{3}{c}:{message},Dosomething else");
    if (message.Equals("exit"))
     iRedisSubscription.UnSubscribeFromChannels("Twelve");
   });//blocking
  }
 });
 using (RedisListService service = new RedisListService())
 {
  Thread.Sleep(1000);
  service.Publish("TianYa", "TianYa1");
  Thread.Sleep(1000);
  service.Publish("TianYa", "TianYa2");
  Thread.Sleep(1000);
  service.Publish("TianYa", "TianYa3");

  Thread.Sleep(1000);
  service.Publish("Twelve", "Twelve1");
  Thread.Sleep(1000);
  service.Publish("Twelve", "Twelve2");
  Thread.Sleep(1000);
  service.Publish("Twelve", "Twelve3");

  Thread.Sleep(1000);
  Console.WriteLine("**********************************************");

  Thread.Sleep(1000);
  service.Publish("TianYa", "exit");
  Thread.Sleep(1000);
  service.Publish("TianYa", "TianYa6");
  Thread.Sleep(1000);
  service.Publish("TianYa", "TianYa7");
  Thread.Sleep(1000);
  service.Publish("TianYa", "TianYa8");

  Thread.Sleep(1000);
  service.Publish("Twelve", "exit");
  Thread.Sleep(1000);
  service.Publish("Twelve", "Twelve6");
  Thread.Sleep(1000);
  service.Publish("Twelve", "Twelve7");
  Thread.Sleep(1000);
  service.Publish("Twelve", "Twelve8");

  Thread.Sleep(1000);
  Console.WriteLine("結束");
 }
}

運行結果如下所示:

至此本文就全部介紹完了,如果覺得對您有所啟發請記得點個贊哦!!!

Demo源碼:

鏈接: https://pan.baidu.com/s/1_kEMCtbf2iT5pLV7irxR5Q 提取碼: v4sr

此文由博主精心撰寫轉載請保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/14022264.html

到此這篇關于詳解Redis中的List類型的文章就介紹到這了,更多相關Redis List類型內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • python3操作redis實現List列表實例
  • Redis List列表的詳細介紹
  • redis redisson 集合的使用案例(RList、Rset、RMap)
  • Redis快速表、壓縮表和雙向鏈表(重點介紹quicklist)
  • redis 獲取 list 中的所有元素操作
  • Redis list 類型學習筆記與總結
  • Redis教程(三):List數據類型
  • 基于Redis的List實現特價商品列表功能

標簽:江蘇 朝陽 果洛 大慶 北京 楊凌 吉安 臺州

巨人網絡通訊聲明:本文標題《詳解Redis中的List類型》,本文關鍵詞  詳解,Redis,中的,List,類型,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解Redis中的List類型》相關的同類信息!
  • 本頁收集關于詳解Redis中的List類型的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    在线精品亚洲一区二区不卡| 久久精品国产**网站演员| 婷婷久久综合九色综合伊人色| 国产在线观看一区二区| 精品久久久三级丝袜| 日韩黄色免费电影| 精品国产伦一区二区三区观看体验 | 在线观看亚洲专区| 亚洲国产精品久久人人爱| 色偷偷一区二区三区| 亚洲一二三四区| 在线成人免费观看| 免费成人av资源网| 国产亚洲短视频| 成人免费毛片嘿嘿连载视频| 亚洲视频一二区| 欧美又粗又大又爽| 狠狠色丁香久久婷婷综| 国产精品久久久久久久久晋中| 91年精品国产| 美腿丝袜一区二区三区| 久久老女人爱爱| 欧洲精品中文字幕| 久久99国产精品久久99果冻传媒| 精品久久久久久久久久久久久久久 | 99久久精品99国产精品| 亚洲一区二区三区在线播放| 日韩欧美不卡一区| 99久久精品一区| 欧美aaaaa成人免费观看视频| 国产精品蜜臀av| 8x8x8国产精品| 一本久道久久综合中文字幕| 蜜桃精品在线观看| 一区二区三区四区在线播放| 欧美白人最猛性xxxxx69交| 9久草视频在线视频精品| 久久国内精品视频| 五月婷婷综合激情| 亚洲男人天堂av网| 国产拍揄自揄精品视频麻豆| 6080亚洲精品一区二区| 欧美曰成人黄网| 99免费精品在线观看| 精品综合免费视频观看| 偷拍一区二区三区四区| 一级日本不卡的影视| 亚洲欧洲性图库| 国产亚洲欧美一级| 欧美视频中文字幕| 在线观看91视频| 91精品在线麻豆| 91丨porny丨蝌蚪视频| 国产精品自产自拍| 九九精品视频在线看| 日韩精品乱码免费| 亚洲成人手机在线| 亚洲福利一区二区| 一区二区理论电影在线观看| 18成人在线观看| 中文字幕一区二区三区乱码在线| 国产欧美视频一区二区三区| 久久精品人人做人人爽人人| 欧美xingq一区二区| 日韩情涩欧美日韩视频| 日韩欧美国产一区在线观看| 日韩女优电影在线观看| 久久综合狠狠综合| 国产偷国产偷精品高清尤物| 久久久久久久久久久久久女国产乱| 日韩欧美一级二级三级| 日韩欧美一级二级三级| 精品成人佐山爱一区二区| 精品国产91久久久久久久妲己| 日韩精品专区在线| 国产日韩欧美电影| 亚洲同性gay激情无套| 亚洲自拍另类综合| 日韩不卡一区二区三区 | 日本道精品一区二区三区| 在线观看欧美日本| 欧美日韩精品专区| 久久久影视传媒| 亚洲美女在线国产| 欧美aaaaaa午夜精品| 国产不卡在线播放| 99re亚洲国产精品| 在线观看91av| 中文字幕不卡的av| 亚洲va在线va天堂| 国产精品自拍网站| 在线看一区二区| 欧美精品一区二区高清在线观看| 国产精品污网站| 午夜欧美一区二区三区在线播放| 国产一区二区电影| 色素色在线综合| 欧美videos中文字幕| 亚洲欧洲99久久| 韩国女主播一区| 欧美唯美清纯偷拍| 亚洲国产精品黑人久久久| 天堂成人免费av电影一区| 粉嫩绯色av一区二区在线观看| 欧美自拍偷拍午夜视频| 久久免费电影网| 日韩有码一区二区三区| 99久久国产综合精品麻豆| 精品日韩在线观看| 亚洲一区成人在线| 毛片不卡一区二区| 色播五月激情综合网| 久久久久99精品国产片| 亚洲成人免费视频| 北条麻妃国产九九精品视频| 91精品国产91热久久久做人人| 欧美激情一区在线观看| 狠狠色综合日日| 欧美一级片在线观看| 亚洲一区二区美女| 91蜜桃视频在线| 中文字幕一区二区三区四区| 国产91精品一区二区麻豆网站| 欧美r级在线观看| 日韩精品国产欧美| 欧美精品久久久久久久多人混战 | 国产91高潮流白浆在线麻豆 | 最新日韩av在线| 国产中文字幕一区| 精品乱人伦小说| 另类人妖一区二区av| 欧美精品色一区二区三区| 亚洲国产成人91porn| 在线免费一区三区| 亚洲乱码精品一二三四区日韩在线 | 日本三级韩国三级欧美三级| 在线观看视频一区| 亚洲无人区一区| 精品视频一区二区三区免费| 亚洲成av人片一区二区三区| 欧美色大人视频| 午夜欧美一区二区三区在线播放| 欧美情侣在线播放| 麻豆久久久久久| 久久婷婷色综合| 成人av网址在线观看| 亚洲人成影院在线观看| 欧美亚洲丝袜传媒另类| 亚洲国产wwwccc36天堂| 欧美一区二区三区影视| 精品在线播放免费| 亚洲国产高清在线观看视频| av成人免费在线| 亚洲国产日日夜夜| 欧美日韩精品电影| 国产一区美女在线| 亚洲日本欧美天堂| 欧美色窝79yyyycom| 精品综合免费视频观看| 中文字幕一区二区三区乱码在线| 色94色欧美sute亚洲线路一久| 丝瓜av网站精品一区二区| 欧美电影免费观看高清完整版在线观看| 美国毛片一区二区| 国产精品免费人成网站| 在线播放亚洲一区| www.66久久| 日本欧美肥老太交大片| 久久免费精品国产久精品久久久久 | 久久精品国产一区二区三| 国产成人精品一区二区三区四区 | 亚洲国产中文字幕| 精品少妇一区二区三区视频免付费 | 亚洲精品成a人| 午夜电影一区二区三区| 久久99九九99精品| 欧美日韩和欧美的一区二区| 久久综合久久综合亚洲| 婷婷国产在线综合| 欧美亚洲图片小说| 亚洲午夜成aⅴ人片| 精品国产免费久久| 高清久久久久久| 亚洲国产精品一区二区www| 日韩免费成人网| 欧美精品一卡两卡| 成人国产精品免费网站| 亚洲国产成人av| 一区二区中文视频| 日韩欧美亚洲国产精品字幕久久久 | 国产午夜精品一区二区三区视频| 色综合天天综合网天天狠天天| 久久爱另类一区二区小说| 亚洲h精品动漫在线观看| 国产精品嫩草影院av蜜臀| 26uuu欧美| 欧美成人vr18sexvr| 91麻豆精品国产91久久久资源速度 | 国产午夜三级一区二区三| 欧美一区二区三区在线电影 |