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

緩存的一些常見的坑,你遇到過哪些,怎么解決的?

新聞 前端
當數據時效性要求很高時,需要保證緩存中的數據與數據庫中的保持一致,而且需要保證緩存節點和副本中的數據也保持一致,不能出現差異現象。

為什么使用緩存

在高并發請求時,我們會頻繁提到使用緩存技術,最直接的原因是,磁盤IO及網絡開銷是直接請求內存IO的千百上千倍

做個簡單計算,如果我們需要某個數據,該數據從數據庫磁盤讀出來需要0.0045S,經過網絡請求傳輸需要0.0005S,那么每個請求完成最少需要0.005S,該數據服務器每秒最多只能響應200個請求,而如果該數據存于本機內存里,讀出來只需要100us,那么每秒能夠響應10000個請求。通過將數據存儲到離CPU更近的未位置,減少數據傳輸時間,提高處理效率,這就是緩存的意義。

什么場景下適合使用緩存

  • 讀密集型的應用

  • 存在熱數據的應用

  • 對響應時效要求高的應用

  • 對一致性要求不嚴格的場景

  • 需要實現分布式鎖的時候

什么場景下不適合使用緩存

  • 對一致性要求嚴格的場景

  • 更新頻繁,更新數據頻率過高的場景,頻繁同步緩存中的數據所花費的代價可能比不使用緩存的代價還要高

  • 讀少的場景,對于讀少的系統而言,使用緩存就完全沒有意義了,比較使用緩存是為了讀取數據更高效

緩存收益成本對比

收益

  1. 加速讀寫。因為緩存通常都是全內存的系統,通過緩存的使用可以有效提高用戶的訪問速度同時優化用戶體驗。

  2. 降低后端負載。通過添加緩存,如果程序沒有什么問題,在命中率還可以的情況下,可以幫助后端減少訪問量和復雜計算,很大程度降低了后端的負載。

成本

  1. 數據不一致性。無論設計做的多么好,緩存數據與真實數據源一定存在著一定時間窗口的數據不一致性

  2. 代碼維護成本。有緩存后,代碼就會在原數據源基礎上加入緩存的相關代碼,例如原來只是一些sql,現在要加入緩存,必然增加代碼維護成本。

  3. 架構復雜度。有緩存后,需要專門的管理人員來維護主從緩存系統,同時也增加了架構的復雜度和維護成本。

高并發場景下帶來的常見問題

在高并發場景下,緩存主要會帶來下面幾個問題:

1.緩存一致性

2.緩存并發(緩存擊穿)

3.緩存穿透

4.緩存雪崩(緩存失效)

打個比方,你是個很有錢的人,開滿了百度云,騰訊視頻各種雜七雜八的會員,但是你就是沒有netflix的會員,然后你把這些賬號和密碼發布到一個你自己做的網站上,然后你有一個朋友每過十秒鐘就查詢你的網站,發現你的網站沒有Netflix的會員后打電話向你要。你就相當于是個數據庫,網站就是Redis。這就是緩存穿透。

大家都喜歡看騰訊視頻上 周星馳的《喜劇之王》 ,但是你的會員突然到期了,大家在你的網站上看不到騰訊視頻的賬號,紛紛打電話向你詢問,這就是緩存擊穿

你的各種會員突然同一時間都失效了,那這就是緩存雪崩了。

下面一一介紹!

緩存一致性問題

當數據時效性要求很高時,需要保證緩存中的數據與數據庫中的保持一致,而且需要保證緩存節點和副本中的數據也保持一致,不能出現差異現象。這就比較依賴緩存的過期和更新策略。一般會在數據發生更改的時,主動更新緩存中的數據或者移除對應的緩存。

下圖情況都會導致數據一致性問題  

 

 

 

緩存擊穿問題

對于一些設置了過期時間的key,可能這些key會在某些時間點被超高并發地訪問,是一種非常“熱點”的數據。這個時候,需要考慮緩存被“擊穿”的問題,和緩存雪崩的區別在于這里針對某一key緩存,而緩存雪崩則是很多key。

