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

緩存、緩存算法和緩存框架簡介

開發 開發工具 算法
很久很久以前,在還沒有緩存的時候……用戶經常是去請求一個對象,而這個對象是從數據庫去取,然后,這個對象變得越來越大,這個用戶每次的請求時間也越來越長了,這也把數據庫弄得很痛苦

引言

我們都聽過 cache,當你問他們是什么是緩存的時候,他們會給你一個完美的答案,可是他們不知道緩存是怎么構建的,或者沒有告訴你應該采用什么標準去選擇緩存框架。在這邊文章,我們會去討論緩存,緩存算法,緩存框架以及哪個緩存框架會更好。

面試

“緩存就是存貯數據(使用頻繁的數據)的臨時地方,因為取原始數據的代價太大了,所以我可以取得快一些。”

這就是 programmer one (programmer one 是一個面試者)在面試中的回答(一個月前,他向公司提交了簡歷,想要應聘要求在緩存,緩存框架,大規模數據操作有著豐富經驗的 java 開發職位)。

programmer one 通過 hash table 實現了他自己的緩存,但是他知道的只是他的緩存和他那存儲著150條記錄的 hash table,這就是他認為的大規模數據(緩存 = hashtable,只需要在 hash table 查找就好了),所以,讓我們來看看面試的過程吧。

面試官:你選擇的緩存方案,是基于什么標準的?

programmer one:呃,(想了5分鐘)嗯,基于,基于,基于數據(咳嗽……)

面試官:excese me ! 能不能重復一下?

programmer one:數據?!

面試官:好的。說說幾種緩存算法以及它們的作用

programmer one:(凝視著面試官,臉上露出了很奇怪的表情,沒有人知道原來人類可以做出這種表情  )

面試官:好吧,那我換個說法,當緩存達到容量時,會怎么做?

programmer one:容量?嗯(思考……hash table 的容量時沒有限制的,我能任意增加條目,它會自動擴充容量的)(這是 programmer one 的想法,但是他沒有說出來)

面試官對 programmer one 表示感謝(面試過程持續了10分鐘),之后一個女士走過來說:謝謝你的時間,我們會給你打電話的,祝你好心情。這是 programmer one 最糟糕的面試(他沒有看到招聘對求職者有豐富的緩存經驗背景要求,實際上,他只看到了豐厚的報酬  )。

說到做到

programmer one 離開之后,他想要知道這個面試者說的問題和答案,所以他上網去查,programmer one 對緩存一無所知,除了:當我需要緩存的時候,我就會用 hash table。

在他使用了他最愛的搜索引擎搜索之后,他找到了一篇很不錯的關于緩存文章,并且開始去閱讀……

#p#

為什么我們需要緩存?

很久很久以前,在還沒有緩存的時候……用戶經常是去請求一個對象,而這個對象是從數據庫去取,然后,這個對象變得越來越大,這個用戶每次的請求時間也越來越長了,這也把數據庫弄得很痛苦,他無時不刻不在工作。所以,這個事情就把用戶和數據庫弄得很生氣,接著就有可能發生下面兩件事情:

1.用戶很煩,在抱怨,甚至不去用這個應用了(這是大多數情況下都會發生的)

2.數據庫為打包回家,離開這個應用,然后,就出現了大麻煩(沒地方去存儲數據了)(發生在極少數情況下)

上帝派來了緩存

在幾年之后,IBM(60年代)的研究人員引進了一個新概念,它叫“緩存”。

什么是緩存?

正如開篇所講,緩存是“存貯數據(使用頻繁的數據)的臨時地方,因為取原始數據的代價太大了,所以我可以取得快一些。”

緩存可以認為是數據的池,這些數據是從數據庫里的真實數據復制出來的,并且為了能別取回,被標上了標簽(鍵 ID)。太棒了

programmer one 已經知道這點了,但是他還不知道下面的緩存術語。

緩存、緩存算法和緩存框架簡介

命中:

當客戶發起一個請求(我們說他想要查看一個產品信息),我們的應用接受這個請求,并且如果是在第一次檢查緩存的時候,需要去數據庫讀取產品信息。

如果在緩存中,一個條目通過一個標記被找到了,這個條目就會被使用、我們就叫它緩存命中。所以,命中率也就不難理解了。

Cache Miss:

但是這里需要注意兩點:

1. 如果還有緩存的空間,那么,沒有命中的對象會被存儲到緩存中來。

2. 如果緩存慢了,而又沒有命中緩存,那么就會按照某一種策略,把緩存中的舊對象踢出,而把新的對象加入緩存池。而這些策略統稱為替代策略(緩存算法),這些策略會決定到底應該提出哪些對象。

