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

聊一聊 Redis 數據內部存儲使用到的數據結構

存儲 Redis
Redis 數據庫雖然一直都在使用,但是對其內部存儲結構之類的,都沒有研究過,哪怕是面試的時候都沒有準備過這方面的東西。最近在看一門網課,里面有講到過這一塊的內容,結合了《Redis 設計與實現》這本書,粗略的整理了 Redis 的內部存儲結構。

 Redis 數據庫雖然一直都在使用,但是對其內部存儲結構之類的,都沒有研究過,哪怕是面試的時候都沒有準備過這方面的東西。最近在看一門網課,里面有講到過這一塊的內容,結合了《Redis 設計與實現》這本書,粗略的整理了 Redis 的內部存儲結構。就是下面這張圖。

 

對于 Redis 數據庫,絕大多數人都知道有每個 Redis 實例有 16 個數據庫,但是對于內部是怎么扭轉的大部分人可能不太清楚,反正我是不清楚。整體流程差不多就是上圖表示的那樣吧,知識面有限,難免存在缺漏,湊合著看吧。

其實前面的這些都不是太重要,重要的是后面那四種數據結構和 redisObject。不管重不重要了,都來過一遍吧。

redisDb

redisDb 就是數據庫實例,存儲了真實的數據,每個 Redis 實例都會有 16 個 redisDb。redisDb 的結構定義如下:

 

  1. typedef struct redisDb { 
  2.     dict *dict;                 /* The keyspace for this DB */ 
  3.     dict *expires;              /* Timeout of keys with a timeout set */ 
  4.     dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/ 
  5.     dict *ready_keys;           /* Blocked keys that received a PUSH */ 
  6.     dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */ 
  7.     int id;                     /* Database ID */ 
  8.     long long avg_ttl;          /* Average TTL, just for stats */ 
  9.     list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */ 
  10. } redisDb; 

redisDb 結構體中有 8 個參數:

  • dict:dict 是用來存儲數據的,當前 DB 下的所有數據都存放在這里。
  • expires:存儲 key 與過期時間的映射。
  • blocking_keys:存儲處于阻塞狀態的 key 及 client 列表。比如在執行 Redis 中 list 的阻塞命令 blpop、brpop 或者 brpoplpush 時,如果對應的 list 列表為空,Redis 就會將對應的 client 設為阻塞狀態,同時將該 client 添加到 DB 中 blocking_keys 這個阻塞 dict。
  • ready_keys:存儲解除阻塞的 Key。當有其他調用方在向某個 key 對應的 list 中增加元素時,Redis 會檢測是否有 client 阻塞在這個 key 上,即檢查 blocking_keys 中是否包含這個 key,如果有則會將這個 key 加入 read_keys 這個 dict 中。同時也會將這個 key 保存到 server 中的一個名叫 read_keys 的列表中。
  • watched_keys:當 client 使用 watch 指令來監控 key 時,這個 key 和 client 就會被保存到 watched_keys 這個 dict 中。
  • id:數據庫編號。

Dict

Dict 數據結構在 Redis 中非常的重要,你可以看到在 redisDb 中,8 個字段中有 5 個是 dict,并且在其他地方也有大量的應用。dict 結構體定義如下:

 

  1. typedef struct dict { 
  2.     dictType *type; 
  3.     void *privdata; 
  4.     dictht ht[2]; 
  5.     long rehashidx; /* rehashing not in progress if rehashidx == -1 */ 
  6.     unsigned long iterators; /* number of iterators currently running */ 
  7. } dict; 

dict 本身是比較簡單的,字段也不多,其中有三個字段比較重要,有必要了解一下:

  • type:用于保存 hash 函數及 key/value 賦值、比較函數。
  • ht[2]:用來存儲數據的數組。默認使用的是 0 號數組,如果 0 號哈希表元素過多,則分配一個 2 倍 0 號哈希表大小的空間給 1 號哈希表,然后進行逐步遷移。
  • rehashidx:用來做標志遷移位置。

