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

面試官:你看過Redis數(shù)據(jù)結(jié)構(gòu)底層實(shí)現(xiàn)嗎?

數(shù)據(jù)庫 其他數(shù)據(jù)庫 Redis
面試中,redis也是很受面試官親睞的一部分。我向在這里講的是redis的底層數(shù)據(jù)結(jié)構(gòu),而不是你理解的五大數(shù)據(jù)結(jié)構(gòu)。

面試中,redis也是很受面試官親睞的一部分。我向在這里講的是redis的底層數(shù)據(jù)結(jié)構(gòu),而不是你理解的五大數(shù)據(jù)結(jié)構(gòu)。你有沒有想過redis底層是怎樣的數(shù)據(jù)結(jié)構(gòu)呢,他們和我們java中的HashMap、List、等使用的數(shù)據(jù)結(jié)構(gòu)有什么區(qū)別呢。

1. 字符串處理(string)

我們都知道redis是用C語言寫,但是C語言處理字符串和數(shù)組的成本是很高的,下面我分別說幾個例子。

沒有數(shù)據(jù)結(jié)構(gòu)支撐的幾個問題

  1.  極其容易造成緩沖區(qū)溢出問題,比如用strcat(),在用這個函數(shù)之前必須要先給目標(biāo)變量分配足夠的空間,否則就會溢出。
  2.  如果要獲取字符串的長度,沒有數(shù)據(jù)結(jié)構(gòu)的支撐,可能就需要遍歷,它的復(fù)雜度是O(N)
  3.  內(nèi)存重分配。C字符串的每次變更(曾長或縮短)都會對數(shù)組作內(nèi)存重分配。同樣,如果是縮短,沒有處理好多余的空間,也會造成內(nèi)存泄漏。

好了,Redis自己構(gòu)建了一種名叫Simple dynamic string(SDS)的數(shù)據(jù)結(jié)構(gòu),他分別對這幾個問題作了處理。我們先來看看它的結(jié)構(gòu)源碼: 

  1. struct sdshdr{  
  2.      //記錄buf數(shù)組中已使用字節(jié)的數(shù)量  
  3.      //等于 SDS 保存字符串的長度  
  4.      int len;  
  5.      //記錄 buf 數(shù)組中未使用字節(jié)的數(shù)量  
  6.      int free;  
  7.      //字節(jié)數(shù)組,用于保存字符串  
  8.      char buf[];  

再來說說它的優(yōu)點(diǎn):

  1.  開發(fā)者不用擔(dān)心字符串變更造成的內(nèi)存溢出問題。
  2.  常數(shù)時間復(fù)雜度獲取字符串長度len字段。
  3.  空間預(yù)分配free字段,會默認(rèn)留夠一定的空間防止多次重分配內(nèi)存。

更多了解:https://redis.io/topics/internals-sds

這就是string的底層實(shí)現(xiàn),更是redis對所有字符串?dāng)?shù)據(jù)的處理方式(SDS會被嵌套到別的數(shù)據(jù)結(jié)構(gòu)里使用)。

2. 鏈表

Redis的鏈表在雙向鏈表上擴(kuò)展了頭、尾節(jié)點(diǎn)、元素數(shù)等屬性。

2.1 源碼

ListNode節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu): 

  1. typedef  struct listNode{  
  2.        //前置節(jié)點(diǎn)  
  3.        struct listNode *prev;  
  4.        //后置節(jié)點(diǎn)  
  5.        struct listNode *next;  
  6.        //節(jié)點(diǎn)的值  
  7.        void *value;    
  8. }listNode 

鏈表數(shù)據(jù)結(jié)構(gòu): 

  1. typedef struct list{  
  2.      //表頭節(jié)點(diǎn)  
  3.      listNode *head;  
  4.      //表尾節(jié)點(diǎn)  
  5.      listNode *tail;  
  6.      //鏈表所包含的節(jié)點(diǎn)數(shù)量  
  7.      unsigned long len;  
  8.      //節(jié)點(diǎn)值復(fù)制函數(shù)  
  9.      void (*free) (void *ptr);  
  10.      //節(jié)點(diǎn)值釋放函數(shù)  
  11.      void (*free) (void *ptr);  
  12.      //節(jié)點(diǎn)值對比函數(shù)  
  13.      int (*match) (void *ptr,void *key);  
  14. }list; 

從上面可以看到,Redis的鏈表有這幾個特點(diǎn):

  1.  可以直接獲得頭、尾節(jié)點(diǎn)。
  2.  常數(shù)時間復(fù)雜度得到鏈表長度。
  3.  是雙向鏈表。

3. 字典(Hash)

Redis的Hash,就是在數(shù)組+鏈表的基礎(chǔ)上,進(jìn)行了一些rehash優(yōu)化等。

