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

帶你100% 地了解 Redis 6.0 的客戶端緩存

存儲 存儲軟件 Redis
近日 Redis 6.0.0 GA 版本發布,這是 Redis 歷史上最大的一次版本更新,包括了客戶端緩存 (Client side caching)、ACL、Threaded I/O 和 Redis Cluster Proxy 等諸多更新。

 近日 Redis 6.0.0 GA 版本發布,這是 Redis 歷史上最大的一次版本更新,包括了客戶端緩存 (Client side caching)、ACL、Threaded I/O 和 Redis Cluster Proxy 等諸多更新。

[[325671]]

我們今天就依次聊一下客戶端緩存的必要性、具體使用、原理分析和實現。

為什么需要客戶端緩存?

我們都知道,使用 Redis 進行數據的緩存的主要目的是減少對 MySQL 等數據庫的訪問,提供更快的訪問速度,畢竟 《Redis in Action》中提到的, Redis 的性能大致是普通關系型數據庫的 10 ~ 100 倍。

所以,如下圖所示,Redis 用來存儲熱點數據,Redis 未命中,再去訪問數據庫,這樣可以應付大多數情況下的性能要求。

 

但是,Redis 也有其性能上限,并且訪問 Redis 必然有一定的網絡 I/O 以及序列化反序列化損耗。所以,往往會引入進程緩存,將最熱的數據存儲在本地,進一步加快訪問速度。

 

如上圖所示(示意圖,細節不必過度在意,下同),Guava Cache 等進程緩存作為一級緩存,Redis 作為二級緩存:

先去 Guava Cache 中查詢數據,如果命中則直接返回。

Guava Cache 中未命中,則再去 Redis 中查詢,如果命中則返回數據,并在 Guava Cache 中設置此數據。

Redis 也未命中的話,只有去 MySQL 中查詢,然后依次將數據設置到 Redis 和 Guava Cache 中。

只使用 Redis 分布式緩存時,遇到數據更新時,應用程序更新完 MySQL 中的數據,可以直接將 Redis 中對應緩存失效掉,保持數據的一致性。

而進程內緩存的數據一致性比分布式的緩存面臨更大的挑戰。數據更新的時候,如何通知其他進程也更新自己的緩存呢?

如果按照分布式緩存的思路,我們可以設置極短的緩存失效時間,這樣不必實現復雜的通知機制。

但是不同進程內的數據依然會面臨不一致的問題,并且不同進程緩存失效時間不統一,同一個請求到了不同的進程,可能出現反復幻讀的情況。

 

Ben 在 RedisConf18 給出了一個方案(視頻和 PPT 鏈接在文末),通過 Redis 的 Pub/Sub,可以通知其他進程緩存對此緩存進行刪除。如果 Redis 掛了或者訂閱機制不靠譜,依靠超時設定,依然可以做兜底處理。

Antirez(Redis 的作者) 也正是聽取 Ben 這個方案后,才決定在 Redis Server 支持客戶端緩存的,因為在有服務端參與的情況下可以更好的處理上述這些問題。

功能介紹和演示

下面使用 Docker 安裝 Redis 6.0.1,然后使用 telnet 來簡單演示一下 Redis 6.0 的客戶端緩存功能。所有相關的功能如下圖所示,分別是使用RESP3 協議版本的普通模式和廣播模式,以及使用 RESP2 協議版本的轉發模式。我們先來看普通模式。

 

普通模式

先使用 redis-cli 設置緩存值 test=111,使用 telnet 連接上 Redis,然后發送 hello 3 開啟 RESP3 協議。

  1. [root@VM_0_3_centos ~]# telnet 127.0.0.1 6379 
  2. Trying 127.0.0.1... 
  3. Connected to 127.0.0.1. 
  4. Escape character is '^]'
  5. hello 3 
  6. // telnet 輸出結果格式化標準化后如下,否則換行太多并且是 RESP3 格式,不需要了解格式。 
  7. > HELLO 3 
  8. 1# "server" => "redis" 
  9. 2# "version" => "6.0.1" 
  10. 3# "proto" => (integer) 3 
  11. 4# "id" => (integer) 10 
  12. 5# "mode" => "standalone" 
  13. 6# "role" => "master" 
  14. 7# "modules" => (empty array) 