如圖所示: 

 

 

 

解決方案:

業界比較常用的做法,是使用mutex(互斥鎖)。

1.使用互斥鎖(mutex key)

該方案思路比較簡單,就是只讓一個線程構建緩存,其他線程等待構建緩存的線程執行完,重新從緩存獲取數據就可以

如果是單機可以用synchronized或者lock來處理,如果是分布式環境可以用分布式鎖(redis的setnx, zookeeper的添加節點操作)

redis偽代碼如下:

  1. public String get(String key) { 
  2.         String value = storeClient.get(key); 
  3.         StoreKey key_mutex = new MutexStoreKey(key); 
  4.         if (value == null) {//代表緩存值過期 
  5.             //設置2min的超時,防止刪除緩存操作失敗的時候,下次緩存過期一直不能獲取DB數據 
  6.             if (storeClient.setnx(key_mutex, 12 * 60)) {  //代表設置成功 
  7.                 value = db.get(key); 
  8.                 storeClient.set(key, value, 3 * 3600); 
  9.                 storeClient.delete(key_mutex); 
  10.             } else { 
  11.                 sleep(1000);  //這個時候代表同時候的其他線程已經獲取DB數據并回設到緩存了,這時候重試獲取緩存值即可 
  12.                 return get(key);  //重試 
  13.             } 
  14.         } 
  15.         return value; 
  16.     } 

2.“提前”使用互斥鎖(mutex key)

即在value內部設置1個超時值(timeout1),timeout1比實際的redis timeout(timeout2)小。

當從cache讀取到timeout1發現它已經過期時候,馬上延長timeout1并重新設置到cache。然后再從數據庫加載數據并設置到cache中。

方案2和方案1的區別在于,如果緩存有數據,但是已經過期,會提前使用互斥鎖,查詢DB最新數據再緩存起來

偽代碼如下,注意代碼else里面的邏輯。

  1. public String get(String key) { 
  2.         MutexDTO value = storeClient.get(key); 
  3.         StoreKey key_mutex = new MutexStoreKey(key); 
  4.         if (value == null) { 
  5.             if (storeClient.setnx(key_mutex, 3 * 60 * 1000)) { 
  6.                 value = db.get(key); 
  7.                 storeClient.set(key, value); 
  8.                 storeClient.delete(key_mutex); 
  9.             } else { 
  10.                 sleep(50); 
  11.                 get(key); 
  12.             } 
  13.         } else { 
  14.             if (value.getTimeout() <= System.currentTimeMillis()) { 
  15.                 if (storeClient.setnx(key_mutex, 3 * 60 * 1000)) { 
  16.                     value.setTimeout(value.getTimeout() + 3 * 60 * 1000); 
  17.                     storeClient.set(key, value, 3 * 3600 * 2); 
  18.  
  19.                     value = db.get(key);//獲取最近DB更新數據 
  20.                     value.setTimeout(value.getTimeout() + 3 * 60 * 1000); 
  21.                     storeClient.set(key, value, 3 * 3600 * 2); 
  22.                     storeClient.delete(key_mutex); 
  23.                 } else { 
  24.                     sleep(50); 
  25.                     get(key); 
  26.                 } 
  27.             } 
  28.         } 
  29.          return value.getValue(); 
  30.     } 

3.緩存”永不過期“

