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

為什么Redis單線程能支撐高并發?

數據庫 其他數據庫 Redis
最近在看 UNIX 網絡編程并研究了一下 Redis 的實現,感覺 Redis 的源代碼十分適合閱讀和分析,其中 I/O 多路復用(mutiplexing)部分的實現非常干凈和優雅,在這里想對這部分的內容進行簡單的整理。

 [[349540]]

 

最近在看 UNIX 網絡編程并研究了一下 Redis 的實現,感覺 Redis 的源代碼十分適合閱讀和分析,其中 I/O 多路復用(mutiplexing)部分的實現非常干凈和優雅,在這里想對這部分的內容進行簡單的整理。

幾種 I/O 模型

為什么 Redis 中要使用 I/O 多路復用這種技術呢?

首先,Redis 是跑在單線程中的,所有的操作都是按照順序線性執行的,但是由于讀寫操作等待用戶輸入或輸出都是阻塞的,所以 I/O 操作在一般情況下往往不能直接返回,這會導致某一文件的 I/O 阻塞導致整個進程無法對其它客戶提供服務,而 I/O 多路復用就是為了解決這個問題而出現的。

Blocking I/O

先來看一下傳統的阻塞 I/O 模型到底是如何工作的:當使用 read 或者 write 對某一個**文件描述符(File Descriptor 以下簡稱 FD)**進行讀寫時,如果當前 FD 不可讀或不可寫,整個 Redis 服務就不會對其它的操作作出響應,導致整個服務不可用。

這也就是傳統意義上的,也就是我們在編程中使用最多的阻塞模型:

blocking-io

阻塞模型雖然開發中非常常見也非常易于理解,但是由于它會影響其他 FD 對應的服務,所以在需要處理多個客戶端任務的時候,往往都不會使用阻塞模型。

I/O 多路復用

雖然還有很多其它的 I/O 模型,但是在這里都不會具體介紹。

阻塞式的 I/O 模型并不能滿足這里的需求,我們需要一種效率更高的 I/O 模型來支撐 Redis 的多個客戶(redis-cli),這里涉及的就是 I/O 多路復用模型了:

I:O-Multiplexing-Mode

在 I/O 多路復用模型中,最重要的函數調用就是 select,該方法的能夠同時監控多個文件描述符的可讀可寫情況,當其中的某些文件描述符可讀或者可寫時,select 方法就會返回可讀以及可寫的文件描述符個數。

關于 select 的具體使用方法,在網絡上資料很多,這里就不過多展開介紹了;

與此同時也有其它的 I/O 多路復用函數 epoll/kqueue/evport,它們相比 select 性能更優秀,同時也能支撐更多的服務。

Reactor 設計模式

Redis 服務采用 Reactor 的方式來實現文件事件處理器(每一個網絡連接其實都對應一個文件描述符)

redis-reactor-pattern

文件事件處理器使用 I/O 多路復用模塊同時監聽多個 FD,當 acceptreadwriteclose 文件事件產生時,文件事件處理器就會回調 FD 綁定的事件處理器。

雖然整個文件事件處理器是在單線程上運行的,但是通過 I/O 多路復用模塊的引入,實現了同時對多個 FD 讀寫的監控,提高了網絡通信模型的性能,同時也可以保證整個 Redis 服務實現的簡單。

I/O 多路復用模塊

I/O 多路復用模塊封裝了底層的 selectepollavport 以及 kqueue 這些 I/O 多路復用函數,為上層提供了相同的接口。

ae-module

在這里我們簡單介紹 Redis 是如何包裝 selectepoll 的,簡要了解該模塊的功能,整個 I/O 多路復用模塊抹平了不同平臺上 I/O 多路復用函數的差異性,提供了相同的接口:

  • static int aeApiCreate(aeEventLoop *eventLoop)
  • static int aeApiResize(aeEventLoop *eventLoop, int setsize)
  • static void aeApiFree(aeEventLoop *eventLoop)
  • static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)
  • static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask)
  • static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)