這里需要注意,Redis 服務端只會 track 客戶端在一個連接生命周期內的獲取的只讀命令的 key值。Redis 客戶端默認不開啟 track 模式,需要使用命令開啟,然后必須要先獲取一次 test 的值,這樣 Redis 服務器才會記錄它。

  1. client tracking on 
  2. +OK 
  3. get test 
  4. $3 
  5. 111 

當鍵被修改,或者因為失效時間(expire time)和內存上限 maxmemory 策略被驅除時,Redis 服務端會通知這些客戶端。我們這里簡單地更新 test 的值,telnet 則會收到如下通知

  1. >2 // RESP3 中的 PUSH 類型,標志為 > 符號 
  2. $10 
  3. invalidate 
  4. *1 
  5. $4 
  6. test 

如果你再一次更新 test 值,這次 telnet 就不會再收到失效(invalidate)消息。除非 telnet 再進行一次 get 操作,重新 tracking 對應的鍵值。

也就是說 Redis 服務端記錄的客戶端 track 信息只生效一次,發送過失效消息后就會刪除,只有下次客戶端再次執行只讀命令被 track,才會進行下一次消息通知 。

取消 tracking 的命令如下所示。

  1. client tracking off 
  2. +OK 

廣播模式

Redis 還提供了一種廣播模式(BCAST),它是另外一種客戶端緩存的實現方式。這種方式下Redis 服務端不再消耗過多內存存儲信息,而是發送更多的失效消息給客戶端。

這是服務端存儲過多數據,消耗內存和客戶端收到過多消息,消耗網絡帶寬之間的權衡(tradeoff)。

  1. // 已經 hello 3 開啟 RESP3 協議,不然無法收到失效消息,下同 
  2. client tracking on bcast  
  3. +OK 
  4. // 此時設置 key 為 a 的鍵值,收到如下消息。 
  5. >2 
  6. $10 
  7. invalidate 
  8. *1 
  9. $1 

如果你不想所有的鍵值的失效消息都收到,則可以限制 key 的前綴,如下命令則表示只關注前綴為 test 的鍵值的消息。一般來說,業務的緩存 key 都是根據業務擁有統一的前綴,所以這一特性十分方便。

  1. client tracking on bcast prefix test 

與普通模式必須獲取一次鍵的規則不同,廣播模式下,只要鍵被修改或刪除,符合規則的客戶端都會收到失效消息,而且是可以多次獲取的

與普通模式相比,雖然少存儲了一些數據,但是由于需要對前綴規則進行匹配,會消耗一定的 CPU 資源,所以注意別使用過長的前綴。

轉發模式

上述操作時客戶端都需要先開啟 RESP3,Redis 為了兼容 RESP2 協議提供了轉發(Redirect)模式,不再使用 RESP3 原生支持 PUSH 消息,而是將消息通過 Pub/Sub 通知給另外一個客戶端,具體流程如下圖所示。

 

這里需要兩個 telnet,其中一個 telnet 需要訂閱 _redis_:invalidate 信道。然后另一個 telnet 開啟 Redirect 模式,并制定將失效消息通過訂閱信道發送給第一個 telnet。

  1. # telent B 
  2. client id 
  3. :368 
  4. subscribe _redis_:invalidate 
  5. # telnet A,開啟 track 并指定轉發給 B 
  6. client tracking on bcast redirect 368 
  7. # telent B 此時有鍵值被修改,收到 __redis__:invalidate 信道的消息 
  8. message 
  9. $20 
  10. __redis__:invalidate 
  11. *1 
  12. $1 