Dictht & DictEntry

 

  1. typedef struct dictht { 
  2.     # 哈希表數組 
  3.     dictEntry **table
  4.     # 哈希表大小 
  5.     unsigned long size
  6.     #哈希表大小掩碼,用于計算索引值 
  7.     unsigned long sizemask; 
  8.     # 該哈希表已有節點的數量 
  9.     unsigned long used; 
  10. } dictht; 
  11.  
  12. typedef struct dictEntry { 
  13.     # 鍵 
  14.     void *key
  15.     union { 
  16.         # 值 
  17.         void *val; 
  18.         uint64_t u64; 
  19.         int64_t s64; 
  20.         double d; 
  21.     } v; 
  22.     # 指向下個哈希表節點,形成鏈表 
  23.     struct dictEntry *next
  24. } dictEntry; 

dictht 數據結構沒啥說的,dictEntry 是真正掛載數據的節點,跟 Java 中的 Map 有一點像,采用 key-value 的映射方式。key 采用的是 sds 結構的字符串,value 為存儲各種數據類型的 redisObject 結構。

redisObject、sds還有其他幾種數據結構才是重點,面試的時候有可能會出現,作為使用者,其實了解這幾個就夠了。

redisObject

redisObject 可以理解成 Redis 數據的數據頭,里面定義了一些數據的信息。redisObject 結構體定義如下:

 

  1. typedef struct redisObject { 
  2.     unsigned type:4; 
  3.     unsigned encoding:4; 
  4.     unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or 
  5.                             * LFU data (least significant 8 bits frequency 
  6.                             * and most significant 16 bits access time). */ 
  7.     int refcount; 
  8.     void *ptr; 
  9. } robj; 

redisObject 結構體字段不多,就 5 個字段,但是這幾個字段都挺重要的,過一下這 5 個字段的含義:

type

type 表示的是 Redis 對象的數據類型,代表這條數據是什么類型,目前 Redis 有 7 種類型。分別為:

  • OBJ_STRING:字符串對象。
  • OBJ_LIST:列表對象。
  • OBJ_SET:集合對象。
  • OBJ_ZSET:有序集合對象。
  • OBJ_HASH:哈希對象。
  • OBJ_MODULE:模塊對象。
  • OBJ_STREAM:消息隊列/流對象。

encoding

encoding 是 Redis 對象的內部編碼方式,即這條數據最終在內部是以哪種數據結構存放的。這個字段的作用還是相當大的,我看了一下源碼,目前 Redis 中有 10 種編碼方式,如下:

  • OBJ_ENCODING_RAW
  • OBJ_ENCODING_INT
  • OBJ_ENCODING_HT
  • OBJ_ENCODING_ZIPLIST
  • OBJ_ENCODING_ZIPMAP
  • OBJ_ENCODING_SKIPLIST
  • OBJ_ENCODING_EMBSTR
  • OBJ_ENCODING_QUICKLIST
  • OBJ_ENCODING_STREAM
  • OBJ_ENCODING_INTSET

LRU

LRU 存儲的是淘汰數據用的 LRU 時間或 LFU 頻率及時間的數據。

refcount

refcount 記錄 Redis 對象的引用計數,用來表示對象被共享的次數,共享使用時加 1,不再使用時減 1,當計數為 0 時表明該對象沒有被使用,就會被釋放,回收內存。

ptr

ptr 是真實數據存儲的引用,它指向對象的內部數據結構。比如一個 string 的對象,內部可能是 sds 數據結構,那么 ptr 指向的就是 sds,除此之外,ptr 還可能指向 ziplist、quicklist、skiplist。

redisObject 大概就這些,下面在聊一聊 Redis 中內存常用的四種數據結構。

1.sds(簡單動態字符串)

Redis沒有直接使用C語言傳統的字符串表示(以空字符結尾的字符數組,以下簡稱C字符串),而是自己構建了一種名為簡單動態字符串(simple dynamic string,SDS)的抽象類型,并將 SDS 用作 Redis 的默認字符串表示。