存儲成本:

當沒有命中時,我們會從數據庫取出數據,然后放入緩存。而把這個數據放入緩存所需要的時間和空間,就是存儲成本。

索引成本:

和存儲成本相仿。

失效:

當存在緩存中的數據需要更新時,就意味著緩存中的這個數據失效了。

替代策略:

當緩存沒有命中時,并且緩存容量已經滿了,就需要在緩存中踢出一個老的條目,加入一條新的條目,而到底應該踢出什么條目,就由替代策略決定。

最優替代策略:

最優的替代策略就是想把緩存中最沒用的條目給踢出去,但是未來是不能夠被預知的,所以這種策略是不可能實現的。但是有很多策略,都是朝著這個目前去努力。

Java 街惡夢:

當 programmer one 在讀這篇文章的時候,他睡著了,并且做了個惡夢(每個人都有做惡夢的時候)。

programmer one:nihahha,我要把你弄失效!(瘋狂的狀態)

緩存對象:別別,讓我活著,他們還需要我,我還有孩子。

programmer one:每個緩存對象在失效之前都會那樣說。你從什么時候開始有孩子的?不用擔心,現在就永遠消失吧!

哈哈哈哈哈……programmer one 恐怖的笑著,但是警笛打破了沉靜,警察把 programmer one 抓了起來,并且控告他殺死了(失效)一個仍需被使用的緩存對象,他被押到了監獄。

programmer one 突然醒了,他被嚇到了,渾身是汗,他開始環顧四周,發現這確實是個夢,然后趕緊繼續閱讀這篇文章,努力的消除自己的恐慌。

在programmer one 醒來之后,他又開始閱讀文章了。

#p#

緩存算法

沒有人能說清哪種緩存算法優于其他的緩存算法

Least Frequently Used(LFU):

大家好,我是 LFU,我會計算為每個緩存對象計算他們被使用的頻率。我會把最不常用的緩存對象踢走。

Least Recently User(LRU):

我是 LRU 緩存算法,我把最近最少使用的緩存對象給踢走。

我總是需要去了解在什么時候,用了哪個緩存對象。如果有人想要了解我為什么總能把最近最少使用的對象踢掉,是非常困難的。

瀏覽器就是使用了我(LRU)作為緩存算法。新的對象會被放在緩存的頂部,當緩存達到了容量極限,我會把底部的對象踢走,而技巧就是:我會把最新被訪問的緩存對象,放到緩存池的頂部。

所以,經常被讀取的緩存對象就會一直呆在緩存池中。有兩種方法可以實現我,array 或者是 linked list。

我的速度很快,我也可以被數據訪問模式適配。我有一個大家庭,他們都可以完善我,甚至做的比我更好(我確實有時會嫉妒,但是沒關系)。我家庭的一些成員包括 LRU2 和 2Q,他們就是為了完善 LRU 而存在的。

Least Recently Used 2(LRU2):

我是 Least Recently Used 2,有人叫我最近最少使用 twice,我更喜歡這個叫法。我會把被兩次訪問過的對象放入緩存池,當緩存池滿了之后,我會把有兩次最少使用的緩存對象踢走。因為需要跟蹤對象2次,訪問負載就會隨著緩存池的增加而增加。如果把我用在大容量的緩存池中,就會有問題。另外,我還需要跟蹤那么不在緩存的對象,因為他們還沒有被第二次讀取。我比LRU好,而且是 adoptive to access 模式 。

Two Queues(2Q):

我是 Two Queues;我把被訪問的數據放到 LRU 的緩存中,如果這個對象再一次被訪問,我就把他轉移到第二個、更大的 LRU 緩存。

我踢走緩存對象是為了保持第一個緩存池是第二個緩存池的1/3。當緩存的訪問負載是固定的時候,把 LRU 換成 LRU2,就比增加緩存的容量更好。這種機制使得我比 LRU2 更好,我也是 LRU 家族中的一員,而且是 adoptive to access 模式 。

Adaptive Replacement Cache(ARC):

我是 ARC,有人說我是介于 LRU 和 LFU 之間,為了提高效果,我是由2個 LRU 組成,第一個,也就是 L1,包含的條目是最近只被使用過一次的,而第二個 LRU,也就是 L2,包含的是最近被使用過兩次的條目。因此, L1 放的是新的對象,而 L2 放的是常用的對象。所以,別人才會認為我是介于 LRU 和 LFU 之間的,不過沒關系,我不介意。

