精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

国产精品国产三级国产有无不卡 | 久久久xxx| 亚洲欧美日韩一区在线| 鲁一鲁一鲁一鲁一av| 在线观看三级视频| 99国产精品久久久久久久久久久 | 欧美激情一区二区三区在线| 亚洲aⅴ男人的天堂在线观看| 国产香蕉在线视频| 成人女性视频| 亚洲国产成人精品女人久久久 | 国产一区二区三区黄视频 | 黄色动漫在线免费看| aⅴ在线视频男人的天堂| 国产不卡视频在线播放| 国产精品视频男人的天堂| 国产一级做a爰片在线看免费| 国产一区日韩| 亚洲国产精品推荐| 中文字幕国产高清| 日韩制服一区| 欧美日韩国产精品一区二区三区四区 | 亚洲av毛片基地| 美女视频亚洲色图| 91精品免费观看| 奇米影音第四色| 中文字幕这里只有精品| 亚洲资源中文字幕| 男女h黄动漫啪啪无遮挡软件| 噜噜噜噜噜在线视频| 国产成人av电影在线观看| 国产欧美在线看| 波多野结衣黄色网址| 在线不卡欧美| 欧美国产在线电影| 久久精品一区二区三区四区五区| 激情婷婷综合| 亚洲男人7777| 熟女丰满老熟女熟妇| 第四色在线一区二区| 欧美一区二区三区免费| 亚洲小视频网站| 成人精品动漫| 欧美日韩精品综合在线| 中文字幕永久视频| 超碰这里只有精品| 在线观看免费亚洲| 成年人在线观看视频免费| 欧美gay视频| 欧美性猛交xxxx富婆| av7777777| 色戒汤唯在线| 日韩欧亚中文在线| 国产精品第12页| 你懂得影院夜精品a| 色综合久久久久综合| 亚洲爆乳无码专区| 国产成人精品一区二三区在线观看 | 2019日韩中文字幕mv| 天堂va在线| 亚洲午夜一区二区| 免费av手机在线观看| av日韩国产| 欧美日韩国产精品一区二区不卡中文| 欧美一区二区中文字幕| 中文不卡1区2区3区| 日韩欧美在线看| 青青青国产在线视频| 国产91欧美| 4hu四虎永久在线影院成人| 激情黄色小视频| 欧美黄色一级| 亚洲精品v天堂中文字幕| 久久久无码人妻精品一区| 你懂的一区二区三区| 在线电影av不卡网址| 99国产精品无码| 欧美欧美天天天天操| 久久欧美在线电影| 亚洲 欧美 日韩 在线| 捆绑调教美女网站视频一区| 91成人免费观看| 神马久久久久久久久久| 国产日韩精品一区二区浪潮av | 欧美日韩在线播放| 天天操夜夜操很很操| 欧洲亚洲一区二区三区| 自拍亚洲一区欧美另类| 久久久久久久久久99| 亚洲专区一区二区三区| 成人激情视频在线观看| 天堂在线观看免费视频| 国产精品少妇自拍| 日本阿v视频在线观看| 免费观看成人性生生活片| 欧美精品一级二级三级| 国产xxxxxxxxx| 久久国产电影| 91成人在线播放| 国产男男gay体育生网站| 91亚洲男人天堂| 天天爱天天做天天操| 涩涩视频在线| 日韩欧美精品三级| 日本黄色小视频在线观看| 欧美精品九九| 国产精品视频自拍| 亚洲人妻一区二区三区| 亚洲色图另类专区| 茄子视频成人免费观看| 99re6热只有精品免费观看| 在线播放精品一区二区三区 | 末成年女av片一区二区下载| 欧美日韩成人综合在线一区二区| 黄色网址在线视频| 午夜欧美精品久久久久久久| 国产精品久久久久久久久男| 国精品人妻无码一区二区三区喝尿| 国产精品蜜臀av| 97国产精东麻豆人妻电影| 秋霞一区二区| 日韩三级成人av网| 亚洲精品一区二区二区| 99国产麻豆精品| 久久国产精品视频在线观看| 精品国产一区二区三区2021| 中文国产成人精品| 香蕉污视频在线观看| 91小视频在线免费看| 黄色激情在线视频| 999久久精品| 九九热这里只有在线精品视| 国产精品无码久久av| 国产精品五月天| 91视频免费版污| 亚洲人成网站77777在线观看| 国模极品一区二区三区| 成人午夜精品福利免费| 亚洲欧美激情一区二区| 国模私拍视频在线观看| 日本女优一区| 国产精品视频99| av网站在线播放| 欧美三级在线播放| 欧美福利第一页| 日韩黄色在线观看| 亚洲国产精品毛片| 精品69视频一区二区三区| 永久免费精品影视网站| 中文字幕乱伦视频| 国产精品人人做人人爽人人添| 五月天婷婷激情视频| 第一社区sis001原创亚洲| 国产精品久久久久久久久久免费 | 欧美日韩一本| 琪琪第一精品导航| 国产在线视频网址| 欧美亚洲一区三区| 国产日产精品一区二区三区的介绍| 麻豆视频一区二区| 色中文字幕在线观看| 美国十次综合久久| 国外成人性视频| 免费人成在线观看网站| 欧洲另类一二三四区| 蜜桃av.com| 国产精品2024| 啊啊啊一区二区| 色棕色天天综合网| 成人福利视频在线观看| av网站免费在线观看| 精品国产3级a| 无码人妻丰满熟妇奶水区码| 中文字幕第一区二区| 91香蕉视频免费看| 91久久夜色精品国产九色| 欧美日韩精品免费看| 欧美少妇激情| 欧美激情手机在线视频 | 最近中文字幕一区二区| 天堂美国久久| 黑人巨大精品欧美一区二区小视频 | 国产精品一区二区三区久久久| 国产原创在线观看| 亚洲精品mp4| 91超薄丝袜肉丝一区二区| 亚洲精品国久久99热| 一级国产黄色片| 卡一卡二国产精品| 福利视频一二区| 日韩欧美一区二区三区免费看| 91久色国产| 欧美日韩免费观看视频| 久久99久久久久久久噜噜| 欧美黄色小说| 日韩欧美一区二区不卡| 亚洲av中文无码乱人伦在线视色| 亚洲欧洲精品成人久久奇米网| 精品人妻在线视频| 老色鬼精品视频在线观看播放| 久久久久久www| 欧美残忍xxxx极端| 久久久久久国产精品mv| 激情五月综合婷婷| 国产高清在线不卡| 日本在线观看大片免费视频| 亚洲性av在线| 日韩一区二区三区在线观看视频| 欧美日韩精品久久久| 91porny在线| 亚洲最新视频在线播放| 最新日韩免费视频| 国产视频一区在线观看| 国产美女视频免费观看下载软件| 精品在线观看视频| 黄色aaa级片| 国产欧美大片| 男人添女人荫蒂免费视频| 亚洲成av人片乱码色午夜| 日韩欧美一区二区视频在线播放| 女一区二区三区| av在线不卡一区| 粉嫩一区二区三区在线观看| 国产精品高潮视频| 亚洲美女炮图| 91国语精品自产拍在线观看性色 | 国产精品一区二区亚洲| 久久日韩精品一区二区五区| 第一页在线视频| 国产毛片一区二区| 高潮一区二区三区| 喷白浆一区二区| 美女喷白浆视频| 日韩黄色片在线观看| 999精品视频在线| 日韩一区欧美二区| 日本男人操女人| 首页欧美精品中文字幕| 日本中文字幕片| 日韩精品欧美成人高清一区二区| 日本成年人网址| 久久久久网站| 欧美性猛交xxx乱久交| 日精品一区二区| 激情婷婷综合网| 日韩精品电影一区亚洲| 久久精品.com| 青青草原综合久久大伊人精品优势 | 欧美精品一区二区三区高清aⅴ| 亚洲国产精品久久久久爰性色 | 欧美久久一区| 成人毛片一区二区| 久久aⅴ国产紧身牛仔裤| 黑鬼大战白妞高潮喷白浆| 最新亚洲激情| 欧美精品99久久| 久久亚洲风情| 亚洲美女性囗交| 国产精品亚洲综合一区在线观看| 国产老头和老头xxxx×| 成人白浆超碰人人人人| 先锋资源av在线| 久久人人爽人人爽| 久草福利资源在线| 一区二区欧美精品| 在线观看中文字幕视频| 欧美日韩精品高清| 亚洲成人av综合| 国产网站欧美日韩免费精品在线观看 | 国产一区二区在线视频播放| 久久国产精品99国产| 午夜欧美福利视频| 国产精品一区二区视频| 伊人网综合视频| 国产女主播视频一区二区| 日韩欧美国产成人精品免费| 亚洲高清视频的网址| aaaaaa毛片| 欧美一区二区三区男人的天堂| 免费观看黄色av| 亚洲天堂av在线免费| 国产美女福利在线| 91sa在线看| www.欧美视频| 精品麻豆av| 国产精品成人一区二区不卡| 国产精品久久久久7777| 青草国产精品久久久久久| 国产调教打屁股xxxx网站| 久久久综合网站| 欧美激情图片小说| 色综合天天天天做夜夜夜夜做| 亚洲一区二区三区网站| 亚洲国产成人91精品| 日本美女在线中文版| 91精品国产91久久久久福利| 国产原创一区| 久久er99热精品一区二区三区 | 久久久久久久久久网| 蜜桃精品视频在线| 捆绑裸体绳奴bdsm亚洲| 亚洲日本乱码在线观看| 天天爱天天做天天爽| 亚洲第一二三四五区| 欧美三级黄网| 国产成人91久久精品| 波多野结衣在线一区二区| 亚洲午夜精品久久| 亚洲在线网站| 成人午夜精品无码区| 亚洲伦在线观看| 亚洲视屏在线观看| 精品无人区太爽高潮在线播放| 9191在线播放| 成人xxxxx| 久久人体视频| 黄色国产小视频| 久久综合国产精品| 国产精品suv一区二区| 91精品国产麻豆| 求av网址在线观看| 国产精品高潮在线| 免费成人结看片| 又粗又黑又大的吊av| 成人国产一区二区三区精品| 中文字幕手机在线观看| 5858s免费视频成人| 一区二区高清不卡| 国产精品流白浆视频| 九色精品国产蝌蚪| 北条麻妃在线一区| 久久午夜羞羞影院免费观看| 男人的天堂一区二区| 亚洲а∨天堂久久精品9966| 青草视频在线免费直播| 99re资源| 欧美色图首页| 日本人妻一区二区三区| 亚洲免费观看高清完整版在线| 国产口爆吞精一区二区| www.xxxx欧美| 精品视频在线播放一区二区三区 | 亚洲女人av| 91玉足脚交白嫩脚丫| 香蕉av福利精品导航 | 中文字幕欧美日韩在线| 免费在线成人激情电影| 亚洲一卡二卡三卡| 精品一区二区三区视频在线观看| 国产3级在线观看| 在线综合+亚洲+欧美中文字幕| 成人午夜在线影视| 亚洲最大的网站| 国内一区二区三区| 久久福利小视频| 色屁屁一区二区| av男人的天堂在线| 成人午夜在线视频一区| 欧美激情视频一区二区三区在线播放 | 亚洲天堂男人天堂| 日韩欧美2区| 欧美aaa在线观看| 粉嫩欧美一区二区三区高清影视| 日韩成年人视频| 亚洲欧美另类人妖| 欧美视频第一| 国产精品无码电影在线观看| www.66久久| 亚洲精品91天天久久人人| 精品国产欧美一区二区五十路| 日本一区二区三区播放| 人妻少妇精品无码专区二区 | 日韩电影天堂视频一区二区| 免费人成网站在线观看欧美高清| 免费看特级毛片| 欧美精品一区二区久久久| 三上悠亚一区二区| 中文字幕中文字幕在线中心一区| 国产美女一区二区| 97免费在线观看视频| 亚洲最新av在线网站| 精品亚洲二区| 无码人妻h动漫| 亚洲欧美日韩系列| 日本午夜在线视频| 成人欧美一区二区三区在线湿哒哒 | 久久99久久99精品免观看粉嫩| 米奇777超碰欧美日韩亚洲| 色戒在线免费观看| 五月激情综合网| 日本在线免费看| 欧美日韩在线一二三| 国内精品久久久久影院一蜜桃| 久久高清免费视频| 日韩中文在线视频| 神马日本精品| 一个人看的视频www| 欧洲精品一区二区三区在线观看| 美足av综合网| 在线精品亚洲一区二区|