3.1 數(shù)據(jù)結(jié)構(gòu)源碼

哈希表: 

  1. typedef struct dictht {  
  2.     // 哈希表數(shù)組  
  3.     dictEntry **table;  
  4.     // 哈希表大小  
  5.     unsigned long size;  
  6.     // 哈希表大小掩碼,用于計算索引值  
  7.     // 總是等于 size - 1  
  8.     unsigned long sizemask;  
  9.     // 該哈希表已有節(jié)點(diǎn)的數(shù)量  
  10.     unsigned long used;  
  11. } dictht; 

Hash表節(jié)點(diǎn): 

  1. typedef struct dictEntry {  
  2.     // 鍵  
  3.     void *key;  
  4.     // 值  
  5.     union {  
  6.         void *val;  
  7.         uint64_t u64;  
  8.         int64_t s64;  
  9.     } v;  
  10.     // 指向下個哈希表節(jié)點(diǎn),形成鏈表  
  11.     struct dictEntry *next;  // 單鏈表結(jié)構(gòu)  
  12. } dictEntry; 

字典: 

  1. typedef struct dict {  
  2.     // 類型特定函數(shù)  
  3.     dictType *type;  
  4.     // 私有數(shù)據(jù)  
  5.     void *privdata;  
  6.     // 哈希表  
  7.     dictht ht[2];  
  8.     // rehash 索引  
  9.     // 當(dāng) rehash 不在進(jìn)行時,值為 -1  
  10.     int rehashidx; /* rehashing not in progress if rehashidx == -1 */  
  11. } dict; 

可以看出:

  1.  Reids的Hash采用鏈地址法來處理沖突,然后它沒有使用紅黑樹優(yōu)化。
  2.  哈希表節(jié)點(diǎn)采用單鏈表結(jié)構(gòu)。
  3.  rehash優(yōu)化。

下面我們講一下它的rehash優(yōu)化。

3.2 rehash

當(dāng)哈希表的鍵對泰國或者太少,就需要對哈希表的大小進(jìn)行調(diào)整,redis是如何調(diào)整的呢?

  1.  我們仔細(xì)可以看到dict結(jié)構(gòu)里有個字段dictht ht[2]代表有兩個dictht數(shù)組。第一步就是為ht[1]哈希表分配空間,大小取決于ht[0]當(dāng)前使用的情況。
  2.  將保存在ht[0]中的數(shù)據(jù)rehash(重新計算哈希值)到ht[1]上。
  3.  當(dāng)ht[0]中所有鍵值對都遷移到ht[1]后,釋放ht[0],將ht[1]設(shè)置為ht[0],并ht[1]初始化,為下一次rehash做準(zhǔn)備。

3.3 漸進(jìn)式rehash

我們在3.2中看到,redis處理rehash的流程,但是更細(xì)一點(diǎn)的講,它如何進(jìn)行數(shù)據(jù)遷的呢?

這就涉及到了漸進(jìn)式rehash,redis考慮到大量數(shù)據(jù)遷移帶來的cpu繁忙(可能導(dǎo)致一段時間內(nèi)停止服務(wù)),所以采用了漸進(jìn)式rehash的方案。步驟如下:

  1.  為ht[1]分配空間,同時持有兩個哈希表(一個空表、一個有數(shù)據(jù))。
  2.  維持一個技術(shù)器rehashidx,初始值0。
  3.  每次對字典增刪改查,會順帶將ht[0]中的數(shù)據(jù)遷移到ht[1],rehashidx++(注意:ht[0]中的數(shù)據(jù)是只減不增的)。
  4.  直到rehash操作完成,rehashidx值設(shè)為-1。

它的好處:采用分而治之的思想,將龐大的遷移工作量劃分到每一次CURD中,避免了服務(wù)繁忙。

4. 跳躍表

這個數(shù)據(jù)結(jié)構(gòu)是我面試中見過最多的,它其實(shí)特別簡單。學(xué)過的人可能都知道,它和平衡樹性能很相似,但為什么不用平衡樹而用skipList呢?

4.1 skipList & AVL 之間的選擇

  1.  從算法實(shí)現(xiàn)難度上來比較,skiplist比平衡樹要簡單得多。
  2.  平衡樹的插入和刪除操作可能引發(fā)子樹的調(diào)整,邏輯復(fù)雜,而skiplist的插入和刪除只需要修改相鄰節(jié)點(diǎn)的指針,操作簡單又快速。
  3.  查找單個key,skiplist和平衡樹的時間復(fù)雜度都為O(log n),大體相當(dāng)。
  4.  在做范圍查找的時候,平衡樹比skiplist操作要復(fù)雜。
  5.  skiplist和各種平衡樹(如AVL、紅黑樹等)的元素是有序排列的。