你會發現,轉發模式和文章開始提到的多級緩存中的更新機制很類似了,只不過那個方案中是業務系統修改完 key 后發送消息通知,而這里是 Redis 服務端代替業務系統發送消息通知。

OPTIN 和 OPTOUT 選項

使用 OPTIN 可以選擇性的開啟 tracking。只有你發送 client caching yes (Redis 文檔中是 CACHING 命令,但是實驗時發現無效)之后的下一條的只讀命令的 key 才會 tracking,否則其他的只讀命令的 key 不會被 tracking。

  1. client tracking on optin 
  2. client caching yes 
  3. get a 
  4. get b 
  5. // 此時修改 a 和 b 的值,發現只收到 a 的失效消息 
  6. >2 
  7. $10 
  8. invalidate 
  9. *1 
  10. $1 

而 OPTOUT 參數與之相反,你可以有選擇的退出 tracking。發送 client caching off 之后的下一條只讀命令的 key 不會被 tracking,其他只讀命令都會被 tracking。

OPTIN 和 OPTOUT 是針對非 BCAST 模式,也就是只有發送了某個 key 的只讀命令后,才會追蹤相應的 key。而 BCAST 模式是無論你是否發送某個 key 的只讀命令,只有 Redis 修改了 key,都會發送相應的 key 的失效消息(前綴匹配的)。

NOLOOP 選項

默認情況下,失效消息會發送給所有需要的 Redis 客戶端,但是有些情況下觸發失效消息也就是更新 key 的客戶端不需要收到該消息。

設置 NOLOOP,可以避免這種情況,更新 Key 的客戶端將不再收到消息,該選項在普通模式和廣播模式下都適用。

最大 tracking 上限 trackingtablemax_keys

由上文可以知道,普通模式下需要存儲大量的被 tracking 的 key 和客戶端信息(具體存儲的數據下文中會講解),所以當 10k 客戶端使用該模式處理百萬個鍵時,會消耗大量的內存空間,所以 Redis 引入了 trackingtablemax_keys 配置,默認為無,不限制。

當有一個新的鍵被 tracking 時,如果當前 tracking 的 key 的數量大于 trackingtablemax_keys,則會隨機刪除之前 tracking 的 key,并且向對應的客戶端發送失效消息。

原理和源碼實現

普通模式原理

我們也先講解普通模式的原理,Redis 服務端使用 TrackingTable 存儲普通模式的客戶端數據,它的數據類型是基數樹(radix tree)。

基數樹是針對稀疏的長整型數據查找的多叉搜索樹,能快速且節省空間的完映射,一般用于解決 Hash沖突和 Hash表大小的設計問題,Linux 的內存管理就使用了它。

 

Redis 用它存儲鍵的指針和客戶端 ID 的映射關系。因為鍵對象的指針就是內存地址,也就是長整型數據。客戶端緩存的相關操作就是對該數據的增刪改查:

  • 當開啟 track 功能的客戶端獲取某一個鍵值時,Redis 會調用 enableTracking 方法使用基數樹記錄下該 key 和 clientId 的映射關系。
  • 當某一個 key 被修改或刪除時,Redis 會調用 trackingInvalidateKey 方法根據 key 從 TrackingTable 中查找所有對應的客戶端ID,然后調用 sendTrackingMessage 方法發送失效消息給這些客戶端(會檢查 CLIENT_TRACKING 相關標志位是否開啟和是否開啟了 NOLOOP)。
  • 發送完失效消息后,根據鍵的指針值將映射關系從 TrackingTable中刪除。
  • 客戶端關閉 track 功能后,因為刪除需要進行大量操作,所以 Redis 使用懶刪除方式,只是將該客戶端的 CLIENT_TRACKING 相關標志位刪除掉。

廣播模式原理

 