實現者為了較少開銷,就 sds 定義了 5 種結構體,分別為:sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64。這樣最終存儲的時候 sds 會根據字符串實際的長度,選擇不同的數據結構,以更好的提升內存效率。5 種結構體的源代碼如下:

 

  1. struct __attribute__ ((__packed__)) sdshdr5 { 
  2.     unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ 
  3.     char buf[]; 
  4. }; 
  5. struct __attribute__ ((__packed__)) sdshdr8 { 
  6.     uint8_t len; /* used */ 
  7.     uint8_t alloc; /* excluding the header and null terminator */ 
  8.     unsigned char flags; /* 3 lsb of type, 5 unused bits */ 
  9.     char buf[]; 
  10. }; 
  11. struct __attribute__ ((__packed__)) sdshdr16 { 
  12.     uint16_t len; /* used */ 
  13.     uint16_t alloc; /* excluding the header and null terminator */ 
  14.     unsigned char flags; /* 3 lsb of type, 5 unused bits */ 
  15.     char buf[]; 
  16. }; 
  17. struct __attribute__ ((__packed__)) sdshdr32 { 
  18.     uint32_t len; /* used */ 
  19.     uint32_t alloc; /* excluding the header and null terminator */ 
  20.     unsigned char flags; /* 3 lsb of type, 5 unused bits */ 
  21.     char buf[]; 
  22. }; 
  23. struct __attribute__ ((__packed__)) sdshdr64 { 
  24.     uint64_t len; /* used */ 
  25.     uint64_t alloc; /* excluding the header and null terminator */ 
  26.     unsigned char flags; /* 3 lsb of type, 5 unused bits */ 
  27.     char buf[]; 
  28. }; 

除了 sdshdr5 之外,其他的幾個數據結構都包含 4 個字段:

  • len:字符串的長度。
  • alloc:給字符串分配的內存大小。
  • flags:當前字節數組的屬性。
  • buf:存儲字符串真正的值和一個結束符 \0。

在 redisObject 中有一個編碼方式的字段,sds 數據結構有三種編碼方式,分別為 INT、RAW 、EMBSTR。INT 就相對比較簡單,ptr 直接指向了具體的數據。在這里就簡單的說一說 RAW 和 EMBSTR 的區別。

在 Redis 源碼中,有這么一段代碼,來判斷采用哪種編碼方式。當保存的字符串長度小于等于 44 ,采用的是 embstr 編碼格式,否則采用 RAW 編碼方式。(具體的長度可能每個版本定義不一樣)

 

  1. #define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44 
  2. robj *createStringObject(const char *ptr, size_t len) { 
  3.     if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) 
  4.         return createEmbeddedStringObject(ptr,len); 
  5.     else 
  6.         return createRawStringObject(ptr,len); 

 

 

 

embstr 和 raw 編碼方式最主要的區別是在內存分配的時候。embstr 編碼是專門用于保存短字符串的一種優化編碼方式,raw 編碼會調用兩次內存分配函數來分別創建 redisObject 結構和 sdshdr 結構,而 embstr 編碼則通過調用一次內存分配函數來分配一塊連續的空間,空間中依次包含redisObject和sdshdr兩個結構。

embstr 編碼

 

raw 編碼

 

 

 

 

raw 編碼

sds 主要是作為字符串的內部數據結構,同時 sds 也是 hyperloglog、bitmap 類型的內部數據結構。

2.ziplist(壓縮列表)

ziplist 是專門為了節約內存,并減少內存碎片而設計的數據結構,ziplist是一塊連續的內存空間,可以連續存儲多個元素,沒有冗余空間,是一種連續內存數據塊組成的順序型內存結構。

 

 

 

 

ziplist 主要包含 5 個部分:

  • zlbytes:ziplist所占用的總內存字節數。
  • Zltail:尾節點到起始位置的字節數。
  • Zllen:總共包含的節點/內存塊數。
  • Entry:ziplist 保存的各個數據節點,這些數據點長度隨意。
  • Zlend:一個魔數 255,用來標記壓縮列表的結束。

 

 

 

 

如圖所示,一個包含 4 個元素的 ziplist,總占用字節是 100bytes,該 ziplist 的起始元素的指針是 p,zltail 是 80,則第 4 個元素的指針是 P+80。