可以看到,skipList中的元素是有序的,所以跳躍表在redis中用在有序集合鍵、集群節(jié)點(diǎn)內(nèi)部數(shù)據(jù)結(jié)構(gòu)。

4.2 源碼

跳躍表節(jié)點(diǎn): 

  1. typedef struct zskiplistNode {  
  2.     // 后退指針  
  3.     struct zskiplistNode *backward;  
  4.     // 分值  
  5.     double score;  
  6.     // 成員對象  
  7.     robj *obj;  
  8.     // 層  
  9.     struct zskiplistLevel {  
  10.         // 前進(jìn)指針  
  11.         struct zskiplistNode *forward;  
  12.         // 跨度  
  13.         unsigned int span;  
  14.     } level[];  
  15. } zskiplistNode; 

跳躍表: 

  1. typedef struct zskiplist {  
  2.     // 表頭節(jié)點(diǎn)和表尾節(jié)點(diǎn)  
  3.     struct zskiplistNode *header, *tail;  
  4.     // 表中節(jié)點(diǎn)的數(shù)量  
  5.     unsigned long length;  
  6.     // 表中層數(shù)最大的節(jié)點(diǎn)的層數(shù)  
  7.     int level;  
  8. } zskiplist; 

它有幾個概念:

4.2.1 層(level[])

層,也就是level[]字段,層的數(shù)量越多,訪問節(jié)點(diǎn)速度越快。(因為它相當(dāng)于是索引,層數(shù)越多,它索引就越細(xì),就能很快找到索引值)。

4.2.2 前進(jìn)指針(forward)

層中有一個forward字段,用于從表頭向表尾方向訪問。

4.2.3 跨度(span)

用于記錄兩個節(jié)點(diǎn)之間的距離。

4.2.4 后退指針(backward)

用于從表尾向表頭方向訪問。

案例 

  1. level0    1----------> 
  2. level1    1---->3----> 
  3. level2    1->2->3->4->5->6->7->

比如我要找鍵為6的元素,在level0中直接定位到5,然后再往后走一個元素就找到了。

5. 整數(shù)集合(intset)

Reids對整數(shù)存儲專門作了優(yōu)化,intset就是redis用于保存整數(shù)值的集合數(shù)據(jù)結(jié)構(gòu)。當(dāng)一個結(jié)合中只包含整數(shù)元素,redis就會用這個來存儲。 

  1. 127.0.0.1:6379[2]> sadd number 1 2 3 4 5 6  
  2. (integer) 6  
  3. 127.0.0.1:6379[2]> object encoding number  
  4. "intset" 

源碼

intset數(shù)據(jù)結(jié)構(gòu): 

  1. typedef struct intset {  
  2.     // 編碼方式  
  3.     uint32_t encoding;  
  4.     // 集合包含的元素數(shù)量  
  5.     uint32_t length;  
  6.     // 保存元素的數(shù)組  
  7.     int8_t contents[];  
  8. } intset; 

你肯定很好奇編碼方式(encoding)字段是干嘛用的呢?

  •  如果 encoding 屬性的值為 INTSET_ENC_INT16 , 那么 contents 就是一個 int16_t 類型的數(shù)組, 數(shù)組里的每個項都是一個 int16_t 類型的整數(shù)值 (最小值為 -32,768 ,最大值為 32,767 )。
  •  如果 encoding 屬性的值為 INTSET_ENC_INT32 , 那么 contents 就是一個 int32_t 類型的數(shù)組, 數(shù)組里的每個項都是一個 int32_t 類型的整數(shù)值 (最小值為 -2,147,483,648 ,最大值為 2,147,483,647 )。
  •  如果 encoding 屬性的值為 INTSET_ENC_INT64 , 那么 contents 就是一個 int64_t 類型的數(shù)組, 數(shù)組里的每個項都是一個 int64_t 類型的整數(shù)值 (最小值為 -9,223,372,036,854,775,808 ,最大值為 9,223,372,036,854,775,807 )。

說白了就是根據(jù)contents字段來判斷用哪個int類型更好,也就是對int存儲作了優(yōu)化。

說到優(yōu)化,那redis如何作的呢?就涉及到了升級。

5.1 encoding升級

如果我們有個Int16類型的整數(shù)集合,現(xiàn)在要將65535(int32)加進(jìn)這個集合,int16是存儲不下的,所以就要對整數(shù)集合進(jìn)行升級。

它是怎么升級的呢(過程)?

假如現(xiàn)在有2個int16的元素:1和2,新加入1個int32位的元素65535。

  1.  內(nèi)存重分配,新加入后應(yīng)該是3個元素,所以分配3*32-1=95位。
  2.  選擇最大的數(shù)65535, 放到(95-32+1, 95)位這個內(nèi)存段中,然后2放到(95-32-32+1+1, 95-32)位...依次類推。