我被認為是性能最好的緩存算法之一,能夠自調,并且是低負載的。我也保存著歷史對象,這樣,我就可以記住那些被移除的對象,同時,也讓我可以看到被移除的對象是否可以留下,取而代之的是踢走別的對象。我的記憶力很差,但是我很快,適用性也強。

Most Recently Used(MRU):

我是 MRU,和 LRU 是對應的。我會移除最近最多被使用的對象,你一定會問我為什么。好吧,讓我告訴你,當一次訪問過來的時候,有些事情是無法預測的,并且在緩存系統中找出最少最近使用的對象是一項時間復雜度非常高的運算,這就是為什么我是最好的選擇。

我是數據庫內存緩存中是多么的常見!每當一次緩存記錄的使用,我會把它放到棧的頂端。當棧滿了的時候,你猜怎么著?我會把棧頂的對象給換成新進來的對象!

First in First out(FIFO):

我是先進先出,我是一個低負載的算法,并且對緩存對象的管理要求不高。我通過一個隊列去跟蹤所有的緩存對象,最近最常用的緩存對象放在后面,而更早的緩存對象放在前面,當緩存容量滿時,排在前面的緩存對象會被踢走,然后把新的緩存對象加進去。我很快,但是我并不適用。

Second Chance:

大家好,我是 second chance,我是通過 FIFO 修改而來的,被大家叫做 second chance 緩存算法,我比 FIFO 好的地方是我改善了 FIFO 的成本。我是 FIFO 一樣也是在觀察隊列的前端,但是很FIFO的立刻踢出不同,我會檢查即將要被踢出的對象有沒有之前被使用過的標志(1一個 bit 表示),沒有沒有被使用過,我就把他踢出;否則,我會把這個標志位清除,然后把這個緩存對象當做新增緩存對象加入隊列。你可以想象就這就像一個環隊列。當我再一次在隊頭碰到這個對象時,由于他已經沒有這個標志位了,所以我立刻就把他踢開了。我在速度上比 FIFO 快。

CLock:

我是 Clock,一個更好的 FIFO,也比 second chance 更好。因為我不會像 second chance 那樣把有標志的緩存對象放到隊列的尾部,但是也可以達到 second chance 的效果。

我持有一個裝有緩存對象的環形列表,頭指針指向列表中最老的緩存對象。當緩存 miss 發生并且沒有新的緩存空間時,我會問問指針指向的緩存對象的標志位去決定我應該怎么做。如果標志是0,我會直接用新的緩存對象替代這個緩存對象;如果標志位是1,我會把頭指針遞增,然后重復這個過程,知道新的緩存對象能夠被放入。我比 second chance 更快。

Simple time-based:

我是 simple time-based 緩存算法,我通過絕對的時間周期去失效那些緩存對象。對于新增的對象,我會保存特定的時間。我很快,但是我并不適用。

Extended time-based expiration:

我是 extended time-based expiration 緩存算法,我是通過相對時間去失效緩存對象的;對于新增的緩存對象,我會保存特定的時間,比如是每5分鐘,每天的12點。

Sliding time-based expiration:

我是 sliding time-based expiration,與前面不同的是,被我管理的緩存對象的生命起點是在這個緩存的最后被訪問時間算起的。我很快,但是我也不太適用。

其他的緩存算法還考慮到了下面幾點:

成本:如果緩存對象有不同的成本,應該把那些難以獲得的對象保存下來。

容量:如果緩存對象有不同的大小,應該把那些大的緩存對象清除,這樣就可以讓更多的小緩存對象進來了。

時間:一些緩存還保存著緩存的過期時間。電腦會失效他們,因為他們已經過期了。

根據緩存對象的大小而不管其他的緩存算法可能是有必要的。

#p#

電子郵件!

在讀完這篇文章之后,programmer one 想了一會兒,然后決定給作者發封郵件,他感覺作者的名字在哪聽過,但是已經想不起來了。不管怎樣,他還是把郵件發送出來了,他詢問了作者在分布式環境中,緩存是怎么樣工作的。

文章的作者收到了郵件,具有諷刺意味的是,這個作者就是面試 programmer one 的人  ,作者回復了……

在這一部分中,我們來看看如何實現這些著名的緩存算法。以下的代碼只是示例用的,如果你想自己實現緩存算法,可能自己還得加上一些額外的工作。

LeftOver 機制

在 programmer one 閱讀了文章之后,他接著看了文章的評論,其中有一篇評論提到了 leftover 機制——random cache。

Random Cache