同時,因為各個函數所需要的參數不同,我們在每一個子模塊內部通過一個 aeApiState 來存儲需要的上下文信息:

  1. // select 
  2. typedef struct aeApiState { 
  3.     fd_set rfds, wfds; 
  4.     fd_set _rfds, _wfds; 
  5. } aeApiState; 
  6.  
  7. // epoll 
  8. typedef struct aeApiState { 
  9.     int epfd; 
  10.     struct epoll_event *events; 
  11. } aeApiState; 

這些上下文信息會存儲在 eventLoopvoid *state 中,不會暴露到上層,只在當前模塊中使用。

封裝 select 函數

select 可以監控 FD 的可讀、可寫以及出現錯誤的情況。

在介紹 I/O 多路復用模塊如何對 select 函數封裝之前,先來看一下 select 函數使用的大致流程:

  1. int fd = /* file descriptor */ 
  2.  
  3. fd_set rfds; 
  4. FD_ZERO(&rfds); 
  5. FD_SET(fd, &rfds) 
  6.  
  7. for ( ; ; ) { 
  8.     select(fd+1, &rfds, NULLNULLNULL); 
  9.     if (FD_ISSET(fd, &rfds)) { 
  10.         /* file descriptor `fd` becomes readable */ 
  11.     } 
  1. 初始化一個可讀的 fd_set 集合,保存需要監控可讀性的 FD;
  2. 使用 FD_SETfd 加入 rfds
  3. 調用 select 方法監控 rfds 中的 FD 是否可讀;
  4. select 返回時,檢查 FD 的狀態并完成對應的操作。

而在 Redis 的 ae_select 文件中代碼的組織順序也是差不多的,首先在 aeApiCreate 函數中初始化 rfdswfds

  1. static int aeApiCreate(aeEventLoop *eventLoop) { 
  2.     aeApiState *state = zmalloc(sizeof(aeApiState)); 
  3.     if (!state) return -1; 
  4.     FD_ZERO(&state->rfds); 
  5.     FD_ZERO(&state->wfds); 
  6.     eventLoop->apidata = state; 
  7.     return 0; 

aeApiAddEventaeApiDelEvent 會通過 FD_SETFD_CLR 修改 fd_set 中對應 FD 的標志位:

  1. static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { 
  2.     aeApiState *state = eventLoop->apidata; 
  3.     if (mask & AE_READABLE) FD_SET(fd,&state->rfds); 
  4.     if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds); 
  5.     return 0; 

整個 ae_select 子模塊中最重要的函數就是 aeApiPoll,它是實際調用 select 函數的部分,其作用就是在 I/O 多路復用函數返回時,將對應的 FD 加入 aeEventLoopfired 數組中,并返回事件的個數:

  1. static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { 
  2.     aeApiState *state = eventLoop->apidata; 
  3.     int retval, j, numevents = 0; 
  4.  
  5.     memcpy(&state->_rfds,&state->rfds,sizeof(fd_set)); 
  6.     memcpy(&state->_wfds,&state->wfds,sizeof(fd_set)); 
  7.  
  8.     retval = select(eventLoop->maxfd+1, 
  9.                 &state->_rfds,&state->_wfds,NULL,tvp); 
  10.     if (retval > 0) { 
  11.         for (j = 0; j <= eventLoop->maxfd; j++) { 
  12.             int mask = 0; 
  13.             aeFileEvent *fe = &eventLoop->events[j]; 
  14.  
  15.             if (fe->mask == AE_NONE) continue
  16.             if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds)) 
  17.                 mask |= AE_READABLE; 
  18.             if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds)) 
  19.                 mask |= AE_WRITABLE; 
  20.             eventLoop->fired[numevents].fd = j; 
  21.             eventLoop->fired[numevents].mask = mask; 
  22.             numevents++; 
  23.         } 
  24.     } 
  25.     return numevents; 