升級的好處是什么呢?

  1.  提高了整數(shù)集合的靈活性。
  2.  盡可能節(jié)約內(nèi)存(能用小的就不用大的)。

5.2 不支持降級

按照上面的例子,如果我把65535又刪掉,encoding會不會又回到Int16呢,答案是不會的。官方?jīng)]有給出理由,我覺得應(yīng)該是降低性能消耗吧,畢竟調(diào)整一次是O(N)的時間復(fù)雜度。

6. 壓縮列表(ziplist)

ziplist是redis為了節(jié)約內(nèi)存而開發(fā)的順序型數(shù)據(jù)結(jié)構(gòu)。它被用在列表鍵和哈希鍵中。一般用于小數(shù)據(jù)存儲。

引用https://segmentfault.com/a/1190000016901154中的兩個圖:

6.1 源碼

ziplist沒有明確定義結(jié)構(gòu)體,這里只作大概的演示。 

  1. typedef struct entry {  
  2.      /*前一個元素長度需要空間和前一個元素長度*/  
  3.     unsigned int prevlengh;  
  4.      /*元素內(nèi)容編碼*/  
  5.     unsigned char encoding;  
  6.      /*元素實(shí)際內(nèi)容*/  
  7.     unsigned char *data;  
  8. }zlentry;  
  1. typedef struct ziplist{  
  2.      /*ziplist分配的內(nèi)存大小*/  
  3.      uint32_t zlbytes;  
  4.      /*達(dá)到尾部的偏移量*/  
  5.      uint32_t zltail;  
  6.      /*存儲元素實(shí)體個數(shù)*/  
  7.      uint16_t zllen;  
  8.      /*存儲內(nèi)容實(shí)體元素*/  
  9.      unsigned char* entry[];  
  10.      /*尾部標(biāo)識*/  
  11.      unsigned char zlend;  
  12. }ziplist; 

第一次看可能會特別蒙蔽,你細(xì)細(xì)的把我這段話看完就一定能懂。

Entry的分析

entry結(jié)構(gòu)體里面有三個重要的字段:

  1.  previous_entry_length: 這個字段記錄了ziplist中前一個節(jié)點(diǎn)的長度,什么意思?就是說通過該屬性可以進(jìn)行指針運(yùn)算達(dá)到表尾向表頭遍歷,這個字段還有一個大問題下面會講。
  2.  encoding:記錄了數(shù)據(jù)類型(int16? string?)和長度。
  3.  data/content: 記錄數(shù)據(jù)。

連鎖更新

previous_entry_length字段的分析

上面有說到,previous_entry_length這個字段存放上個節(jié)點(diǎn)的長度,那默認(rèn)長度給分配多少呢?redis是這樣分的,如果前節(jié)點(diǎn)長度小于254,就分配1字節(jié),大于的話分配5字節(jié),那問題就來了。

如果前一個節(jié)點(diǎn)的長度剛開始小于254字節(jié),后來大于254,那不就存放不下了嗎? 這就涉及到previous_entry_length的更新,但是改一個肯定不行阿,后面的節(jié)點(diǎn)內(nèi)存信息都需要改。所以就需要重新分配內(nèi)存,然后連鎖更新包括該受影響節(jié)點(diǎn)后面的所有節(jié)點(diǎn)。

除了增加新節(jié)點(diǎn)會引發(fā)連鎖更新、刪除節(jié)點(diǎn)也會觸發(fā)。

7. 快速列表(quicklist)

一個由ziplist組成的雙向鏈表。但是一個quicklist可以有多個quicklist節(jié)點(diǎn),它很像B樹的存儲方式。是在redis3.2版本中新加的數(shù)據(jù)結(jié)構(gòu),用在列表的底層實(shí)現(xiàn)。

結(jié)構(gòu)體源碼

表頭結(jié)構(gòu):  

  1. typedef struct quicklist { 
  2.     //指向頭部(最左邊)quicklist節(jié)點(diǎn)的指針 
  3.     quicklistNode *head;  
  4.     //指向尾部(最右邊)quicklist節(jié)點(diǎn)的指針 
  5.     quicklistNode *tail;  
  6.     //ziplist中的entry節(jié)點(diǎn)計數(shù)器 
  7.     unsigned long count;        /* total count of all entries in all ziplists */  
  8.     //quicklist的quicklistNode節(jié)點(diǎn)計數(shù)器 
  9.     unsigned int len;           /* number of quicklistNodes */  
  10.     //保存ziplist的大小,配置文件設(shè)定,占16bits 
  11.     int fill : 16;              /* fill factor for individual nodes */  
  12.     //保存壓縮程度值,配置文件設(shè)定,占16bits,0表示不壓縮 
  13.     unsigned int compress : 16; /* depth of end nodes not to compress;0=off */ 
  14. } quicklist; 