ziplist 的存儲節點是 zlentry, zlentry 結構體定義如下:

 

  1. typedef struct zlentry { 
  2.     unsigned int prevrawlensize; /* Bytes used to encode the previous entry len*/ 
  3.     unsigned int prevrawlen;     /* Previous entry len. */ 
  4.     unsigned int lensize;        /* Bytes used to encode this entry type/len. 
  5.                                     For example strings have a 1, 2 or 5 bytes 
  6.                                     header. Integers always use a single byte.*/ 
  7.     unsigned int len;            /* Bytes used to represent the actual entry. 
  8.                                     For strings this is just the string length 
  9.                                     while for integers it is 1, 2, 3, 4, 8 or 
  10.                                     0 (for 4 bit immediate) depending on the 
  11.                                     number range. */ 
  12.     unsigned int headersize;     /* prevrawlensize + lensize. */ 
  13.     unsigned char encoding;      /* Set to ZIP_STR_* or ZIP_INT_* depending on 
  14.                                     the entry encoding. However for 4 bits 
  15.                                     immediate integers this can assume a range 
  16.                                     of values and must be range-checked. */ 
  17.     unsigned char *p;            /* Pointer to the very start of the entry, that 
  18.                                     is, this points to prev-entry-len field. */ 
  19. } zlentry; 

zlentry 結構體中有 6 個字段:

  • prevRawLen:前置節點的長度;
  • preRawLenSize:編碼 preRawLen 需要的字節數;
  • len:當前節點的長度;
  • lensize:編碼 len 所需要的字節數;
  • encoding: 當前節點所用的編碼類型;
  • entryData:當前節點數據;

 

 

 

 

由于 ziplist 是連續緊湊存儲,沒有冗余空間,所以插入新的元素需要 realloc 擴展內存,所以如果 ziplist 占用空間太大,realloc 重新分配內存和拷貝的開銷就會很大,所以 ziplist 不適合存儲過多元素,也不適合存儲過大的字符串。

ziplist 是 hash、sorted set 數據類型的內部存儲結構之一,對于 hash 來說,當元素不超過 512 個 并且值不超過 64個字節,會使用 ziplist 作為內存存儲結構,我們可以通過修改 hash-max-ziplist-entries、hash-max-ziplist-value 參數來控制。對于 sorted set 來說,當元素個數不超過 128個并且值不超過 64 字節,使用 ziplist 來存儲,可以通過調整 zset-max-ziplist-entries、zset-max-ziplist-value 來控制。

3.quicklist(快速列表)

quicklist 數據結構是 Redis 在 3.2 之后引入的,用來替換 linkedlist。因為 linkedlist 每個節點有前后指針,要占用 16 字節,而且每個節點獨立分配內存,很容易加劇內存的碎片化。

而 ziplist 由于緊湊型存儲,增加元素需要 realloc,刪除元素需要內存拷貝,天然不適合元素太多、value 太大的存儲,quicklist 也就誕生了。

quicklist 相關結構體定義如下:

 

  1. typedef struct quicklist { 
  2.     quicklistNode *head; 
  3.     quicklistNode *tail; 
  4.     unsigned long count;        /* total count of all entries in all ziplists */ 
  5.     unsigned long len;          /* number of quicklistNodes */ 
  6.     int fill : 16;              /* fill factor for individual nodes */ 
  7.     unsigned int compress : 16; /* depth of end nodes not to compress;0=off */ 
  8. } quicklist; 
  9.  
  10. typedef struct quicklistNode { 
  11.     struct quicklistNode *prev; 
  12.     struct quicklistNode *next
  13.     unsigned char *zl; 
  14.     unsigned int sz;             /* ziplist size in bytes */ 
  15.     unsigned int count : 16;     /* count of items in ziplist */ 
  16.     unsigned int encoding : 2;   /* RAW==1 or LZF==2 */ 
  17.     unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */ 
  18.     unsigned int recompress : 1; /* was this node previous compressed? */ 
  19.     unsigned int attempted_compress : 1; /* node can't compress; too small */ 
  20.     unsigned int extra : 10; /* more bits to steal for future usage */ 
  21. } quicklistNode; 

quicklist 整體結構圖:

 

 

 

 

quicklist 整體結構還是比較簡單的,它是一個基于 ziplist 的雙向鏈表。將數據分段存儲到 ziplist,然后將這些 ziplist 用雙向指針連接。

quicklist 結構體說明:

  • head、tail 是兩個指向第一個和最后一個 ziplist 節點的指針。
  • count 是 quicklist 中所有的元素個數。
  • len 是 ziplist 節點的個數。
  • compress 是 LZF 算法的壓縮深度。