這里的“永遠不過期”包含兩層意思:

  • 從redis上看,不設置過期時間,這就保證了,不會出現熱點key過期問題,也就是“物理”不過期。

  • 從功能上看,如果不過期,那不就成靜態的了嗎?所以我們把過期時間存在key對應的value里,如果發現要過期了,通過一個后臺的異步線程進行緩存的構建,也就是“邏輯”過期。

 

  1. public String get(String key) { 
  2.         MutexDTO mutexDTO = storeClient.get(key); 
  3.         String value = mutexDTO.getValue(); 
  4.         if (mutexDTO.getTimeout() <= System.currentTimeMillis()) { 
  5.             ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();// 異步更新后臺異常執行 
  6.             singleThreadExecutor.execute(new Runnable() { 
  7.                 public void run() { 
  8.                     StoreKey mutexKey = new MutexStoreKey(key); 
  9.                     if (storeClient.setnx(mutexKey, "1")) { 
  10.                         storeClient.expire(mutexKey, 3 * 60); 
  11.                         String dbValue = db.get(key); 
  12.                         storeClient.set(key, dbValue); 
  13.                         storeClient.delete(mutexKey); 
  14.                     } 
  15.                 } 
  16.             }); 
  17.         } 
  18.         return value; 
  19.     } 

三種方法如下比較:

解決方案 優點 缺點
使用互斥鎖 1.思路簡單2.保證一致性 1. 代碼復雜度增大2. 存在死鎖的風險
提前使用互斥鎖 1. 保證一致性 同上
緩存永不過期 1. 異步構建緩存,不會阻塞線程池 1. 不保證一致性。2. 代碼復雜度增大(每個value都要維護一個timekey)。3. 占用一定的內存空間(每個value都要維護一個timekey)。

緩存穿透問題

緩存穿透是指查詢一個一定不存在的數據,由于緩存是不命中時被動寫的,并且出于容錯考慮,如果從存儲層查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到存儲層去查詢,失去了緩存的意義。

在流量大時,要是DB無法承受瞬間流量沖擊,DB可能就掛了。

如圖所示:  

 

 

 

解決方案:

有多種方法可以有效解決緩存穿透問題,一種比較簡單粗暴的方法采用緩存空數據,如果一個查詢返回的數據為空(數據庫中不存在該數據),仍然把這個空結果進行緩存(過期時間一般較短)。

另一種方法則是采用常用的布隆過濾器,將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。

1.緩存空數據