quicklist節(jié)點(diǎn)結(jié)構(gòu):

  1. typedef struct quicklistNode {  
  2.     struct quicklistNode *prev;     //前驅(qū)節(jié)點(diǎn)指針  
  3.     struct quicklistNode *next;     //后繼節(jié)點(diǎn)指針  
  4.     //不設(shè)置壓縮數(shù)據(jù)參數(shù)recompress時指向一個ziplist結(jié)構(gòu)  
  5.     //設(shè)置壓縮數(shù)據(jù)參數(shù)recompress指向quicklistLZF結(jié)構(gòu)  
  6.     unsigned char *zl;  
  7.     //壓縮列表ziplist的總長度 
  8.     unsigned int sz;                  /* ziplist size in bytes */  
  9.     //ziplist中包的節(jié)點(diǎn)數(shù),占16 bits長度  
  10.     unsigned int count : 16;          /* count of items in ziplist */  
  11.     //表示是否采用了LZF壓縮算法壓縮quicklist節(jié)點(diǎn),1表示壓縮過,2表示沒壓縮,占2 bits長度  
  12.     unsigned int encoding : 2;        /* RAW==1 or LZF==2 */  
  13.     //表示一個quicklistNode節(jié)點(diǎn)是否采用ziplist結(jié)構(gòu)保存數(shù)據(jù),2表示壓縮了,1表示沒壓縮,默認(rèn)是2,占2bits長度  
  14.     unsigned int container : 2;       /* NONE==1 or ZIPLIST==2 */  
  15.     //標(biāo)記quicklist節(jié)點(diǎn)的ziplist之前是否被解壓縮過,占1bit長度  
  16.     //如果recompress為1,則等待被再次壓縮  
  17.     unsigned int recompress : 1; /* was this node previous compressed? */  
  18.     //測試時使用  
  19.     unsigned int attempted_compress : 1; /* node can't compress; too small */  
  20.     //額外擴(kuò)展位,占10bits長度  
  21.     unsigned int extra : 10; /* more bits to steal for future usage */  
  22. } quicklistNode; 

相關(guān)配置

在redis.conf中的ADVANCED CONFIG部分: 

  1. list-max-ziplist-size -2  
  2. list-compress-depth 0 

list-max-ziplist-size參數(shù)

我們來詳細(xì)解釋一下list-max-ziplist-size這個參數(shù)的含義。它可以取正值,也可以取負(fù)值。

當(dāng)取正值的時候,表示按照數(shù)據(jù)項個數(shù)來限定每個quicklist節(jié)點(diǎn)上的ziplist長度。比如,當(dāng)這個參數(shù)配置成5的時候,表示每個quicklist節(jié)點(diǎn)的ziplist最多包含5個數(shù)據(jù)項。

當(dāng)取負(fù)值的時候,表示按照占用字節(jié)數(shù)來限定每個quicklist節(jié)點(diǎn)上的ziplist長度。這時,它只能取-1到-5這五個值,每個值含義如下:

-5: 每個quicklist節(jié)點(diǎn)上的ziplist大小不能超過64 Kb。(注:1kb => 1024 bytes)

-4: 每個quicklist節(jié)點(diǎn)上的ziplist大小不能超過32 Kb。

-3: 每個quicklist節(jié)點(diǎn)上的ziplist大小不能超過16 Kb。

-2: 每個quicklist節(jié)點(diǎn)上的ziplist大小不能超過8 Kb。(-2是Redis給出的默認(rèn)值)

list-compress-depth參數(shù)

這個參數(shù)表示一個quicklist兩端不被壓縮的節(jié)點(diǎn)個數(shù)。注:這里的節(jié)點(diǎn)個數(shù)是指quicklist雙向鏈表的節(jié)點(diǎn)個數(shù),而不是指ziplist里面的數(shù)據(jù)項個數(shù)。實(shí)際上,一個quicklist節(jié)點(diǎn)上的ziplist,如果被壓縮,就是整體被壓縮的。

參數(shù)list-compress-depth的取值含義如下:

0: 是個特殊值,表示都不壓縮。這是Redis的默認(rèn)值。 1: 表示quicklist兩端各有1個節(jié)點(diǎn)不壓縮,中間的節(jié)點(diǎn)壓縮。 2: 表示quicklist兩端各有2個節(jié)點(diǎn)不壓縮,中間的節(jié)點(diǎn)壓縮。 3: 表示quicklist兩端各有3個節(jié)點(diǎn)不壓縮,中間的節(jié)點(diǎn)壓縮。 依此類推…