quicklistNode 結構體就更簡單的了,quicklistNode 主要包含一個 prev/next 雙向指針,以及一個 ziplist 節點。單個 ziplist 節點可以存放多個元素。

 

 

 

 

quicklist 是 list 列表的內部數據結構,quicklist 從頭尾讀寫數據很快,時間復雜度為 O(1)。也支持從中間任意位置插入或讀寫元素,但速度較慢,時間復雜度為 O(n)。

4.zskiplist(跳躍表)

在 Java 中也有跳躍表,跳躍表 zskiplist 是一種有序數據結構,它通過在每個節點維持多個指向其他節點的指針,從而可以加速訪問,在大部分場景,跳躍表的效率和平衡樹接近,跳躍表支持平均 O(logN) 和最差 O(n) 復雜度的節點查找,并且跳躍表的實現比平衡樹要簡單。

但是在 Redis 中zskiplist 應用的并不多,只有在以下兩種情況下會使用到跳躍表:

  • 在 sorted set 數據類型中,如果元素數較多或元素長度較大,則使用跳躍表作為內部數據結構。默認元素數超過 128 或者最大元素的長度超過 64,此時有序集合就采用 zskiplist 進行存儲。
  • 在集群結點中用作內部數據結構。

在 Redis 中,跳躍表主要有 zskiplistNode 和 zskiplist 組合,定義如下:

 

  1. typedef struct zskiplistNode { 
  2.     sds ele; 
  3.     double score; 
  4.     struct zskiplistNode *backward; 
  5.     struct zskiplistLevel { 
  6.         struct zskiplistNode *forward
  7.         unsigned long span; 
  8.     } level[]; 
  9. } zskiplistNode; 
  10. typedef struct zskiplist { 
  11.     struct zskiplistNode *header, *tail; 
  12.     unsigned long length; 
  13.     int level
  14. } zskiplist; 
  15. typedef struct zset { 
  16.     dict *dict; 
  17.     zskiplist *zsl; 
  18. } zset; 

跳躍表 zskiplist 結構比較簡單,有四個字段:

  • header 指向跳躍表的表頭節點。
  • tail 指向跳躍表的表尾節點。
  • length 表示跳躍表的長度,它是跳躍表中不包含表頭節點的節點數量。
  • level 是目前跳躍表內,除表頭節點外的所有節點中,層數最大的那個節點的層數。跳躍表的節點 zskiplistNode 要相對復雜一些。不過也只有 4 個字段:
  • ele 是節點對應的 sds 值,在 zset 有序集合中就是集合中的 field 元素。
  • score 是節點的分數,通過 score,跳躍表中的節點自小到大依次排列。
  • backward 是指向當前節點的前一個節點的指針。
  • level 是節點中的層,每個節點一般有多個層。每個 level 層都帶有兩個屬性,一個是 forwad 前進指針,它用于指向表尾方向的節點;另外一個是 span 跨度,它是指 forward 指向的節點到當前節點的距離。

跳躍表的思想比較簡單,以空間換時間,可以實現快速查找。比如我們要找 S3 這個節點,從先從表頭節點的 L32 層開始查找,一層一層的下沉,最后找到想要的元素。

最后總結一下 Redis 的 8 大類型使用的內部存儲結構。

 

 

 

 

責任編輯:華軒 來源: 互聯網平頭哥
相關推薦

2018-04-27 09:22:21

數據存儲技巧

2022-11-07 09:00:33

2022-05-18 16:35:43

Redis內存運維

2020-07-16 14:40:23

大數據計算框架

2018-07-03 08:48:48

對象存儲塊存儲

2022-03-08 16:10:38

Redis事務機制

2018-06-25 09:32:44

2018-05-16 08:58:04

用戶畫像存儲

2019-12-12 14:52:10

數據庫腳本

2017-12-26 10:19:14

大數據問題缺陷

2022-08-30 10:15:27

Kubernetes數據持久化管理

2022-05-12 23:19:15

Redis內存碎片處理

2022-05-16 09:59:30

內部威脅網絡安全

2019-12-13 10:50:49

集群Redis存儲

2023-03-06 21:23:23

Redis數據庫

2018-04-19 10:22:06

數據中心連接性托管

2018-03-22 10:36:15

未來數據中心停機

2022-04-13 18:01:39

CSS組件技巧

2020-11-17 06:57:15