當Client請求MISS后,仍然將空對象保留到Cache中(可能是保留一段時間,具體問題具體分析),下次新的Request(同一個key)將會從Cache中獲取到數據,保護了后端的DB。偽代碼如下:

  1. public class CacheNullService { 
  2.     private Cache cache = new Cache(); 
  3.     private Storage storage = new Storage(); 
  4.     /** 
  5.      * 模擬正常模式  
  6.      * @param key 
  7.      * @return 
  8.      */ 
  9.     public String getNormal(String key) { 
  10.         // 從緩存中獲取數據   
  11.         String cacheValue = cache.get(key); 
  12.         // 緩存為空   
  13.         if (StringUtils.isBlank(cacheValue)) { 
  14.             // 從存儲中獲取   
  15.             String storageValue = storage.get(key); 
  16.             // 如果存儲數據不為空,將存儲的值設置到緩存   
  17.             if (StringUtils.isNotBlank(storageValue)) { 
  18.                 cache.set(key, storageValue); 
  19.             } 
  20.             return storageValue; 
  21.         } else { 
  22.             // 緩存非空   
  23.             return cacheValue; 
  24.         } 
  25.     } 
  26.     /** 
  27.      * 模擬防穿透模式  
  28.      * @param key 
  29.      * @return 
  30.      */ 
  31.     public String getPassThrough(String key) { 
  32.         // 從緩存中獲取數據   
  33.         String cacheValue = cache.get(key); 
  34.         // 緩存為空   
  35.         if (StringUtils.isBlank(cacheValue)) { 
  36.             // 從存儲中獲取   
  37.             String storageValue = storage.get(key); 
  38.             cache.set(key, storageValue); 
  39.             // 如果存儲數據為空,需要設置一個過期時間(300秒)   
  40.             if (StringUtils.isBlank(storageValue)) { 
  41.                 cache.expire(key, 60 * 5); 
  42.             } 
  43.             return storageValue; 
  44.         } else { 
  45.             // 緩存非空   
  46.             return cacheValue; 
  47.         } 
  48.     } 

2.布隆過濾器

BloomFilter 是一個非常有意思的數據結構,不僅僅可以擋住非法 key 攻擊,還可以低成本、高性能地對海量數據進行判斷,比如一個系統有數億用戶和百億級新聞 feed,就可以用 BloomFilter 來判斷某個用戶是否閱讀某條新聞 feed

在訪問所有資源(cache, DB)之前,將存在的key用布隆過濾器提前保存起來,做第一層攔截。算法的簡單圖解如下: 

 

 

 

 

 用布隆過濾器實際只需要判斷客戶端傳過來的userCode是否存在就可以,圖中的hash1,hash2,hash3分別代表三種hash算法,不同的userCode對應著不同的數據位,當需要校驗的時候,判斷每一種算法的得出來的byte位是否相同,只要一位不同,那么我們可以認為這個userCode不存在。

一般BloomFilter 要緩存全量的 key,這就要求全量的 key 數量不大,10 億條數據以內最佳,因為 10 億條數據大概要占用 1.2 GB 的內存。也可以用 BloomFilter 緩存非法 key,每次發現一個 key 是不存在的非法 key,就記錄到 BloomFilter 中,這種記錄方案,會導致 BloomFilter 存儲的 key 持續高速增長,為了避免記錄 key 太多而導致誤判率增大,需要定期清零處理

布隆使用案例如下:

  1. import com.google.common.base.Charsets; 
  2. import com.google.common.hash.BloomFilter; 
  3. import com.google.common.hash.Funnels; 
  4.  
  5. import java.util.*; 
  6.  
  7. public class BFDemo { 
  8.  
  9.     private static final int insertions = 1000000;//100W 
  10.  
  11.     public static void main(String[] args) { 
  12.         BloomFilter bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), insertions); 
  13.         Set sets = new HashSet(insertions); 
  14.         List<String> lists = new ArrayList(insertions); 
  15.         for (int i = 0; i < insertions; i++) { 
  16.             String uuid = UUID.randomUUID().toString(); 
  17.             bf.put(uuid); 
  18.             sets.add(uuid); 
  19.             lists.add(uuid); 
  20.         } 
  21.         int wrong = 0
  22.         int right = 0
  23.         for (int i = 0; i < 10000; i++) { 
  24.             String test = i % 100 == 0 ? lists.get(i / 100) : UUID.randomUUID().toString();  //隨機生成1W字符串 
  25.             if (bf.mightContain(test)) { 
  26.                 if (sets.contains(test)) { 
  27.                     right++; 
  28.                 } else { 
  29.                     wrong++; 
  30.                 } 
  31.             } 
  32.         } 
  33.         System.out.println("========right=======" + right); 
  34.         System.out.println("========wrong=======" + wrong); 
  35.     } 
  36.  

上文中提到的兩種方法,比較:

解決方案 適用場景 優缺點
緩存空數據 1. 數據命中不高2. 數據頻繁變化實時性高 1.維護簡單2.需要更多的緩存空間3.可能數據不一致
布隆過濾器 1. 數據命中不高2. 數據相對固定實時性低 1.代碼維護復雜2.緩存空間占用少

緩存雪崩問題

緩存雪崩一般是由兩個原因導致的

第一個原因是:緩存中有大量數據同時過期,導致大量請求無法得到處理。

如圖所示: 

 

 

 

解決方案:

設計不同的過期時間

我們可以避免給大量的數據設置相同的過期時間。如果業務層的確要求有些數據同時失效,你可以在用EXPIRE命令給每個數據設置過期時間時,給這些數據的過期時間增加一個較小的隨機數(例如,隨機增加1~3分鐘),這樣一來,不同數據的過期時間有所差別,但差別又不會太大,既避免了大量數據同時過期,同時也保證了這些數據基本在相近的時間失效,仍然能滿足業務需求

服務降級處理

發生緩存雪崩時,針對不同的數據采取不同的處理方式。

  • 當業務應用訪問的是非核心數據時,暫時停止從緩存中查詢這些數據,而是直接返回預定義信息、空值或是錯誤信息;

  • 當業務應用訪問的是核心數據時,仍然允許查詢緩存,如果緩存缺失,也可以繼續通過數據庫讀取。