Redis對于quicklist內(nèi)部節(jié)點(diǎn)的壓縮算法,采用的LZF——一種無損壓縮算法。 

 

責(zé)任編輯:龐桂玉 來源: Java知音
相關(guān)推薦

2021-09-01 09:44:16

Redis持久化配置

2024-08-29 16:30:27

2025-04-08 00:00:00

@AsyncSpring異步

2024-02-29 16:49:20

volatileJava并發(fā)編程

2019-09-27 08:53:47

Redis數(shù)據(jù)C語言

2020-07-02 07:52:11

RedisHash映射

2022-06-30 14:31:57

Java阻塞隊列

2024-03-14 14:56:22

反射Java數(shù)據(jù)庫連接

2021-11-02 09:05:25

Redis

2020-03-06 15:36:01

Redis內(nèi)存宕機(jī)

2020-09-26 22:04:32

數(shù)據(jù)安全傳輸HTTPSHTTP 協(xié)議

2015-08-13 10:29:12

面試面試官

2024-04-09 10:40:04

2024-10-22 16:39:07

2020-11-10 13:47:29

String源碼長度限制

2022-06-15 15:14:17

Java公平鎖非公平鎖

2019-06-12 22:51:57

Redis軟件開發(fā)

2022-07-18 13:59:43

Redis單線程進(jìn)程

2024-03-06 15:38:06

Spring微服務(wù)架構(gòu)擴(kuò)展組件

2019-04-17 15:35:37

Redis數(shù)據(jù)庫數(shù)據(jù)結(jié)構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