廣播模式與普通模式類似,Redis 同樣使用 PrefixTable 存儲廣播模式下的客戶端數據,它存儲前綴字符串指針和(需要通知的key和客戶端ID)的映射關系。它和廣播模式最大的區別就是真正發送失效消息的時機不同:

  • 當客戶端開啟廣播模式時,會在 PrefixTable的前綴對應的客戶端列表中加入該客戶端ID。
  • 當某一個 key 被修改或刪除時,Redis 會調用 trackingInvalidateKey 方法, trackingInvalidateKey 方法中如果發現 PrefixTable 不為空,則調用 trackingRememberKeyToBroadcast 依次遍歷所有前綴,如果key 符合前綴規則,則記錄到 PrefixTable 對應的位置。
  • 在 Redis 的事件處理周期函數 beforeSleep 函數里會調用 trackingBroadcastInvalidationMessages 函數來真正發送消息。

處理最大 tracking 上限

Redis 會在每次執行過命令后(processCommand方法)調用 trackingLimitUsedSlots 來判斷是否需要進行清理:

  • 判斷 TrackingTable 中鍵的數量是否大于 trackingtablemax_keys;
  • 在一定時間段內(不能太長,阻塞主流程),隨機從 TrackingTable 中選出一個鍵刪除,直到數量小于或者時間用完為止。

具體源碼