對緩存增加多個副本

緩存異常或請求 miss 后,再讀取其他緩存副本,而且多個緩存副本盡量部署在不同機架,從而確保在任何情況下,緩存系統都會正常對外提供服務

對緩存體系進行實時監控

當請求訪問的慢速比超過閥值時,及時報警,通過機器替換、服務替換進行及時恢復;也可以通過各種自動故障轉移策略,自動關閉異常接口、停止邊緣服務、停止部分非核心功能措施,確保在極端場景下,核心功能的正常運行。

第二個原因是:

如果Cache層由于某些原因(宕機、cache服務掛了或者不響應了)整體crash掉了,也就意味著所有的請求都會達到DB層,所有DB調用量會暴增,所以它有點扛不住了,甚至也會掛掉。

如圖所示: 

 

 

 

 

 雪崩過后緩存已經crash,解決方案無非是讓DB能承受更大數據壓力,我們可以DB擴容解決,但不是長久之計,最好解決辦法是如何預防緩存雪崩。

如何預防我們可以從以下方面入手:

保證Cache服務高可用性。

如果我們的cache也是高可用的,即使個別實例掛掉了,影響不會很大(主從切換或者可能會有部分流量到了后端),實現自動化運維。

例如:memcache的一致性hash、redis的sentinel和cluster機制

依賴隔離組件為后端限流。

其實無論是cache或者是mysql、hbase、甚至別人的RPC都會出現問題,我們可以將這些視同為資源,作為并發量較大的系統,假如有一個資源不可訪問了,即使設置了超時時間,依然會hold住所有線程,造成其他資源和接口也不可以訪問。

提前演練預估。

在項目上線前,通過演練,觀察cache crash后,整體系統和DB的負載,提前做好預案。

 

責任編輯:張燕妮 來源: 月伴飛魚
相關推薦

2021-08-29 18:36:17

MySQL技術面試題

2017-07-14 09:29:45

AndroidWebview

2020-10-12 09:49:14

C++ 開發代碼

2019-10-28 14:07:29

研發管理技術

2020-11-08 14:38:35

JavaScript代碼開發

2019-12-05 08:44:20

MybatisSQL場景

2009-07-23 15:07:32

2025-05-28 00:00:01

MySQL場景索引

2021-02-19 11:01:46

異步競態接口異步

2021-12-26 14:32:11

緩存數據庫數據

2022-10-20 18:00:59

OCP模型參數

2018-04-25 10:57:00

AIX報錯vios

2017-09-07 15:23:21

神經網絡數據網絡

2017-11-14 15:22:06

ReactNativeAppBugly

2024-03-18 08:14:07

SpringDAOAppConfig

2021-04-04 22:31:26

白帽子廠商漏洞

2011-04-26 09:22:05

SQLite

2020-04-26 14:40:19

戴爾

2020-09-24 10:49:09

iOSiPadOSBug

2023-03-13 07:41:34

分頁查詢數據排序
點贊
收藏

51CTO技術棧公眾號