女人让男人操自己视频在线观看 | 国产福利视频一区| 久久精品国产亚洲av麻豆| 中文在线免费二区三区| 中文字幕 久热精品 视频在线 | 日韩在线视频播放| 人妻 丝袜美腿 中文字幕| av电影一区| 亚洲日本va在线观看| 久久国产精品精品国产色婷婷| 精人妻无码一区二区三区| 亚洲成人二区| 亚洲女人天堂网| 涩涩网站在线看| 伊人久久视频| 亚洲国产乱码最新视频| 色综合电影网| 日本美女一级片| 久久国产精品无码网站| 91精品国产91久久久久久吃药 | 欧美精品三区| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲色图欧美自拍| 欧美aaa视频| 精品女厕一区二区三区| 欧美一二三不卡| 淫片在线观看| 久久综合久久综合亚洲| 成人资源av| 国产乱色精品成人免费视频| 久久久久久久欧美精品| 国内精品久久久久久久久| 奇米网一区二区| 免费看av成人| 精品视频在线观看日韩| 久久性爱视频网站| 深夜福利一区二区三区| 欧美绝品在线观看成人午夜影视| 男女av免费观看| 成av人片在线观看www| 亚洲一级片在线观看| 蜜桃视频成人在线观看| eeuss影院www在线观看| 久久久久久毛片| 蜜桃视频在线观看91| 日韩在线观看视频一区二区三区| 国产成人综合在线播放| 1区1区3区4区产品乱码芒果精品| 91久久精品无码一区二区| 蜜桃久久久久久久| 国产精品直播网红| 国产成人av免费| 日本欧美在线看| 国产精品精品一区二区三区午夜版| 中文字幕亚洲精品一区| 国产亚洲精品v| 欧美中文字幕第一页| 好看的av在线| 久久精品亚洲一区二区| 国产精品久久久久久久久久久新郎| 久久人人爽人人爽人人片av免费| 视频一区在线播放| 国产精品视频精品视频| 亚洲综合五月天婷婷丁香| 极品尤物av久久免费看| av资源一区二区| 色婷婷中文字幕| 久久久国产精品麻豆| 亚洲精品在线免费看| 欧美jizzhd69巨大| 夜色激情一区二区| 黄色一级视频片| 亚洲精品国产嫩草在线观看| 欧美日韩一区不卡| 精产国品一二三区| 久草在线综合| 一区二区欧美亚洲| 唐朝av高清盛宴| 国产视频一区三区| 国产美女久久精品香蕉69| 国产激情视频在线播放 | 91.麻豆视频| 久久久久99人妻一区二区三区| 久久久久97| 中国china体内裑精亚洲片| 亚洲综合网在线| 亚洲精品三级| 国产欧美日韩视频| 丰满肉肉bbwwbbww| 国产欧美视频一区二区三区| 在线观看免费黄色片| 爱情岛论坛亚洲品质自拍视频网站| 欧美视频一区二区三区…| 91欧美视频在线| aaa国产精品| 在线看片第一页欧美| 国产一级二级三级视频| 日精品一区二区| av色综合网| www.亚洲免费| 天天av天天翘天天综合网| jizzzz日本| 欧美性生活一级片| 久久视频在线播放| 日本视频免费观看| 丁香亚洲综合激情啪啪综合| 日韩欧美一区二区在线观看| 久久不射影院| 欧美精选在线播放| 中国女人特级毛片| 激情婷婷欧美| 成人看片人aa| 国产鲁鲁视频在线观看免费| 亚洲大片在线观看| 超碰人人草人人| 欧美**字幕| 91精品国产九九九久久久亚洲| 91久久精品国产91性色69| 久久婷婷国产综合国色天香| 黄色激情在线视频| 国产一区二区三区视频在线| 国产亚洲精品久久久久久牛牛| 动漫精品一区一码二码三码四码| 麻豆传媒一区二区三区| 欧美久久久久久一卡四| av老司机免费在线| 欧美一级黄色片| 潘金莲一级黄色片| 视频一区欧美日韩| 久久人人九九| 免费h在线看| 精品电影一区二区| 老妇女50岁三级| 精品一区二区三区久久| 亚洲春色在线视频| 日日av拍夜夜添久久免费| 日韩hd视频在线观看| 九九视频免费观看| 国产精品一二三四五| 正在播放91九色| 日韩黄色在线| 日韩视频在线免费观看| 在线观看国产小视频| 日本一区二区不卡视频| 欧美性猛交xxx乱久交| 精品日韩毛片| 国产精品自产拍高潮在线观看| 91伦理视频在线观看| 欧洲日韩一区二区三区| 中文字幕有码在线播放| 日韩1区2区日韩1区2区| 亚洲国产日韩欧美| 免费视频成人| 欧美成人精品激情在线观看| 国产999久久久| 亚洲一区免费视频| www.17c.com喷水少妇| 在线综合亚洲| 欧美一区观看| 亚洲高清影院| 欧美乱妇高清无乱码| 免费看日韩av| 色婷婷激情综合| 欧美a级片免费看| 国产酒店精品激情| 国产九九九九九| 九一亚洲精品| 国产日韩欧美夫妻视频在线观看 | 97国产精品久久| 欧美女子与性| 欧美日韩和欧美的一区二区| 综合五月激情网| 99免费精品视频| 中文字幕在线观看第三页| 欧美激情理论| 国产伦精品一区二区三| 美女福利一区二区三区| 久久精品国产2020观看福利| 亚洲av无码片一区二区三区| 天天综合色天天| 国产亚洲精品精品精品| 高清国产一区二区| 国产成人久久婷婷精品流白浆| 成人动漫免费在线观看| 91aaaa| 成人勉费视频| 欧美精品生活片| 欧美xxx.com| 91精品国产综合久久福利软件 | 日本在线天堂| 欧美成人vr18sexvr| 日韩综合在线观看| 一区二区三区中文免费| 亚洲精品视频久久久| 国产一区二区三区视频在线播放| a级黄色一级片| 国产韩日影视精品| 欧美黑人3p| 日韩精品久久久久久久软件91| 日韩美女av在线免费观看| 在线heyzo| 中文字幕亚洲在线| 亚洲av成人精品一区二区三区在线播放 | 丰满少妇久久久久久久| 麻豆三级在线观看| 亚洲日本激情| 日本一二三区视频在线| 国产a久久精品一区二区三区| 99久久99久久| 欧美高清影院| 日本免费久久高清视频| 成人性生交大片免费看网站| 久久精品欧美视频| 成人在线免费视频| 精品无人国产偷自产在线| 亚洲不卡免费视频| 在线不卡一区二区| 国产主播第一页| 婷婷成人综合网| 91porn在线视频| 亚洲欧洲日本在线| 国产7777777| 91视频观看免费| 国产精品亚洲一区二区无码| 老司机精品视频一区二区三区| 日韩av资源在线| 亚洲高清激情| 男人天堂手机在线视频| 亚洲精品国产成人影院| 一区二区三区我不卡| 欧美精品一区二区久久| 蜜桃精品久久久久久久免费影院| 欧美亚洲国产日韩| 久久久7777| 亚州国产精品| 久久综合一区二区三区| 婷婷综合电影| 欧美精品一区三区在线观看| 婷婷成人综合| 欧美一区二区福利| 韩日一区二区三区| 日韩三级电影免费观看| 欧美精选一区二区三区| 日韩视频在线观看国产| 精品美女久久久| 亚洲午夜精品福利| 羞羞答答成人影院www| 一区在线电影| 忘忧草精品久久久久久久高清| 亚洲图片小说在线| 中文字幕午夜精品一区二区三区 | 久久美女免费视频| 国产片一区二区| 亚洲AV成人无码网站天堂久久| 中文字幕一区不卡| 69av视频在线| 亚洲第一成人在线| 国产视频1区2区| 91福利在线看| 国产日韩欧美一区二区东京热| 91精选在线观看| 成人午夜精品福利免费| 亚洲精品国产免费| 成人在线播放视频| 欧美成人高清视频| av资源中文在线| 国产精品99久久99久久久二8| 国产精品4hu.www| 91久久伊人青青碰碰婷婷| 欧美大胆视频| 亚洲欧洲精品在线| 亚洲特级毛片| 动漫av免费观看| 国产一区二区三区香蕉| 免费中文字幕av| 国产精品久久久久久久久免费丝袜 | 欧美久久香蕉| 日韩欧美精品久久| 国产精品大片| 国产一级做a爰片久久| 国产精品一二三在| 中文字幕一区二区三区人妻电影| 国产精品你懂的| 五月天婷婷丁香| 在线观看日产精品| 亚洲精品无amm毛片| 亚洲人成网站色ww在线| 最近中文字幕免费mv2018在线| 69av视频在线播放| 高清不卡一区| 欧美日韩综合另类| 欧美区亚洲区| 亚洲精品视频导航| 播五月开心婷婷综合| 日韩精品久久久久久久的张开腿让| 亚洲午夜影视影院在线观看| 黄色污污视频软件| 亚洲国产成人在线播放| 日本美女高清在线观看免费| 性欧美亚洲xxxx乳在线观看| 香蕉久久一区| 日本精品国语自产拍在线观看| 欧美国产三级| 91欧美视频在线| 久久综合九色综合久久久精品综合| 亚洲 欧美 变态 另类 综合| 日韩欧美第一页| 亚洲欧美激情国产综合久久久| 中文字幕视频在线免费欧美日韩综合在线看 | 91视频网页| 欧美xxav| 欧美视频第三页| 成年人午夜久久久| 成人免费毛片xxx| 欧美三级日韩三级国产三级| 无码精品人妻一区二区| 欧美激情成人在线视频| 欧美极品在线| 小说区图片区图片区另类灬| 国产精品久久久久久模特| 精品人妻二区中文字幕| 中文字幕在线不卡一区| 欧美日韩在线视频播放| 日韩电影在线观看中文字幕| 国产网红女主播精品视频| 91亚洲永久免费精品| 天天做天天爱天天综合网2021| 黄色三级视频片| 久久久av毛片精品| 久久久午夜影院| 亚洲国产成人精品女人久久久| 免费电影网站在线视频观看福利| 成人激情免费在线| 99久久精品费精品国产| 超碰超碰在线观看| 日本一区二区三区视频视频| 特级西西444www大精品视频免费看| 欧美精品一区在线观看| 男女视频在线| 国产精品99久久久久久久| 欧美日韩亚洲一区二区三区在线| 五月花丁香婷婷| 亚洲色图都市小说| 999久久久久久| 色综合久久中文字幕综合网小说| 日本一区二区三区视频在线看| 中文字幕一区二区三区有限公司 | 精品日韩一区二区三区| 青青草视频在线免费直播| 999精品视频一区二区三区| 欧美日本中文| 国产精品手机在线观看| 精品久久久久人成| 免费播放片a高清在线观看| 国产福利成人在线| 91亚洲一区| 久久久国产精品久久久| 亚洲一区二区三区四区中文字幕| 亚洲xxx在线| 欧美孕妇孕交黑巨大网站| 国产一区日韩| 五月天婷婷影视| 亚洲一区二区三区四区五区黄| 天堂中文资源在线观看| 日韩av手机在线| 91精品啪在线观看国产81旧版| 中文字幕一区二区三区人妻在线视频 | 日韩精品一线二线三线| 紧缚奴在线一区二区三区| 久久久香蕉视频| 亚洲欧美国产一本综合首页| 嫩草伊人久久精品少妇av杨幂| 中文字幕欧美日韩一区二区三区| 国产91在线观看丝袜| 少妇一级淫片免费放中国| 国产一区二区三区日韩欧美| 91嫩草国产线观看亚洲一区二区 | 视频一区视频二区中文字幕| 黄色免费一级视频| 精品国产污污免费网站入口 | 欧美日韩国产乱码电影| 高潮毛片在线观看| 好吊色欧美一区二区三区视频| 丝袜亚洲另类欧美| 美女福利视频在线观看| 亚洲欧美日本另类| 精品国产一区二区三区2021| 亚洲欧洲日产国码无码久久99| 中文字幕一区二区三区蜜月| 色欲av永久无码精品无码蜜桃 | 中文幕一区二区三区久久蜜桃| www.天堂av.com| 国产精品va在线| 欧美特黄a级高清免费大片a级| 亚洲区自拍偷拍| 精品久久久久久综合日本欧美| 91九色综合| 俄罗斯av网站| 亚洲精品成人在线| xxxxx日韩|