關于源碼,在 tracking.c 文件下,我們這里只看一下最為關鍵的 trackingInvalidateKey 函數和 sendTrackingMessage 函數,理解了這兩個函數,廣播模式和處理最大 tracking 上限等相關函數都與之類似。

  1. void trackingInvalidateKey(client *c, robj *keyobj) { 
  2. if (TrackingTable == NULLreturn
  3. sds sdskey = keyobj->ptr; 
  4. // 省略,如果廣播模式的記錄基數樹不為空,則先處理廣播模式 
  5. // 1 根據鍵的指針去 TrackingTable 查找 
  6. rax *ids = raxFind(TrackingTable,(unsigned char*)sdskey,sdslen(sdskey)); 
  7. if (ids == raxNotFound) return
  8. // 2 使用迭代器遍歷 
  9. raxIterator ri;raxStart(&ri,ids);raxSeek(&ri,"^",NULL,0); 
  10. while(raxNext(&ri)) { 
  11. // 3 根據 clientId 查找 client 實例 
  12. client *target = lookupClientByID(id); 
  13. // 4 如果未開啟 track 或者是廣播模式則跳過。 
  14. if (target == NULL || 
  15. !(target->flags & CLIENT_TRACKING)|| 
  16. target->flags & CLIENT_TRACKING_BCAST) 
  17. continue; } 
  18. // 5 如果開啟了 NOLOOP 并且是導致key發生變化的client則跳過。 
  19. if (target->flags & CLIENT_TRACKING_NOLOOP && 
  20. target == c) 
  21. continue; } 
  22. // 6 發送失效消息 
  23. sendTrackingMessage(target,sdskey,sdslen(sdskey),0); 
  24. // 7 減少數據統計,根據sdskey刪除對應的記錄 
  25. TrackingTableTotalItems -= raxSize(ids); 
  26. raxFree(ids); 
  27. raxRemove(TrackingTable,(unsigned char*)sdskey,sdslen(sdskey),NULL); 

源碼如上所示,trackingInvalidateKey 方法主要做了 7 件事情:

  • 根據鍵的指針去 TrackingTable 查找客戶端ID列表;
  • 使用迭代器遍歷列表;
  • 根據 clientId 查找 client 實例;
  • 如果 client 實例未開啟 track 或者是廣播模式則跳過;
  • 如果 client 實例開啟了 NOLOOP 并且是導致key發生變化的client則跳過;
  • 調用 sendTrackingMessage 方法發送失效消息;
  • 減少數據統計,根據sdskey刪除對應的記錄

下面來看真正發送消息的 sendTrackingMessage 函數,它主要做了6件事:

  • 如果 clienttrackingredirection 不為空,則開啟了轉發模式;
  • 找到轉發的客戶端實例;
  • 如果轉發客戶端關閉了,則必須通知原客戶端;
  • 如果是客戶端使用 RESP3 則發 PUSH 消息;
  • 如果是轉發模式,往 TrackingChannelName 也就是 _redis_:invalidate 信道中發送失效消息的頭部信息;
  • 發送鍵等信息。
  1. void sendTrackingMessage(client *c, char *keyname, size_t keylen, int proto) { 
  2. int using_redirection = 0; 
  3. // 1 如果 client_tracking_redirection 不為空,則開啟了轉發模式 
  4. if (c->client_tracking_redirection) { 
  5. // 2 找到轉發的客戶端實例 
  6. client *redir = lookupClientByID(c->client_tracking_redirection); 
  7. if (!redir) { 
  8. // 3 如果轉發客戶端關閉了,則必須通知原客戶端 
  9. .... 
  10. return
  11. c = redir; 
  12. using_redirection = 1; 
  13.  
  14.  
  15. if (c->resp > 2) { 
  16. // 4 如果是 RESP3 則發PUSH 
  17. addReplyPushLen(c,2); 
  18. addReplyBulkCBuffer(c,"invalidate",10); 
  19. else if (using_redirection && c->flags & CLIENT_PUBSUB) { 
  20. // 5 轉發模式,往 TrackingChannelName 信道中發送消息 
  21. addReplyPubsubMessage(c,TrackingChannelName,NULL); 
  22. else { 
  23. return
  24. // 6 發送鍵等信息,和上邊4,5操作連在一起的。 
  25. addReplyProto(c,keyname,keylen); 

后記

相信看到這里的小伙伴們都已經有點疲憊了吧,但是還請大家多多點贊多多評論。后續還會學習其他 Redis 6.0.0 的其他亮點功能,請大家繼續關注。

責任編輯:武曉燕 來源: 程序員歷小冰
相關推薦

2020-05-20 14:45:38

緩存MySQL數據庫

2022-05-11 13:56:08

Java項目redis客戶端

2021-09-22 15:46:29

虛擬桌面瘦客戶端胖客戶端

2022-04-28 13:58:41

Redis6客戶端服務端

2015-08-17 09:48:29

C#客戶端分布式緩存

2021-08-01 23:18:21

Redis Golang命令

2011-03-21 14:53:36

Nagios監控Linux

2011-04-06 14:24:20

Nagios監控Linux

2011-11-30 14:21:19

Java分布式緩存

2009-07-10 18:15:24

HTTP頭

2011-08-17 10:10:59

2022-09-23 08:02:42

Kafka消息緩存

2021-06-22 15:06:13

Redis客戶端 Redis-clie

2019-07-05 17:00:33

Redis數據庫可視化管理

2024-01-17 19:05:44

mget優化數據庫

2023-10-12 07:54:02

.NETXamarin框架

2010-05-31 10:11:32

瘦客戶端

2011-10-26 13:17:05

2011-03-24 13:00:31

配置nagios客戶端

2010-12-21 11:03:15

獲取客戶端證書
點贊
收藏

51CTO技術棧公眾號

国产 欧美在线| 91精品电影| 欧美日韩视频在线第一区| 色噜噜色狠狠狠狠狠综合色一| 国产又粗又猛又爽| 黄色在线成人| 在线视频免费一区二区| 性高潮久久久久久| 亚洲第一影院| 夜夜爽夜夜爽精品视频| 欧美日韩精品免费在线观看视频| 国产精品xxxxxx| 黄色一区二区三区四区| 最新69国产成人精品视频免费| 超碰人人cao| 日本肉肉一区 | 亚洲精品国产91| 99综合久久| 91电影在线观看| www.av蜜桃| h片在线播放| 久久亚洲免费视频| 成人av片网址| 91国内精品视频| 久久一区二区三区超碰国产精品| 两个人的视频www国产精品| 黄色a一级视频| 91成人噜噜噜在线播放| 欧美日韩免费视频| 成人在线观看黄| www.超碰在线| 亚洲一区二三区| 国产av第一区| 麻豆av在线免费看| 欧美韩国日本综合| 欧美一区二区三区成人久久片| 后进极品白嫩翘臀在线视频| 国产一区中文字幕| 国产精品无码专区在线观看| 日韩 国产 欧美| 在线一区视频| 隔壁老王国产在线精品| 九九九在线视频| 久久久久久久久久久9不雅视频| 中文字幕亚洲天堂| 成人黄色免费网址| 精品国产精品久久一区免费式 | 国产一级片在线播放| 99久久精品国产毛片| 国产精品一区视频| 黑人精品一区二区三区| av中文一区二区三区| 国产chinese精品一区二区| 国产肥老妇视频| 国产老肥熟一区二区三区| 亚洲wwwav| 99久久国产免费| 国产v综合v亚洲欧| 国产精品久久久久久久久久久久午夜片| 国产高清在线观看视频| 国产在线麻豆精品观看| 91色在线观看| 亚洲男人第一天堂| 99re亚洲国产精品| 日本高清不卡三区| 午夜在线小视频| 日韩码欧中文字| www.18av.com| 黄色软件视频在线观看| 日本精品一区二区三区高清 | 亚洲剧情一区二区| 色欲狠狠躁天天躁无码中文字幕| 北条麻妃国产九九九精品小说| 神马久久久久久| 强乱中文字幕av一区乱码| 激情欧美日韩一区| 91av在线网站| 中文字幕av片| 国产成人免费视频网站| 精品一区久久久| 国产精品免费播放| 亚洲激情校园春色| 国产超级av在线| 国产精品伦一区二区| 日韩欧美一二三四区| 中出视频在线观看| 久久精品国产亚洲夜色av网站| 欧美精品亚州精品| 91av在线免费视频| 美国毛片一区二区三区| 国产精品一区二区三区四区五区| 国产中文字幕在线看| 亚洲丝袜制服诱惑| 国产亚洲欧美在线视频| 图片一区二区| 精品视频偷偷看在线观看| 男人av资源站| 亚洲一区二区三区免费在线观看| 成人在线一区二区| 性高潮久久久久久久久久| 成人免费在线视频| 欧美韩国日本在线| 在线视频亚洲欧美中文| 伊人伊成久久人综合网小说| 久久免费在线观看视频| 免费的国产精品| 久久久久久九九| 视频在线观看入口黄最新永久免费国产 | 高清久久一区| 亚洲欧美福利视频| 久久精品www人人爽人人| 人人精品人人爱| 精品国产一区二区三区麻豆小说 | 久久精品国产亚洲一区二区三区| 国产女主播一区二区| 黄色小网站在线观看| 色婷婷av一区二区三区大白胸| 9191在线视频| 婷婷激情图片久久| 国产成人精品久久亚洲高清不卡| 欧美一区二区公司| 亚洲人成精品久久久久| 最新中文字幕2018| 国产日产精品一区二区三区四区的观看方式 | 最近2019中文免费高清视频观看www99| 国产一级在线播放| 国产在线麻豆精品观看| 一区二区三区四区五区精品 | 肉色超薄丝袜脚交69xx图片| 麻豆91精品| 久久久精品国产一区二区三区| 国产美女情趣调教h一区二区| 91精品欧美久久久久久动漫| 亚洲天堂av中文字幕| 久久国产精品久久久久久电车| 国产精品区一区二区三含羞草| а√天堂8资源在线官网| 欧美性大战久久久久久久蜜臀| 国产精品亚洲无码| 免费在线播放第一区高清av| 精品乱码一区| 在线天堂新版最新版在线8| 亚洲国产精品资源| 日本一级黄色录像| 99视频国产精品| 9久久9毛片又大又硬又粗| 精品精品国产毛片在线看| 国内成人精品一区| 污视频网站免费观看| 欧美日韩午夜剧场| 免费看污黄网站在线观看| 欧美亚洲一区二区三区| 欧美一区1区三区3区公司| 欧美第一视频| 在线观看中文字幕亚洲| 在线观看中文字幕av| ...av二区三区久久精品| а 天堂 在线| 一区在线免费| 九九99久久| 性欧美超级视频| 最新日韩中文字幕| 99热这里只有精品9| 亚洲一区二区三区在线| 国产精品无码网站| 蜜桃久久精品一区二区| 糖心vlog在线免费观看| 激情小说一区| 国产成人涩涩涩视频在线观看 | 婷婷激情综合五月天| 欧美/亚洲一区| 精品高清视频| 国产成人免费精品| 伦理中文字幕亚洲| 天天操天天干天天| 欧美在线观看视频一区二区| 国产高潮流白浆| av中文字幕在线不卡| 日韩欧美黄色大片| 中文字幕一区二区精品区| 国产一区免费视频| 国产一区二区三区朝在线观看| 色七七影院综合| 欧美一级淫片aaaaaa| 欧美视频一区二区在线观看| 欧美黑吊大战白妞| 久久久久久久一区| 男人操女人下面视频| 亚洲欧美日韩国产综合精品二区 | 麻豆传媒在线观看| 亚洲高清一区二| 亚洲手机在线观看| 性做久久久久久免费观看| 蜜桃av乱码一区二区三区| 国产激情一区二区三区| 免费日韩视频在线观看| 午夜国产欧美理论在线播放| 久久精品女人的天堂av| www.成人在线.com| 日本高清视频精品| 国产盗摄精品一区二区酒店| 色yeye香蕉凹凸一区二区av| 凸凹人妻人人澡人人添| 91精品在线免费| 亚洲欧美日韩激情| 香蕉加勒比综合久久| 国产一区第一页| 久久久久88色偷偷免费| 大尺度做爰床戏呻吟舒畅| 激情五月婷婷综合| 亚洲精品中文字幕无码蜜桃| 精久久久久久| 日本xxx免费| 精品午夜久久| 狼狼综合久久久久综合网| 激情久久免费视频| 国产精品综合不卡av| 中文字幕这里只有精品| 欧美老肥婆性猛交视频| 男人资源在线播放| 亚洲日本成人网| 三级黄视频在线观看| 欧美tk丨vk视频| 国产三级自拍视频| 欧美日韩国产综合草草| www.五月婷婷.com| 色综合 综合色| 国产精品人人人人| 性做久久久久久久久| 久久亚洲国产成人精品性色| 亚洲特黄一级片| 欧美爱爱免费视频| 中文字幕的久久| 中字幕一区二区三区乱码| 久久综合久久鬼色中文字| 日本一区二区三区网站| 成av人片一区二区| 中文字幕乱视频| 成人性生交大片免费看中文网站| 手机在线观看日韩av| 国产精品正在播放| 亚洲熟女乱综合一区二区| 国产伦精品一区二区三区免费迷| 亚洲午夜精品一区| 久久国内精品视频| 国内自拍第二页| 国产麻豆成人精品| 麻豆tv在线观看| 成人中文字幕在线| 久久久久亚洲AV成人无码国产| 不卡电影一区二区三区| 精品无码在线视频| 久久久三级国产网站| 亚洲一级片在线播放| 国产精品素人一区二区| 国产又粗又硬又长又爽| 一区二区三区在线观看动漫 | 色婷婷久久久久swag精品| 69国产精品视频免费观看| 色婷婷精品大视频在线蜜桃视频| 亚洲成熟少妇视频在线观看| 欧洲亚洲精品在线| 91精品国自产| 精品国产免费一区二区三区四区| 日韩中文字幕观看| 亚洲午夜av久久乱码| 尤物视频在线免费观看| 另类图片亚洲另类| 少妇淫片在线影院| 国产精品久久久久av| 外国成人毛片| 精品国产一区二区三区日日嗨 | 中文字幕久久精品一区二区 | 欧美午夜视频一区二区| 无码人妻av免费一区二区三区| 欧美三级乱人伦电影| 精品久久无码中文字幕| 精品亚洲国产成av人片传媒| 91在线网址| 欧美精品成人91久久久久久久| 在线天堂新版最新版在线8| 国产精品一二三在线| 亚洲国产中文在线| 欧洲精品久久| 欧美日韩第一区| 久久久久国产精品熟女影院| 国产精品18久久久久久vr| 亚欧洲乱码视频| 亚洲一区二区三区精品在线| 少妇一级淫片日本| 欧美精品一区二区三区高清aⅴ | 丰满少妇在线观看bd| 亚洲人精品午夜在线观看| 欧洲性视频在线播放| 国产成人综合一区二区三区| 91午夜精品| 亚洲视频欧美在线| 午夜综合激情| 好吊操视频这里只有精品| 中文字幕不卡一区| 日本少妇性高潮| 制服丝袜成人动漫| 精品一二三区视频| 欧美激情精品久久久久| 欧美一区=区三区| 欧美国产二区| 黄色一区二区三区四区| 亚洲天堂伊人网| 国产日产精品1区| 日本一区二区三区四区五区| 正在播放一区二区| youjizz在线播放| 欧美最猛性xxxxx亚洲精品| 亚洲国产中文在线二区三区免| 在线观看成人av电影| 丝袜诱惑亚洲看片 | 最新中文字幕一区二区三区| 五月激情六月丁香| 亚洲成人精品视频在线观看| 国产美女福利在线| 国产乱人伦真实精品视频| 一道本一区二区三区 | 麻豆专区一区二区三区四区五区| 国产乱了高清露脸对白| 亚洲成人综合在线| www香蕉视频| 欧美大码xxxx| 蜜桃精品一区二区三区| 伊人色综合久久天天五月婷| 日韩精品午夜视频| 自拍偷拍亚洲天堂| 色综合欧美在线| 日中文字幕在线| 78色国产精品| 日韩欧美在线精品| 国产一区二区网| 久久综合九色综合97婷婷| 国产在线观看免费av| 日韩精品一区二区三区四区| 亚洲小说区图片| 国产精品对白刺激久久久| 欧美日本不卡高清| 久久久久亚洲AV成人网人人小说| 亚洲综合激情另类小说区| 午夜精品久久久久久久99| 欧美另类交人妖| www.丝袜精品| av黄色在线网站| 久久蜜臀精品av| 九九热最新视频| 日韩亚洲精品视频| 中文幕av一区二区三区佐山爱| 懂色av粉嫩av蜜臀av| 国产精品一区二区无线| 久久久无码一区二区三区| 亚洲第一精品福利| 午夜影院在线观看国产主播| 欧洲精品在线一区| 美洲天堂一区二卡三卡四卡视频| 精品少妇一区二区三区密爱| 日韩欧美一区二区不卡| 成人三级小说| 欧美日韩国产免费一区二区三区 | 亚洲国产三级| a级大片在线观看| 欧美精品色综合| 青春草免费在线视频| 精品久久久久久中文字幕动漫| 玖玖玖国产精品| 精品国产大片大片大片| 日韩你懂的在线播放| 韩国成人二区| 一区二区免费在线观看| 成人午夜电影久久影院| 成人av网站在线播放| www.久久色.com| 九九热播视频在线精品6| 九色91popny| 亚洲精品福利视频网站| 手机亚洲第一页| 成人激情视频免费在线| 亚洲三级观看| 欧美巨胸大乳hitomi| 日韩精品一区二区三区视频播放| 亚洲欧美小说色综合小说一区| 一区二区不卡视频| 成人黄色网址在线观看| 超碰在线免费97| 久久99精品久久久久久青青91 | 亚洲日本va| 国产视频一区二区三区在线播放 | 欧美一级视频免费看| 国产欧美精品在线观看| 性欧美videos另类hd| 国产mv久久久| 欧美破处大片在线视频| 欧美a在线播放| 亚洲精品久久久久久下一站| 亚洲精品第一| 乱子伦视频在线看|