存儲互聯網用戶

2018-03-26 14:51:17

數據中心停機中斷邊緣計算
點贊
收藏

51CTO技術棧公眾號

亚洲大片在线| av影片在线| 精品亚洲成a人| 亚洲欧美精品一区二区| 日韩av片在线看| 久蕉在线视频| 久色婷婷小香蕉久久| 久久精品美女视频网站| 91porn在线| 日韩欧美精品一区二区三区| 国产亲近乱来精品视频 | 亚洲最大av网| 青娱乐国产在线视频| a看欧美黄色女同性恋| 黑人巨大精品欧美一区二区三区| 日本免费高清不卡| 国产免费黄色录像| 日韩午夜av| 日韩av网站大全| 国内外成人免费在线视频| 岛国成人毛片| 91久色porny| 国产有码在线一区二区视频| 国产在线视频二区| 久久久久影视| 欧美二区三区91| ww国产内射精品后入国产| av大全在线免费看| 成人国产精品免费观看| 国产精品老女人视频| 精品福利一区二区三区| 久久免费一级片| 成人久久久精品国产乱码一区二区| 一本久久知道综合久久| 日韩日本欧美亚洲| 日本一卡二卡在线| 91久久青草| 欧美色视频日本版| 色婷婷777777仙踪林| 蜜桃视频在线观看视频| 国产成人av电影在线| 国产精品久久久久久搜索 | 国产精品美女一区二区在线观看| 成人av免费看| 国产免费a视频| 国产欧美69| 欧美国产乱视频| 天堂资源在线视频| 极品国产人妖chinesets亚洲人妖| 在线观看日韩高清av| 国产精品久久久久久久乖乖| 91在线看黄| 久久亚洲一区二区三区明星换脸| 亚洲自拍偷拍色图| 国产91av在线播放| 麻豆久久精品| 2020欧美日韩在线视频| 亚洲一区二区91| 在线看日韩欧美| 国产中文字幕乱人伦在线观看| 毛片免费在线| 成人精品一区二区三区四区| 成人看片人aa| 91丨porny丨在线中文| 老司机久久99久久精品播放免费| 97国产在线观看| 久久精品一区二区三| 亚洲国产精品成人| 色偷偷av亚洲男人的天堂| 91l九色lporny| 国产精品午夜一区二区三区| 亚洲欧美日韩图片| 国产精品毛片一区二区| 色88888久久久久久影院| 精品国产免费一区二区三区四区| 中文字幕第三区| 国产精品xxx| 欧美日韩亚洲综合| 色一情一区二区三区| 色999韩欧美国产综合俺来也| 91久久国产综合久久| 国产av无码专区亚洲精品| 欲香欲色天天天综合和网| 亚洲h在线观看| 天天夜碰日日摸日日澡性色av| 在线免费观看污| 亚洲在线免费播放| 99色这里只有精品| 女人高潮被爽到呻吟在线观看 | 精品国产乱码久久久久| 亚洲 精品 综合 精品 自拍| 91日韩在线专区| 日本一区二区三区免费看| 国产色a在线| 国产精品国产a| 热久久最新地址| 草美女在线观看| 色欧美日韩亚洲| 一级黄色特级片| 日韩午夜电影免费看| 欧美一二三区在线观看| 人妻换人妻a片爽麻豆| 黑色丝袜福利片av久久| 亚洲成人激情在线观看| 波多野吉衣中文字幕| 成人激情诱惑| 欧美成人免费一级人片100| 久久这里只有精品免费| 亚洲深爱激情| 国产美女高潮久久白浆| 亚洲国产精品久久久久久久| www国产精品av| 亚洲欧美国产不卡| 一色桃子av在线| 黄色成人在线播放| 麻豆一区二区三区视频| 亚洲开心激情| 亚洲夜晚福利在线观看| 欧美成人另类视频| 国产精品啊啊啊| 日韩暖暖在线视频| www.亚洲天堂.com| 久久青草欧美一区二区三区| 午夜欧美性电影| 一二三四区在线观看| 色欲综合视频天天天| 亚洲视频在线不卡| 国产日产精品_国产精品毛片| 久久影视电视剧免费网站清宫辞电视| 国产精品99无码一区二区| 日韩激情一区二区| 国产66精品久久久久999小说| 久久精品国产亚洲a∨麻豆| 亚洲人成伊人成综合网小说| 日韩欧美精品在线观看视频| 网站一区二区| 亚洲日本中文字幕| 精品视频一区二区在线观看| 美女视频黄免费的久久| 九九九九九精品| 日本在线观看视频| 色婷婷一区二区三区四区| 不许穿内裤随时挨c调教h苏绵| 精品久久久久中文字幕小说| 97国产精品视频| 亚洲国产一二三区| 中文字幕在线一区二区三区| 亚洲狼人综合干| 亚洲精品推荐| 欧美激情精品久久久久久| 国产一区二区三区视频免费观看| 国产欧美久久久精品影院| 免费看国产曰批40分钟| 精品国产亚洲日本| 日韩在线观看免费全| 精品乱码一区内射人妻无码 | 精品二区三区线观看| 黑人无套内谢中国美女| 国产精品传媒精东影业在线| 午夜精品久久久久久久99热| 午夜精品在线播放| 亚洲欧美成aⅴ人在线观看| 91插插插插插插插插| 国产欧美一区二区精品久久久| 91高清视频免费观看| 开心激情综合网| 亚洲成在人线在线播放| av不卡中文字幕| 久久一级电影| 国产色视频一区| 免费成人黄色| 在线播放亚洲一区| 成人欧美一区二区三区黑人一 | 国产91精品精华液一区二区三区| 国产91av视频在线观看| 香蕉久久免费电影| 亚洲欧美综合区自拍另类| 800av免费在线观看| 99re这里都是精品| 性做爰过程免费播放| 精品中文视频| 欧美高清视频在线| 丁香六月色婷婷| 欧美日韩午夜激情| 熟女少妇一区二区三区| 亚洲免费综合| 精品在线一区| 自拍偷自拍亚洲精品被多人伦好爽| 日韩精品在线观看一区| 中文字幕xxxx| 欧美高清在线精品一区| 手机在线成人免费视频| 91精品在线观看国产| 7777精品伊久久久大香线蕉语言| 欧美xxxx做受欧美88bbw| 亚洲成av人乱码色午夜| 国产 日韩 欧美 在线| 国产欧美在线观看一区| 天美一区二区三区| 激情久久五月| 日本免费高清一区二区| 日韩深夜福利网站| 欧美激情免费在线| 日韩大胆人体| 欧美精品99久久久**| 久久网免费视频| 久久综合色综合88| 午夜精品免费看| 精品1区2区3区4区| 国产欧美一区二区在线播放| 国产精品25p| 日日摸夜夜添一区| 国产日韩欧美一区二区东京热 | xxxxx.日韩| 九色精品美女在线| 老牛影视av牛牛影视av| 色狠狠色狠狠综合| 丝袜美腿小色网| 久久久国产一区二区三区四区小说| 在线观看免费视频高清游戏推荐 | 蜜臀精品一区二区| 欧美一级淫片| 国产精品青青草| 久久精品嫩草影院| 2019中文字幕免费视频| 91麻豆一二三四在线| 亚洲跨种族黑人xxx| 国产一区二区三区视频免费观看| 精品久久久久久中文字幕| 黄色av免费播放| eeuss国产一区二区三区 | 理论不卡电影大全神| 久久精品国产99国产精品澳门| 天天干天天插天天操| 91精品国产乱码久久蜜臀| 国产无套粉嫩白浆内谢| 国产精品日韩成人| 人妻熟女aⅴ一区二区三区汇编| 国产一区二区久久| 黑森林精品导航| 欧美一级一区| 99热这里只有精品免费| 99re66热这里只有精品8| 鲁鲁视频www一区二区| 欧美专区视频| 成人国产精品久久久久久亚洲| 欧美性理论片在线观看片免费| 欧美精品久久久久久久| av片在线观看永久免费| 最新日韩中文字幕| 欧美人xxx| 超碰精品一区二区三区乱码| 国产高清一区二区三区视频| 久久中文字幕国产| www在线免费观看视频| 久久91亚洲精品中文字幕奶水| 国产乱色在线观看| 九九视频直播综合网| 电影k8一区二区三区久久| 久久久久久久久91| 在线你懂的视频| 久久国产精品99国产精| 欧美巨大xxxx做受沙滩| 久久男人av资源网站| 一根才成人网| 国产精品丝袜视频| 在线免费成人| www.成人三级视频| 另类ts人妖一区二区三区| 欧美另类高清视频在线| 成人影院天天5g天天爽无毒影院| 一本久道久久综合| 亚洲精品国产首次亮相| 你真棒插曲来救救我在线观看| 一区二区精品| 国产又粗又长又大的视频| 国产一区二区三区高清播放| 任你躁av一区二区三区| 久久综合久色欧美综合狠狠| 国产福利在线导航| 一区二区三区日韩在线观看| 日韩污视频在线观看| 日本乱人伦一区| 国产男女猛烈无遮挡| 亚洲精品xxxx| 香蕉视频在线免费看| 色综合久久悠悠| 伊人久久在线| 91亚洲精品久久久| 牲欧美videos精品| 在线不卡视频一区二区| 18成人免费观看视频| 在线观看的毛片| 成人精品视频一区二区三区| 免费网站在线高清观看| 一区二区三区日韩欧美精品| 中文字幕在线观看视频免费| 91麻豆精品91久久久久同性| 香蕉国产在线视频| 精品国产一区二区三区久久狼黑人 | 黄色aaa大片| 在线国产精品播放| 国产美女情趣调教h一区二区| 国产91在线视频| 99久久人爽人人添人人澡| 亚洲国产欧洲综合997久久 | 网友自拍视频在线| 欧美日韩福利视频| 成人亚洲免费| 精品国产中文字幕| 91精品国产乱码久久久久久久 | 亚洲精品一区三区三区在线观看| 亚洲精品免费av| 欧洲美女日日| 成人av一级片| 成人午夜视频在线观看| 波多野结衣欲乱| 色综合久久久久网| 黄色一级a毛片| 久热国产精品视频| a屁视频一区二区三区四区| 狠狠久久综合婷婷不卡| 欧美精品网站| 中文字幕在线视频精品| 国产欧美日本一区视频| 国产原创视频在线| 亚洲成人999| 美女精品导航| 97免费高清电视剧观看| 99久久影视| 成年人三级黄色片| 日本一区二区免费在线观看视频| av图片在线观看| 亚洲激情在线观看| 国产www视频在线观看| 91在线观看网站| 欧美91视频| 91人妻一区二区三区| 日韩美女啊v在线免费观看| 一区二区自拍偷拍| 一区国产精品视频| 成人免费av电影| 日韩精品一区二区三区色偷偷 | 日韩不卡的av| 亚洲欧美日韩久久精品| 国产乱叫456在线| 精品国产一区二区三区四区在线观看 | 欧美日韩一级二级| h视频在线免费| 国产欧美日韩最新| 欧美wwwww| 日日夜夜精品视频免费观看| 亚洲欧美日韩国产另类专区| 国产又爽又黄免费软件| 日韩亚洲欧美中文高清在线| 日韩免费大片| 黄色特一级视频| 成人丝袜18视频在线观看| 国产午夜福利一区二区| 亚洲激情在线观看| 香蕉成人av| 中文字幕免费在线不卡| 国产乱码精品1区2区3区| 91精品国产闺蜜国产在线闺蜜| 日韩丝袜美女视频| 国产高清视频色在线www| 你懂的视频在线一区二区| 丝袜美腿成人在线| 毛片久久久久久| 91精品国产一区二区三区| av片在线观看网站| 国产伦精品一区二区三区高清版| 亚洲免费高清| av网在线播放| 3751色影院一区二区三区| 男人天堂亚洲| 欧美精品一区二区视频 | 在线观看免费视频黄| 欧美日韩中文字幕日韩欧美| 高清日韩av电影| 亚洲精品欧美极品| av成人国产| 极品尤物一区二区| 欧美sm美女调教| 日韩pacopacomama| 在线观看18视频网站| av资源网一区| 在线观看av大片| 欧美激情在线一区| 狠狠做深爱婷婷综合一区| 天堂av2020| 欧美色道久久88综合亚洲精品| av在线电影播放| 国产高清在线一区二区| 麻豆久久精品| 国产性生活网站| 中文字幕日韩综合av| 日韩三级不卡| 黄色片在线免费| 精品久久久久久中文字幕大豆网|