封裝 epoll 函數

Redis 對 epoll 的封裝其實也是類似的,使用 epoll_create 創建 epoll 中使用的 epfd

  1. static int aeApiCreate(aeEventLoop *eventLoop) { 
  2.     aeApiState *state = zmalloc(sizeof(aeApiState)); 
  3.  
  4.     if (!state) return -1; 
  5.     state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize); 
  6.     if (!state->events) { 
  7.         zfree(state); 
  8.         return -1; 
  9.     } 
  10.     state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */ 
  11.     if (state->epfd == -1) { 
  12.         zfree(state->events); 
  13.         zfree(state); 
  14.         return -1; 
  15.     } 
  16.     eventLoop->apidata = state; 
  17.     return 0; 

aeApiAddEvent 中使用 epoll_ctlepfd 中添加需要監控的 FD 以及監聽的事件:

  1. static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { 
  2.     aeApiState *state = eventLoop->apidata; 
  3.     struct epoll_event ee = {0}; /* avoid valgrind warning */ 
  4.     /* If the fd was already monitored for some event, we need a MOD 
  5.      * operation. Otherwise we need an ADD operation. */ 
  6.     int op = eventLoop->events[fd].mask == AE_NONE ? 
  7.             EPOLL_CTL_ADD : EPOLL_CTL_MOD; 
  8.  
  9.     ee.events = 0; 
  10.     mask |= eventLoop->events[fd].mask; /* Merge old events */ 
  11.     if (mask & AE_READABLE) ee.events |= EPOLLIN; 
  12.     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; 
  13.     ee.data.fd = fd; 
  14.     if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1; 
  15.     return 0; 

由于 epoll 相比 select 機制略有不同,在 epoll_wait 函數返回時并不需要遍歷所有的 FD 查看讀寫情況;在 epoll_wait 函數返回時會提供一個 epoll_event 數組:

  1. typedef union epoll_data { 
  2.     void    *ptr; 
  3.     int      fd; /* 文件描述符 */ 
  4.     uint32_t u32; 
  5.     uint64_t u64; 
  6. } epoll_data_t; 
  7.  
  8. struct epoll_event { 
  9.     uint32_t     events; /* Epoll 事件 */ 
  10.     epoll_data_t data; 
  11. }; 

其中保存了發生的 epoll 事件(EPOLLINEPOLLOUTEPOLLERREPOLLHUP)以及發生該事件的 FD。

aeApiPoll 函數只需要將 epoll_event 數組中存儲的信息加入 eventLoopfired 數組中,將信息傳遞給上層模塊:

  1. static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { 
  2.     aeApiState *state = eventLoop->apidata; 
  3.     int retval, numevents = 0; 
  4.  
  5.     retval = epoll_wait(state->epfd,state->events,eventLoop->setsize, 
  6.             tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1); 
  7.     if (retval > 0) { 
  8.         int j; 
  9.  
  10.         numevents = retval; 
  11.         for (j = 0; j < numevents; j++) { 
  12.             int mask = 0; 
  13.             struct epoll_event *e = state->events+j; 
  14.  
  15.             if (e->events & EPOLLIN) mask |= AE_READABLE; 
  16.             if (e->events & EPOLLOUT) mask |= AE_WRITABLE; 
  17.             if (e->events & EPOLLERR) mask |= AE_WRITABLE; 
  18.             if (e->events & EPOLLHUP) mask |= AE_WRITABLE; 
  19.             eventLoop->fired[j].fd = e->data.fd; 
  20.             eventLoop->fired[j].mask = mask; 
  21.         } 
  22.     } 
  23.     return numevents; 

子模塊的選擇

因為 Redis 需要在多個平臺上運行,同時為了最大化執行的效率與性能,所以會根據編譯平臺的不同選擇不同的 I/O 多路復用函數作為子模塊,提供給上層統一的接口;在 Redis 中,我們通過宏定義的使用,合理的選擇不同的子模塊:

  1. #ifdef HAVE_EVPORT 
  2. #include "ae_evport.c" 
  3. #else 
  4.     #ifdef HAVE_EPOLL 
  5.     #include "ae_epoll.c" 
  6.     #else 
  7.         #ifdef HAVE_KQUEUE 
  8.         #include "ae_kqueue.c" 
  9.         #else 
  10.         #include "ae_select.c" 
  11.         #endif 
  12.     #endif 
  13. #endif 

因為 select 函數是作為 POSIX 標準中的系統調用,在不同版本的操作系統上都會實現,所以將其作為保底方案:

redis-choose-io-function

Redis 會優先選擇時間復雜度為 的 I/O 多路復用函數作為底層實現,包括 Solaries 10 中的 evport、Linux 中的 epoll 和 macOS/FreeBSD 中的 kqueue,上述的這些函數都使用了內核內部的結構,并且能夠服務幾十萬的文件描述符。

但是如果當前編譯環境沒有上述函數,就會選擇 select 作為備選方案,由于其在使用時會掃描全部監聽的描述符,所以其時間復雜度較差 ,并且只能同時服務 1024 個文件描述符,所以一般并不會以 select 作為第一方案使用。

總結

Redis 對于 I/O 多路復用模塊的設計非常簡潔,通過宏保證了 I/O 多路復用模塊在不同平臺上都有著優異的性能,將不同的 I/O 多路復用函數封裝成相同的 API 提供給上層使用。

整個模塊使 Redis 能以單進程運行的同時服務成千上萬個文件描述符,避免了由于多進程應用的引入導致代碼實現復雜度的提升,減少了出錯的可能性。 

 

 

 

 

 

責任編輯:龐桂玉 來源: 今日頭條
相關推薦

2019-05-07 09:44:45

Redis高并發模型

2019-05-06 11:12:18

Redis高并發單線程

2023-10-15 12:23:10

單線程Redis

2020-06-11 09:35:39

Redis單線程Java

2021-12-28 09:50:18

Redis單線程高并發

2023-03-21 08:02:36

Redis6.0IO多線程

2019-06-17 14:20:51

Redis數據庫Java

2019-04-02 11:20:48

Redis高并發單線程

2021-03-03 08:01:58

Redis多線程程序

2025-01-17 08:23:33

2023-08-17 14:12:17

2019-11-25 10:13:52

Redis單線程I

2021-08-10 07:00:01

Redis單線程并發

2020-11-17 10:20:53

Redis多線程單線程

2025-06-17 00:22:00

2019-02-18 08:10:53

2025-09-18 08:16:28

JavaScrip單線程Linux

2022-01-04 11:11:32

Redis單線程Reactor

2020-10-16 16:00:50

Redis單線程數據庫

2025-04-24 08:15:00

Redis單線程線程
點贊
收藏

51CTO技術棧公眾號

香蕉成人伊视频在线观看| 久久中文在线| 精品日韩99亚洲| 青青青国产在线观看| chinese偷拍一区二区三区| 久草在线在线精品观看| 97视频在线看| www.av免费| 国产精品亚洲人成在99www| 欧美乱熟臀69xxxxxx| 国产在线视频综合| 成年午夜在线| av亚洲产国偷v产偷v自拍| 国产精品久久二区| 日韩三级视频在线| 亚洲91久久| 亚洲男人第一网站| 少妇高潮一69aⅹ| jizz欧美| 欧美性xxxxhd| 日本五级黄色片| 日本在线免费播放| 国产日韩欧美麻豆| 国产精品美女诱惑| 国产人妻精品一区二区三区| 久久亚洲美女| 欧美一级片在线播放| 欧美又粗又大又长| 天天综合久久| 中文字幕欧美国内| 免费看污片网站| 国产精品任我爽爆在线播放| 91精品久久久久久久99蜜桃| 欧美伦理视频在线观看| 国产乱码精品一区二三赶尸艳谈| 国产精品免费丝袜| 欧美精品一区三区在线观看| 日韩一卡二卡在线| 成人综合婷婷国产精品久久蜜臀| 成人a级免费视频| 制服丝袜在线一区| 日精品一区二区三区| 欧洲成人午夜免费大片| 国产无遮挡又黄又爽| 欧美精品网站| 免费99精品国产自在在线| www.99re6| 天天射综合网视频| 久久精品免费播放| 亚洲欧美精品久久| 亚洲激情五月| 欧美日韩国产va另类| 黄页网站免费观看| 欧美日韩三级电影在线| 九九精品视频在线| 国产精品成人久久| 亚洲毛片视频| 欧美专区中文字幕| 久久久精品视频网站| 丝袜美腿亚洲综合| 国产精品久久久久久久久借妻| 国产亚洲欧美日韩高清| 日av在线不卡| 成人黄色中文字幕| 国产麻豆一精品一男同| 国产精品99久久久久久有的能看| 99久热re在线精品视频| 丰满人妻一区二区三区免费视频| www.亚洲色图.com| 精品国产一区二区三区日日嗨| 四虎电影院在线观看| 久久亚洲影视婷婷| 日韩色妇久久av| 乱人伦中文视频在线| 亚洲免费观看高清完整版在线观看 | 老熟妇仑乱一区二区av| 肉色丝袜一区二区| 成人亚洲综合色就1024| 男人天堂一区二区| 久久久久国产成人精品亚洲午夜| 亚洲电影免费| 欧美性video| 岛国av一区二区在线在线观看| 日韩av资源在线| 精品国产黄a∨片高清在线| 欧美精品v日韩精品v韩国精品v| 免费高清视频在线观看| 日韩美女国产精品| 日韩中文字幕欧美| 久久久久国产精品夜夜夜夜夜| 一区二区毛片| 国产精品久久久久久久美男 | 日韩欧美一区二区三区在线观看| 在线观看欧美黄色| 在线成人精品视频| 欧美日韩国产免费观看视频| 色偷偷av一区二区三区| 精品少妇久久久| 日本亚洲最大的色成网站www| 91亚洲国产成人久久精品网站| 免费av网站观看| 中文字幕av资源一区| 日本丰满少妇xxxx| 久久亚洲精品中文字幕| 亚洲国产精品va在看黑人| 国产毛片久久久久久久| 欧美另类女人| 国产精品香蕉国产| 亚洲区小说区图片区| 亚洲人亚洲人成电影网站色| 91av在线免费播放| 视频在线亚洲| 日韩在线欧美在线| 天堂а√在线中文在线新版 | 亚洲已满18点击进入在线看片| 视频在线观看你懂的| 亚洲欧美日韩在线| www.色就是色| 色婷婷综合久久久久久| 欧美人在线视频| 亚洲熟妇av乱码在线观看| 99久久综合狠狠综合久久| 国产盗摄视频在线观看| 91久久久久久白丝白浆欲热蜜臀| 亚洲国内高清视频| 豆国产97在线 | 亚洲| 国产在线播放一区二区三区| 色一情一乱一伦一区二区三欧美| 欧美调教sm| 精品久久国产97色综合| 538任你躁在线精品视频网站| 日韩不卡一二三区| 精品国产综合久久| av资源中文在线| 日韩欧美精品在线视频| 老熟妇高潮一区二区三区| 美女脱光内衣内裤视频久久网站| 欧美中日韩免费视频| 在线播放高清视频www| 亚洲成色777777在线观看影院| 欧美黑吊大战白妞| 国产一区二区导航在线播放| 在线看无码的免费网站| 国产一区高清| 中文字幕日韩专区| 国产精品露脸视频| 国产精品污污网站在线观看| 奇米影视四色在线| 久久激情电影| 国产精品美女久久| 日本中文在线观看| 91精品婷婷国产综合久久竹菊| 在线观看美女av| 国产一区999| 精品人妻人人做人人爽| jizzjizzjizz欧美| 97人人模人人爽人人喊中文字| 天堂网在线播放| 欧美色videos| 影音先锋男人在线| 美腿丝袜在线亚洲一区| 99热都是精品| 精品亚洲自拍| 清纯唯美日韩制服另类| 成年人在线视频免费观看| 欧美电影影音先锋| 在线观看成人毛片| 成人听书哪个软件好| 免费黄色日本网站| 欧美中文一区二区| 91美女片黄在线观看游戏| 天天色天天射天天综合网| 亚洲成人av片在线观看| 91porny在线| 国产精品黄色在线观看| 污免费在线观看| 一区二区三区四区五区精品视频| 免费99视频| 成人av在线播放| 久久久久国产精品免费| 你懂的在线观看| 91麻豆精品国产91久久久久久久久 | 国产精品成人一区二区| 黄色免费在线网站| 日韩高清人体午夜| 一级片一区二区三区| 亚洲香蕉伊在人在线观| 欧美偷拍一区二区三区| 国产一区二区三区av电影| 国产成人黄色片| 天天综合网91| 久久久99爱| 99综合久久| 琪琪亚洲精品午夜在线| 国产精品va在线观看视色| 亚洲精品久久久久久久久| 中文字幕一区二区三区四区免费看 | 国产精品第一国产精品| 久久久久久午夜| 国产高清视频免费最新在线| 精品国精品自拍自在线| 中文字幕激情视频| 亚洲成人动漫在线观看| 日韩av网站在线播放| 99精品视频中文字幕| 日本美女视频一区| 久久亚洲精选| 免费看黄在线看| 亚洲国产一成人久久精品| 日本视频一区二区不卡| 中文在线综合| 国产一区香蕉久久| 伊人久久在线| 久久久这里只有精品视频| 日本免费在线视频| 国产一区二区三区网站| 黄频网站在线观看| 欧美一三区三区四区免费在线看| 免费无码国产精品| 婷婷丁香久久五月婷婷| 国产suv一区二区三区| 中文字幕第一区综合| 人妻无码一区二区三区| 福利一区二区在线| xxx中文字幕| 国产一区二区三区在线观看免费视频| 国产xxxxx在线观看| 亚洲乱码视频| 欧美成人高潮一二区在线看| 欧美激情aⅴ一区二区三区| 亚洲精品视频一二三| 国产一区二区三区探花| 欧美理论一区二区| 奇米影视777在线欧美电影观看| 懂色av一区二区三区在线播放| 一区在线不卡| 国产一区红桃视频| 四虎在线精品| 国产日韩在线观看av| 亚洲精品一区三区三区在线观看| 人妖精品videosex性欧美| 一区二区三区四区日本视频| 91成人福利在线| 松下纱荣子在线观看| 4388成人网| 97久久香蕉国产线看观看| 国产999精品久久久| sis001欧美| 国产精品吹潮在线观看| 四虎成人在线| 国产精品一区二区久久国产| 成人精品高清在线视频| 国产原创欧美精品| 欧美黄视频在线观看| 91传媒视频在线观看| 中文字幕一区图| 国产久一道中文一区| 欧美一级一片| 欧美在线视频一区二区三区| 日韩国产一区| av电影一区二区三区| 欧美日韩亚洲一区三区| 国产96在线 | 亚洲| 久久精品人人| 亚洲综合欧美在线| 国产美女娇喘av呻吟久久| 黑人巨大猛交丰满少妇| 成人va在线观看| 37p粉嫩大胆色噜噜噜| 国产日韩成人精品| 亚洲不卡在线播放| 亚洲国产人成综合网站| 久久99精品波多结衣一区| 在线观看av不卡| 99久久免费国产精精品| 精品国产在天天线2019| 你懂的好爽在线观看| 最近2019年好看中文字幕视频| 9191在线播放| 69精品小视频| 亚洲精品成人一区| 国产伦视频一区二区三区| 禁果av一区二区三区| 中文字幕久久一区| 亚洲美女少妇无套啪啪呻吟| 亚洲视频在线观看一区二区三区| 极品少妇xxxx精品少妇偷拍 | 国产日韩三级| 午夜一区二区三区| 欧美日韩理论| 九九热免费精品视频| 岛国av在线一区| 亚洲黄色网址大全| 偷窥少妇高潮呻吟av久久免费| 中文av免费观看| 亚洲成人网在线| 日本在线看片免费人成视1000| 性色av一区二区咪爱| 婷婷激情成人| 免费在线国产精品| 国产精品啊v在线| 天天爽天天爽夜夜爽| 成人精品gif动图一区| 妖精视频在线观看免费| 精品久久久国产| 国内精品国产成人国产三级| 亚洲视频日韩精品| av第一福利在线导航| 91精品视频观看| 精品产国自在拍| 欧美日本视频在线观看| 国产一区二区三区在线观看精品| 国产男女猛烈无遮挡a片漫画| 亚洲精品成人悠悠色影视| 中文字幕天堂在线| 亚洲激情视频在线播放| 污污片在线免费视频| 成人精品一区二区三区电影黑人| 亚洲亚洲免费| 妞干网在线观看视频| 国产精品亚洲一区二区三区在线| 91激情视频在线观看| 天天综合日日夜夜精品| 亚洲av无码一区二区三区性色| 久久精品人人做人人爽| 日韩色淫视频| 欧美日韩一区二区视频在线观看| 亚洲无吗在线| 日本一级大毛片a一| 樱花草国产18久久久久| 国产一区二区在线视频聊天| 国产亚洲一级高清| 四虎4545www精品视频| 美女被啪啪一区二区| 99精品视频免费| 三级男人添奶爽爽爽视频| 亚洲国产三级在线| 日韩一区免费视频| 欧美精品久久久久久久| 一本一道久久a久久| 日本高清视频免费在线观看| 国产伦精品一区二区三区免费 | 成人a在线视频| 欧美电影一二区| 中文字幕12页| 亚洲三级在线观看| 99久久精品免费看国产交换| 久久影视免费观看| 九九九九九九精品任你躁| 亚洲精品国产suv一区88| 国产成人啪免费观看软件| 欧美精品99久久久| 精品国产一区二区三区久久影院 | 91玉足脚交白嫩脚丫| 香蕉av福利精品导航 | 北条麻妃一区二区三区中文字幕| 成人在线视频观看| 亚洲最新免费视频| 国产一区二区三区蝌蚪| 麻豆亚洲av熟女国产一区二| 精品国产电影一区二区| 日本不卡网站| 色综合影院在线观看| 国产尤物一区二区| 精品一区二区三区人妻| 日韩精品免费观看| 韩国精品主播一区二区在线观看 | 日韩精品一二三区| 国产午夜精品福利视频| 91精品国产综合久久久久久漫画| 在线观看男女av免费网址| 国产高清一区视频| 久久精品一区| 色偷偷www8888| 精品欧美久久久| 我爱我色成人网| 中文字幕一区二区三区在线乱码| 国产精品亚洲午夜一区二区三区| 欧美精品亚洲精品日韩精品| 伊人亚洲福利一区二区三区| 美国十次综合久久| 18禁免费无码无遮挡不卡网站| 欧美国产一区二区| 国产黄色高清视频| 青草青草久热精品视频在线观看| 日本欧美国产| 女性生殖扒开酷刑vk| 欧美伊人精品成人久久综合97| 成人高清免费在线| 欧美极品一区二区| 国产一区二区福利视频| 男人天堂视频网| 欧美日韩成人免费| 成人在线免费观看91| 国内精品免费视频| 在线成人午夜影院| 亚洲成人人体| 精品国偷自产一区二区三区| 国产精品视频在线看| 天天色天天操天天射|