国产精品视频一二三四区| 久久久久久久久久久久久久久久久久av | 国产一级一片免费播放放a| 亚洲国产精品免费视频| 伊人夜夜躁av伊人久久| 久久久久久亚洲精品不卡4k岛国| 日韩在线 中文字幕| 91欧美国产| 精品成人一区二区三区| 日本va中文字幕| 3d玉蒲团在线观看| 99久久er热在这里只有精品15| 国产精品黄视频| 久久丫精品久久丫| 成人黄色av| 91精品国产一区二区人妖| 分分操这里只有精品| 香蕉视频网站在线观看| 97精品久久久午夜一区二区三区| 国产精品久久久久久久久免费看| 久久婷婷一区二区| 国产精品久久天天影视| 日韩精品中文字幕在线播放| 在线a免费观看| 日本三级一区| 一区二区三区久久| 亚洲欧美日韩国产yyy| 全部免费毛片在线播放一个| 免费久久99精品国产| 97久久精品国产| 国产av无码专区亚洲av毛网站| 国产a久久精品一区二区三区| 欧美成人一区二区三区片免费| 欧美一级裸体视频| 僵尸再翻生在线观看| 亚洲精品综合在线| 亚洲欧美电影在线观看| 国产精品秘入口| 99v久久综合狠狠综合久久| 99免费在线视频观看| 亚洲永久精品视频| 日本欧美在线观看| 日韩av大片免费看| 久久久综合久久| 欧美日韩四区| 中文欧美日本在线资源| 亚洲欧美va天堂人熟伦| 蜜桃一区二区| 亚洲老头老太hd| 人妻体内射精一区二区三区| 91精品国产自产在线丝袜啪| 欧美酷刑日本凌虐凌虐| 三上悠亚在线一区二区| av在线日韩| 在线一区二区三区四区| 欧美精品aaaa| 秋霞国产精品| 欧美日韩精品一区二区三区蜜桃| 91插插插插插插插插| 日本另类视频| 欧美日韩亚洲综合一区| 日韩av片专区| 9999精品视频| 欧美一卡在线观看| wwwww在线观看| 草莓视频一区二区三区| 欧美精品一区二区蜜臀亚洲| 逼特逼视频在线观看| 国产精品成人自拍| 亚洲精品久久久久中文字幕二区| 亚洲精品视频大全| 久久av影视| 伊人青青综合网站| 91无套直看片红桃在线观看| 欧美韩国日本在线观看| 欧美裸身视频免费观看| 国产亚洲小视频| 99av国产精品欲麻豆| 日本乱人伦a精品| 综合久久中文字幕| 国内精品写真在线观看| 999热视频| 日本亚洲欧美| 国产精品视频一二| 日韩中文在线字幕| 成人免费网站观看| 在线免费观看成人短视频| 精品综合久久久久| 中文字幕一区二区三区四区久久 | 老司机av网站| 日韩精品a在线观看91| 国产一区二区三区日韩欧美| 日本高清一二三区| 日韩一级不卡| 成人福利网站在线观看11| 亚洲成人中文字幕在线| 337p粉嫩大胆噜噜噜噜噜91av| 日韩亚洲欧美精品| www在线视频| 黑人巨大精品欧美一区二区三区| 88av.com| 成人线上播放| 最新国产精品拍自在线播放| 精品少妇久久久久久888优播| 久久只有精品| 99久久精品免费看国产一区二区三区 | 91高清免费观看| 黄色亚洲精品| 国产一区视频在线| 四虎影视精品成人| 亚洲三级电影网站| 成人在线免费在线观看| 欧美久久一区二区三区| 亚洲色图国产精品| 久久精品一区二区三| 日本91福利区| 久久精品人成| 影音先锋在线视频| 欧美日韩亚州综合| 女人被狂躁c到高潮| 欧美日韩hd| 国产精品视频1区| 日本五码在线| 亚洲高清久久久| 992kp免费看片| 超碰成人久久| 91精品国产乱码久久久久久蜜臀| 国产精品人妻一区二区三区| 久久精品一区蜜桃臀影院| www.xxx麻豆| 韩国三级成人在线| 在线激情影院一区| 波多野结衣一二区| 91日韩在线专区| 人妻av中文系列| 99久久人爽人人添人人澡| 不用播放器成人网| 一本色道久久综合熟妇| 国产无遮挡一区二区三区毛片日本| 欧美一区二区中文字幕| 成人爽a毛片| 欧美激情视频网站| 国产xxxxxx| 亚洲欧美日韩中文字幕一区二区三区| 日韩一级理论片| 国产剧情在线观看一区| 国产91精品久久久久久| 亚洲人妻一区二区| 狠狠躁夜夜躁久久躁别揉| 国产精品成人无码专区| 亚洲激情国产| 精品国产乱码久久久久软件| 91九色美女在线视频| 亚洲国产精品久久久| 国产成年人免费视频| 岛国av在线一区| 日本人体一区二区| 国产精伦一区二区三区| 69久久夜色精品国产7777 | 亚洲最新av网址| 国产免费一级视频| 久久精品视频一区二区三区| 免费激情视频在线观看| 欧洲激情综合| 国产日韩精品综合网站| 成人ww免费完整版在线观看| 日韩欧美精品在线视频| 一级免费在线观看| 久久婷婷国产综合精品青草| 日本三区在线观看| 日韩在线观看一区| 91九色单男在线观看| 污污视频在线看| 亚洲国产高清福利视频| 日本熟女毛茸茸| 中文字幕精品—区二区四季| 亚洲18在线看污www麻豆 | 高清欧美性猛交xxxx黑人猛| 91精品国产色综合久久不卡98口| 青青草av免费在线观看| 欧美日韩亚洲另类| 国产一卡二卡在线播放| 91麻豆免费看片| 欧美男女交配视频| 午夜欧美理论片| 久久99精品久久久久久三级| 高清在线一区| 欧美高清一级大片| 男女网站在线观看| 欧美另类变人与禽xxxxx| 久久精品www人人爽人人| 国产亚洲制服色| 亚洲在线观看网站| 国产精品一区亚洲| 只有这里有精品| 亚洲午夜久久| 91精品视频大全| 亚洲精品动漫| 美女精品久久久| 日本高清中文字幕二区在线| 91精选在线观看| 日本免费在线观看视频| 亚洲精品精品亚洲| 亚洲精品乱码久久久久久久久久久久| 国内精品伊人久久久久av一坑| 欧美成人一区二区在线观看| 久久精品影视| 日本一区二区精品| 九九热hot精品视频在线播放| 国产精品视频资源| 色戒汤唯在线| 久久久久久久久久久国产| 米奇777四色精品人人爽| 成人精品动漫| 亚洲天堂成人在线| 国产香蕉在线观看| 欧美美女直播网站| 在线免费观看国产精品| 精品久久久久久久久久ntr影视| 亚洲 欧美 国产 另类| 久久综合九色综合97婷婷| 美女流白浆视频| 黄色资源网久久资源365| 日韩视频免费在线播放| 国产精品视区| 精品国产av无码一区二区三区| 久久婷婷蜜乳一本欲蜜臀| 蜜桃av噜噜一区二区三| 福利在线一区| 国产激情美女久久久久久吹潮| 涩涩涩久久久成人精品| 欧洲永久精品大片ww免费漫画| 后进极品白嫩翘臀在线播放| 久久国产精品偷| 幼a在线观看| 亚洲午夜性刺激影院| 男男电影完整版在线观看| 亚洲精品v欧美精品v日韩精品| 精品久久久无码中文字幕| 91精品免费观看| 91精品在线视频观看| 欧美日韩美女一区二区| 国产精品欧美综合| 91传媒视频在线播放| 亚洲国产av一区二区三区| 欧美性高潮在线| 台湾佬中文在线| 色婷婷激情一区二区三区| 无码人妻av一区二区三区波多野| 都市激情亚洲色图| 成人免费视频毛片| 欧美性高潮在线| 日韩黄色一级视频| 欧美中文字幕亚洲一区二区va在线| 国产第一页在线观看| 欧美综合一区二区三区| 亚洲无码精品在线观看| 欧美日韩黄色一区二区| 国产一区二区小视频| 欧美一区二区三区播放老司机| 国产黄色片网站| 精品国产凹凸成av人导航| 日本精品999| 亚洲欧美国产精品专区久久| 国产黄在线看| 日日狠狠久久偷偷四色综合免费| 黄a在线观看| 久久99国产精品自在自在app| 91在线超碰| 国产suv精品一区二区| 久久69成人| 97久久夜色精品国产九色 | 久久人人精品| 亚洲一级片免费| 韩国一区二区在线观看| jjzz黄色片| 久久精品在这里| 成人免费视频国产免费观看| 亚洲一二三四在线观看| 潘金莲一级淫片aaaaaa播放| 欧美日韩不卡一区| 亚洲精品国产av| 亚洲男人天堂九九视频| 麻豆影视国产在线观看| 国内精品400部情侣激情| 日韩伦理三区| 91传媒在线免费观看| 性人久久久久| 国产又黄又爽免费视频| 日韩午夜在线电影| 九九热免费在线观看| 成人激情校园春色| 精品伦精品一区二区三区视频密桃| 亚洲激情图片小说视频| 日韩不卡在线播放| 欧美精品国产精品| 日本免费网站在线观看| 日韩综合视频在线观看| 校园春色亚洲| 亚洲va国产va天堂va久久| 亚洲欧洲色图| 久久天天东北熟女毛茸茸| 丝袜亚洲另类欧美| 亚洲性图第一页| 国产精品无码永久免费888| 国产精品成人网站| 欧美精品乱人伦久久久久久| 欧美18xxxxx| 欧美激情国内偷拍| 久久青草视频| 日韩.欧美.亚洲| 亚洲人www| 四虎国产精品永久免费观看视频| 久久精品一区二区三区不卡| 亚洲激情视频一区| 欧美久久免费观看| 国产中文字幕在线看| 97精品一区二区三区| 日本少妇精品亚洲第一区| 亚洲日本精品一区| 欧美在线综合| 国产精品无码永久免费不卡| 亚洲在线视频网站| 国产精品羞羞答答在线| 国产午夜精品全部视频在线播放| av伦理在线| 97自拍视频| 亚洲欧美色图| 视频免费1区二区三区| 国产精品丝袜91| 中文字幕日韩免费| 日韩精品极品在线观看播放免费视频 | 中文无码精品一区二区三区| 精品亚洲国产视频| 波多野结衣视频一区二区| 国产精品区一区二区三在线播放| 亚洲国产不卡| 欧美日韩理论片| 亚洲私人黄色宅男| 国产精品久久久久久无人区 | 国产精品视频免费一区二区三区| 久久久久久久久久久妇女 | yourporn久久国产精品| 久久久精品视频在线| 日韩欧美一区二区不卡| 国内精品久久久久国产| 成人在线精品视频| 国产精品久久久久久| 久久久久久久久久一区| 亚洲欧洲一区二区三区| 一级特黄aaa大片在线观看| 日韩亚洲欧美中文高清在线| 欧美天堂一区| 黄色一级视频播放| 国产精品羞羞答答xxdd| 久草资源在线视频| 亚洲第一精品夜夜躁人人爽 | 亚洲电影中文字幕在线观看| 丁香花免费高清完整在线播放| 久久久久免费视频| 精品国产影院| 大肉大捧一进一出好爽视频| 久久九九影视网| 国产又黄又猛又爽| 欧美精品在线免费播放| 精品按摩偷拍| 成人黄色片视频| 国产精品大尺度| aaa级黄色片| 88国产精品欧美一区二区三区| 伊人精品一区| 天天影视色综合| 亚洲一区二区三区小说| 欧美视频综合| 成人高清视频观看www| 欧美日韩国产在线一区| 亚洲一区二区三区四区五区六区| 日本高清不卡一区| 国产写真视频在线观看| 国产免费一区二区三区| 久久精品导航| 麻豆明星ai换脸视频| 日韩国产激情在线| 精品国产美女a久久9999| 久久亚洲国产成人精品无码区| www成人在线观看| 91黄色在线视频| 97视频免费在线观看| 欧美亚洲在线日韩| caopor在线| 欧美天天综合网| av福利在线导航| 亚洲精品成人a8198a| 成人av在线一区二区三区| 午夜精品免费观看| 欧美激情按摩在线| 成人直播大秀| 少妇激情一区二区三区视频| 欧美日韩一级二级三级| 性欧美xxx69hd高清|