我是隨機緩存,我隨意的替換緩存實體,沒人敢抱怨。你可以說那個被替換的實體很倒霉。通過這些行為,我隨意的去處緩存實體。我比 FIFO 機制好,在某些情況下,我甚至比 LRU 好,但是,通常LRU都會比我好。

現在是評論時間

當 programmer one 繼續閱讀評論的時候,他發現有個評論非常有趣,這個評論實現了一些緩存算法,應該說這個評論做了一個鏈向評論者網站的鏈接,programmer one順著鏈接到了那個網站,接著閱讀。

看看緩存元素(緩存實體)

  1. public class CacheElement  
  2.  {  
  3.      private Object objectValue;  
  4.      private Object objectKey;  
  5.      private int index;  
  6.      private int hitCount; // getters and setters  
  7.  } 

這個緩存實體擁有緩存的key和value,這個實體的數據結構會被以下所有緩存算法用到。

緩存算法的公用代碼

  1. public final synchronized void addElement(Object key, Object value)  
  2. {  
  3.     int index;  
  4.     Object obj;  
  5.     // get the entry from the table  
  6.     obj = table.get(key);  
  7.     // If we have the entry already in our table  
  8.     // then get it and replace only its value.  
  9.     obj = table.get(key);  
  10.    
  11.     if (obj != null)  
  12.     {  
  13.         CacheElement element;  
  14.         element = (CacheElement) obj;  
  15.         element.setObjectValue(value);  
  16.         element.setObjectKey(key);  
  17.         return;  
  18.     }  

上面的代碼會被所有的緩存算法實現用到。這段代碼是用來檢查緩存元素是否在緩存中了,如果是,我們就替換它,但是如果我們找不到這個 key 對應的緩存,我們會怎么做呢?那我們就來深入的看看會發生什么吧!

現場訪問

今天的專題很特殊,因為我們有特殊的客人,事實上他們是我們想要聽的與會者,但是首先,先介紹一下我們的客人:Random Cache,FIFO Cache。讓我們從 Random Cache開始。

看看隨機緩存的實現

  1. public final synchronized void addElement(Object key, Object value)  
  2. {  
  3.     int index;  
  4.     Object obj;  
  5.     obj = table.get(key);  
  6.     if (obj != null)  
  7.     {  
  8.         CacheElement element;// Just replace the value.  
  9.         element = (CacheElement) obj;  
  10.         element.setObjectValue(value);  
  11.         element.setObjectKey(key);  
  12.         return;  
  13.     }// If we haven't filled the cache yet, put it at the end.  
  14.     if (!isFull())  
  15.     {  
  16.         index = numEntries;  
  17.         ++numEntries;  
  18.     }  
  19.     else { // Otherwise, replace a random entry.  
  20.         index = (int) (cache.length * random.nextFloat());  
  21.         table.remove(cache[index].getObjectKey());  
  22.     }  
  23.     cache[index].setObjectValue(value);  
  24.     cache[index].setObjectKey(key);  
  25.     table.put(key, cache[index]);  

看看FIFO緩算法的實現

  1. public final synchronized void addElement(Objectkey, Object value)  
  2. {  
  3.     int index;  
  4.     Object obj;  
  5.     obj = table.get(key);  
  6.     if (obj != null)  
  7.     {  
  8.         CacheElement element; // Just replace the value.  
  9.         element = (CacheElement) obj;  
  10.         element.setObjectValue(value);  
  11.         element.setObjectKey(key);  
  12.         return;  
  13.     }  
  14.     // If we haven't filled the cache yet, put it at the end.  
  15.     if (!isFull())  
  16.     {  
  17.         index = numEntries;  
  18.         ++numEntries;  
  19.     }  
  20.     else { // Otherwise, replace the current pointer,  
  21.            // entry with the new one.  
  22.         index = current;  
  23.         // in order to make Circular FIFO  
  24.         if (++current >= cache.length)  
  25.             current = 0;  
  26.         table.remove(cache[index].getObjectKey());  
  27.     }  
  28.     cache[index].setObjectValue(value);  
  29.     cache[index].setObjectKey(key);  
  30.     table.put(key, cache[index]);  

看看LFU緩存算法的實現

  1. public synchronized Object getElement(Object key)  
  2. {  
  3.     Object obj;  
  4.     obj = table.get(key);  
  5.     if (obj != null)  
  6.     {  
  7.         CacheElement element = (CacheElement) obj;  
  8.         element.setHitCount(element.getHitCount() + 1);  
  9.         return element.getObjectValue();  
  10.     }  
  11.     return null;  
  12. }  
  13. public final synchronized void addElement(Object key, Object value)  
  14. {  
  15.     Object obj;  
  16.     obj = table.get(key);  
  17.     if (obj != null)  
  18.     {  
  19.         CacheElement element; // Just replace the value.  
  20.         element = (CacheElement) obj;  
  21.         element.setObjectValue(value);  
  22.         element.setObjectKey(key);  
  23.         return;  
  24.     }  
  25.     if (!isFull())  
  26.     {  
  27.         index = numEntries;  
  28.         ++numEntries;  
  29.     }  
  30.     else 
  31.     {  
  32.         CacheElement element = removeLfuElement();  
  33.         index = element.getIndex();  
  34.         table.remove(element.getObjectKey());  
  35.     }  
  36.     cache[index].setObjectValue(value);  
  37.     cache[index].setObjectKey(key);  
  38.     cache[index].setIndex(index);  
  39.     table.put(key, cache[index]);  
  40. }  
  41. public CacheElement removeLfuElement()  
  42. {  
  43.     CacheElement[] elements = getElementsFromTable();  
  44.     CacheElement leastElement = leastHit(elements);  
  45.     return leastElement;  
  46. }  
  47. public static CacheElement leastHit(CacheElement[] elements)  
  48. {  
  49.     CacheElement lowestElement = null;  
  50.     for (int i = 0; i < elements.length; i++)  
  51.     {  
  52.         CacheElement element = elements[i];  
  53.         if (lowestElement == null)  
  54.         {  
  55.             lowestElement = element;  
  56.         }  
  57.         else {  
  58.             if (element.getHitCount() < lowestElement.getHitCount())  
  59.             {  
  60.                 lowestElement = element;  
  61.             }  
  62.         }  
  63.     }  
  64.     return lowestElement;  

今天的專題很特殊,因為我們有特殊的客人,事實上他們是我們想要聽的與會者,但是首先,先介紹一下我們的客人:Random Cache, FIFO Cache。讓我們從 Random Cache開始。

最重點的代碼,就應該是 leastHit 這個方法,這段代碼就是把hitCount 最低的元素找出來,然后刪除,給新進的緩存元素留位置。

看看LRU緩存算法實現

  1. private void moveToFront(int index)  
  2. {  
  3.     int nextIndex, prevIndex;  
  4.     if(head != index)  
  5.     {  
  6.         nextIndex = next[index];  
  7.         prevIndex = prev[index];  
  8.         // Only the head has a prev entry that is an invalid index  
  9.         // so we don't check.  
  10.         next[prevIndex] = nextIndex;  
  11.         // Make sure index is valid. If it isn't, we're at the tail  
  12.         // and don't set prev[next].  
  13.         if(nextIndex >= 0)  
  14.             prev[nextIndex] = prevIndex;  
  15.         else 
  16.             tail = prevIndex;  
  17.         prev[index] = -1;  
  18.         next[index] = head;  
  19.         prev[head] = index;  
  20.         head = index;  
  21.     }  
  22. }  
  23. public final synchronized void addElement(Object key, Object value)  
  24. {  
  25.     int index;Object obj;  
  26.     obj = table.get(key);  
  27.     if(obj != null)  
  28.     {  
  29.         CacheElement entry;  
  30.         // Just replace the value, but move it to the front.  
  31.         entry = (CacheElement)obj;  
  32.         entry.setObjectValue(value);  
  33.         entry.setObjectKey(key);  
  34.         moveToFront(entry.getIndex());  
  35.         return;  
  36.     }  
  37.     // If we haven't filled the cache yet, place in next available  
  38.     // spot and move to front.  
  39.     if(!isFull())  
  40.     {  
  41.         if(_numEntries > 0)  
  42.         {  
  43.             prev[_numEntries] = tail;  
  44.             next[_numEntries] = -1;  
  45.             moveToFront(numEntries);  
  46.         }  
  47.         ++numEntries;  
  48.     }  
  49.     else { // We replace the tail of the list.  
  50.         table.remove(cache[tail].getObjectKey());  
  51.         moveToFront(tail);  
  52.     }  
  53.     cache[head].setObjectValue(value);  
  54.     cache[head].setObjectKey(key);  
  55.     table.put(key, cache[head]);  

這段代碼的邏輯如 LRU算法 的描述一樣,把再次用到的緩存提取到最前面,而每次刪除的都是最后面的元素。

結論

我們已經看到 LFU緩存算法 和 LRU緩存算法的實現方式,至于如何實現,采用數組還是 LinkedHashMap,都由你決定,不夠我一般是小的緩存容量用數組,大的用 LinkedHashMap。

原文鏈接:http://blog.jobbole.com/30940/

責任編輯:張偉 來源: 伯樂在線
相關推薦

2021-11-30 10:58:52

算法緩存技術

2019-11-05 14:24:31

緩存雪崩框架

2021-08-05 16:10:03

進程緩存緩存服務Java

2017-07-13 16:40:16

偽共享緩存行存儲

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2009-06-30 14:08:00

Hibernate緩存

2013-07-29 16:22:21

Android緩存框架

2010-10-13 16:44:10

MySQL查詢緩存機制

2025-03-03 07:00:00

2019-10-12 14:19:05

Redis數據庫緩存

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2022-05-10 08:58:56

CacheHTTP

2011-08-05 15:51:44

MySQL數據庫緩存

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2009-09-21 13:49:14

Hiberate3 S

2017-12-27 12:01:39

2022-03-08 00:07:51

緩存雪崩數據庫

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2021-01-20 05:33:03

緩存ReadWriteLo高并發

2025-06-30 01:55:00

點贊
收藏

51CTO技術棧公眾號

亚洲一二三区在线观看| 久久午夜影视| 精品国产电影一区二区| 男女av免费观看| 日本三级在线视频| 成人教育av在线| 热久久这里只有精品| 午夜激情福利电影| silk一区二区三区精品视频| 色哟哟一区二区| 久久福利一区二区| 国产三级在线看| 成人免费视频国产在线观看| 国产在线精品播放| 黄网在线观看视频| 欧美日本不卡| 中文字幕免费精品一区高清| 亚洲av无码一区二区三区观看 | 久久久久久亚洲精品不卡| 伊人网伊人影院| 99精品在免费线中文字幕网站一区| 91久久线看在观草草青青| 乱子伦一区二区| 在线国产91| 久久久精品影视| 精品日本一区二区| 秋霞网一区二区| 国产精品一二一区| 成人免费看片视频| 亚洲精品国产精品乱码视色| 久久xxxx精品视频| 国模精品视频一区二区| 91视频免费在线看| 午夜影院欧美| 久久精视频免费在线久久完整在线看| 久久午夜福利电影| 米奇777超碰欧美日韩亚洲| 亚洲黄色免费三级| 国产情侣久久久久aⅴ免费| 精品一区二区三区中文字幕| 欧美三级日韩三级国产三级| 久草资源站在线观看| 波多野在线观看| 亚洲精品国产一区二区精华液| 亚洲精品国产精品国自产观看| 国产精品一区二区婷婷| 国产日韩v精品一区二区| 欧美少妇一区| 精品推荐蜜桃传媒| 欧美国产精品v| 日韩欧美一区二区三区四区 | 不卡av日日日| www色aa色aawww| 91精品一区二区三区综合| 日韩中文字幕在线看| 久草福利资源在线| 亚洲午夜精品一区 二区 三区| 久久综合五月天| 在线免费观看亚洲视频| 欧美日韩福利| 国语对白做受69| 久久久久亚洲av成人毛片韩| 老鸭窝毛片一区二区三区| 国产成+人+综合+亚洲欧美丁香花| 亚洲天堂一区在线| 日韩精品午夜视频| 成人黄色中文字幕| 精品国产999久久久免费| 国产福利视频一区二区三区| 国产伦精品一区二区三| 亚洲人在线观看视频| 久久蜜桃av一区精品变态类天堂 | 激情偷拍久久| 欧美最顶级丰满的aⅴ艳星| 精人妻无码一区二区三区| 久久精品国产99国产| 亚洲综合在线小说| 亚洲人妻一区二区三区| 国产精品久99| 我的公把我弄高潮了视频| 精品国产第一福利网站| 这里只有精品免费| 波多野结衣影院| 日本一二区不卡| 欧美国产日韩视频| 无码人妻精品一区二区三区不卡| 久久99久久99精品免视看婷婷| 99国产超薄肉色丝袜交足的后果| 三级网站在线看| 日本一区二区动态图| 日韩一级特黄毛片| 中文在线аv在线| 在线不卡的av| 少妇毛片一区二区三区| 久久久久久久久久久久久久| 97视频在线观看免费高清完整版在线观看 | 超碰成人在线播放| 欧美交a欧美精品喷水| 日韩在线视频导航| 日韩精品成人一区| 精品中文字幕一区二区小辣椒 | 91亚洲国产| 国模精品系列视频| av在线免费在线观看| 久久久久久久久99精品| 青草全福视在线| 亚洲a∨精品一区二区三区导航| 欧美mv和日韩mv的网站| 成人欧美一区二区三区黑人一| 亚洲欧洲另类| 91九色在线免费视频| 黄色片免费在线| 精品久久久久久亚洲精品| 亚洲第一区第二区第三区| 猛男gaygay欧美视频| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 蜜桃传媒一区二区三区| 色成人综合网| 亚洲性视频网站| 成人在线免费看视频| 国产成人在线观看| 大地资源第二页在线观看高清版| 亚洲va中文在线播放免费| 亚洲成人免费在线视频| 国产三级国产精品国产国在线观看| 久久精品男女| 欧美高清性xxxxhd| 高清视频在线观看三级| 精品国产亚洲在线| 久久久久久久久久99| 国产综合久久久久久鬼色| 水蜜桃亚洲精品| 全球最大av网站久久| 亚洲欧美精品伊人久久| 午夜精品久久久久久久久久久久久蜜桃 | 日韩美女精品在线| 中文字幕视频在线免费观看| 欧美日韩一区二区综合| 亲爱的老师9免费观看全集电视剧| 殴美一级特黄aaaaaa| 亚洲亚洲人成综合网络| 中文字幕无码毛片免费看| 91视频一区| 91在线观看欧美日韩| 日本天堂在线观看| 欧美剧情片在线观看| 日本免费网站视频| 美洲天堂一区二卡三卡四卡视频| 亚洲欧美国产精品桃花| 一区在线影院| 日韩中文字幕网站| 国产美女www爽爽爽视频| 中文字幕佐山爱一区二区免费| 精品国产鲁一鲁一区二区三区| 久久精品久久久| 99在线高清视频在线播放| 欧美1234区| 亚洲精品97久久| 色婷婷av国产精品| 中文字幕免费不卡| 污污的视频免费观看| 欧美激情无毛| 蜜桃av噜噜一区二区三| 精品肉辣文txt下载| 久久精品99久久久香蕉| 午夜免费福利视频| 欧美日韩一区二区三区| 99久久人妻无码精品系列| 日韩和欧美一区二区| 亚洲一区综合| 一区二区中文字幕在线观看| 91精品国产色综合久久不卡98口| 青青青免费视频在线2| 精品视频1区2区3区| 欧美精品99久久久| 久久蜜臀精品av| 奇米777在线视频| 国产精品亚洲欧美| 亚洲三区四区| 超碰cao国产精品一区二区| 国产98色在线| 呦呦在线视频| 亚洲性猛交xxxxwww| www.日韩高清| 91国偷自产一区二区使用方法| 中文字幕资源站| 99精品热视频| 爱豆国产剧免费观看大全剧苏畅| 亚洲电影成人| 亚洲资源在线网| 成人激情自拍| 国产一区二区在线免费视频| 黄频免费在线观看| 久久精品最新地址| 日本1级在线| 日韩欧美中文一区| 日韩三级一区二区| 亚洲成人av在线电影| xxxx日本黄色| 99久久久无码国产精品| 午夜在线观看av| 日韩亚洲国产精品| 中文字幕一区二区三区四区五区 | 亚洲天堂导航| 欧美另类高清videos| 高清在线观看av| 亚洲精品美女在线| www五月婷婷| 欧美日韩精品免费观看视频 | 婷婷色在线资源| 色婷婷综合久久久久| 五月天婷婷在线观看| 精品国产乱码久久久久久夜甘婷婷 | 日韩 中文字幕| 国产成人福利片| 污污的网站免费| 日本女优在线视频一区二区| 成人av一级片| 亚洲承认在线| 日本福利视频网站| 围产精品久久久久久久| 亚洲国产日韩美| 国内精品久久久久久久影视简单| 国产精品一区视频网站| 亚洲视频精选| 翡翠波斯猫1977年美国| 高清不卡一区| 亚洲mm色国产网站| 91国产一区| 国产欧美中文字幕| 国产原创一区| 国产精品一区专区欧美日韩| 91福利精品在线观看| 国产精品高潮呻吟久久av黑人| 欧美人体一区二区三区| 2019中文字幕免费视频| 极品视频在线| 91福利视频在线观看| 日本在线啊啊| 欧美在线观看网站| 韩国成人漫画| 国产精品久久久久福利| 日韩中文视频| 国产精品久久久久久久7电影| 3d欧美精品动漫xxxx无尽| 国产成人精品久久| 国产91亚洲精品久久久| 成人午夜黄色影院| 精品国产鲁一鲁****| 99一区二区三区| 牛牛影视久久网| 欧美另类一区| 青青一区二区三区| 麻豆md0077饥渴少妇| 欧美精品三区| 欧美午夜小视频| 亚洲永久网站| 污色网站在线观看| 国产麻豆视频精品| 亚洲少妇一区二区三区| 91免费看片在线观看| 久久久久久久毛片| 亚洲欧美综合色| 国产亚洲自拍av| 欧美视频在线视频| 中文字幕免费在线看| 91精品国产高清一区二区三区| 国产黄频在线观看| 精品调教chinesegay| 成人高清免费在线播放| 欧美日韩高清在线观看| 两个人看的在线视频www| 国产精品69av| 精品视频一区二区三区| 精品日韩美女| 国产精品二区不卡| 欧美丰满熟妇bbbbbb百度| 日本色综合中文字幕| 在线播放第一页| 久久久久久99久久久精品网站| 最新黄色av网址| 激情亚洲一区二区三区四区| 中文字幕一二三四| 精品国产免费人成电影在线观看四季| 可以免费看污视频的网站在线| 日韩视频免费在线观看| 国产乱码精品一区二三赶尸艳谈| 国产精品青青在线观看爽香蕉| 51亚洲精品| 日韩精品在在线一区二区中文| 国产精品国码视频| 中文字幕av专区| 93久久精品日日躁夜夜躁欧美| 欧美一级特黄高清视频| 精品免费在线观看| 国产又粗又大又爽视频| 亚洲精品自产拍| 日本aa在线| 国产一区视频在线播放| 老牛精品亚洲成av人片| 欧美一级黄色录像片| 天堂精品中文字幕在线| 国产伦精品一区二区三区88av| 国产精品拍天天在线| 成人毛片在线播放| 日韩免费性生活视频播放| 国产高清一区在线观看| 性欧美xxxx视频在线观看| 国产免费av国片精品草莓男男| 日韩一本精品| 香蕉久久夜色精品国产| 久草免费资源站| 亚洲欧美另类综合偷拍| 一本色道久久综合无码人妻| 日韩二区三区在线| 黄视频在线免费看| 91久久久久久久久久久久久| 第一会所亚洲原创| 成人性生生活性生交12| 久久免费的精品国产v∧| 日韩黄色一级大片| 精品国精品自拍自在线| 日本在线视频www鲁啊鲁| 91久久精品一区| 婷婷亚洲五月色综合| 色播五月综合网| 国产精品色眯眯| 在线免费观看一级片| 国产亚洲精品一区二555| 精品91久久| 欧美日韩国产高清视频| 性久久久久久| 丰满少妇一区二区| 欧美日韩中文字幕在线视频| 无码精品在线观看| 91精品国产精品| 日韩mv欧美mv国产网站| 久艹在线免费观看| 成人av在线看| 日韩精品人妻中文字幕| 日韩大片在线观看视频| 松下纱荣子在线观看| 蜜桃传媒视频麻豆一区 | 777一区二区| 亚洲天堂网中文字| a毛片在线免费观看| 欧美成人在线免费| 97精品久久| 日韩av黄色网址| 久久久蜜桃精品| 国产乱码在线观看| 久久视频在线视频| 7m精品国产导航在线| 亚洲人成无码网站久久99热国产| 不卡视频免费播放| 国产一级免费视频| 中文字幕在线视频日韩| 亚洲欧美在线人成swag| 国产在线无码精品| 99re热这里只有精品视频| 黄色在线视频网址| www.久久撸.com| 亚洲伊人影院| 看av免费毛片手机播放| 国产精品欧美一级免费| 国产美女三级无套内谢| 午夜精品一区二区三区在线视频 | 制服诱惑一区| 国产成人在线影院| 在线精品免费视| 精品精品国产国产自在线| av日韩精品| 成人小视频在线看| 国产精品第13页| 国模私拍视频在线| 日本久久久久久久久久久| 99视频精品全国免费| 高清中文字幕mv的电影| 色综合激情久久| 最新av在线播放| 欧美日韩精品综合| 国产伦精品一区二区三区免费 | 久久爱一区二区| 精品久久一区二区| 成人日韩av| 成人午夜视频在线观看免费| 国产精品三级av在线播放| 成人无码一区二区三区| 国产精品成人一区| 欧美日韩网站| 久久久久无码精品国产sm果冻| 欧美一区二区三区免费视频| 在线日韩影院| 欧美视频在线第一页| 国产欧美日韩三级| 欧美一级视频免费| 成人av在线亚洲| 日韩和欧美一区二区三区| 国产中文字字幕乱码无限| 色妞一区二区三区|