中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

redis server多路復用機制是什么?

發布時間:2020-05-21 11:16:19 來源:億速云 閱讀:1331 作者:Leah 欄目:系統運維

redis server多路復用機制是什么?相信大部分人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,話不多說,一起往下看吧。

redis server 啟動時調用bind() 傳入文件描述符fd6 綁定端口6379,調用listen()監聽端口,并通過accept() 等待連接

root@pmghong-VirtualBox:/usr/local/redis/bin# strace -ff -o /data/redis_strace/redis ./redis-server 
root@pmghong-VirtualBox:/proc/22330/fd# ls /data/redis_strace/ -l
total 48
-rw-r--r-- 1 root root 34741 3月  14 10:37 redis.25102
-rw-r--r-- 1 root root   134 3月  14 10:37 redis.25105
-rw-r--r-- 1 root root   134 3月  14 10:37 redis.25106
-rw-r--r-- 1 root root   134 3月  14 10:37 redis.25107

root@pmghong-VirtualBox:/proc/22330/fd# vi /data/redis_strace/redis.25102
... ...
epoll_create(1024)                      = 5
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 6
setsockopt(6, SOL_IPV6, IPV6_V6ONLY, [1], 4) = 0
setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(6, {sa_family=AF_INET6, sin6_port=htons(6379), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
listen(6, 511)                          = 0
fcntl(6, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(6, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
... ...
root@pmghong-VirtualBox:/proc/25102/fd# ll
total 0
dr-x------ 2 root root  0 3月  14 12:05 ./
dr-xr-xr-x 9 root root  0 3月  14 10:37 ../
lrwx------ 1 root root 64 3月  14 12:28 0 -> /dev/pts/0
lrwx------ 1 root root 64 3月  14 12:28 1 -> /dev/pts/0
lrwx------ 1 root root 64 3月  14 12:05 2 -> /dev/pts/0
lr-x------ 1 root root 64 3月  14 12:28 3 -> pipe:[104062]
l-wx------ 1 root root 64 3月  14 12:28 4 -> pipe:[104062]
lrwx------ 1 root root 64 3月  14 12:28 5 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 3月  14 12:28 6 -> socket:[104063]
lrwx------ 1 root root 64 3月  14 12:28 7 -> socket:[104064]
lrwx------ 1 root root 64 3月  14 12:28 8 -> socket:[256344]

第一階段:BIO(阻塞IO)

redis server多路復用機制是什么?

Redis Server 啟動后通過文件描述符fd6 監聽系統內核

Client1 / Client2 分別通過fd7,fd8 請求訪問redis

在BIO的場景下,redis server 會調用read()方法并進入阻塞狀態,也就是直到fd7 有請求過來,處理完才能處理其他請求

這個模式缺點很明顯,就是阻塞IO導致效率低

第二階段 NIO (非阻塞IO)

redis server多路復用機制是什么?

跟BIO的區別在于,調用read(fd7) 時,如果沒有請求數據,立即給redis server 返回一個錯誤

redis server 收到該類型的錯誤即可知道當前連接沒有數據過來,可以繼續處理下一個請求,提高處理效率

bind(6, {sa_family=AF_INET6, sin6_port=htons(6379), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
listen(6, 511)                          = 0
fcntl(6, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(6, F_SETFL, O_RDWR|O_NONBLOCK)    = 0

該模式的問題在于,定時輪詢調用read(fdx)系統調用,當多個client 請求過來時,需要頻繁的進行內核態/用戶態切換,上下文切換開銷大

第三階段 select 同步非阻塞

redis server多路復用機制是什么?

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class
of I/O operation (e.g., input possible).  A file descriptor is considered ready if it is possible to perform a corresponding I/O  operation  (e.g.,  read(2)
without blocking, or a sufficiently small write(2)).

目標是同時監聽多個fd,直到一個或者多個fd 進入ready 狀態,才會調用read()等系統調用處理業務邏輯,而不像上述的NIO場景下,需要輪詢調用x個read()

select 只能解決事件通知問題(即哪些進程能讀,哪些不能讀的問題),但到了內核態,仍需在內核中遍歷x個fd,看哪個client 發生了IO,再通知select 把結果集返回給server端,接著由sever端向指定的fd發起read() 系統調用

第四階段 epoll 多路復用

redis server多路復用機制是什么?

epoll 機制包括 epoll_create / epoll_ctl / epoll_wait 3個系統調用

// epoll_create
// 說明
epoll_create() creates an epoll(7) instance.

//函數簽名
int epoll_create(int size);

//返回值 
On success, these system calls return a nonnegative file descriptor.  
On error, -1 is returned, and errno is set to indicate the error.

//epoll_ctl
//說明
This  system  call  performs control operations on the epoll(7) instance referred to by the file descriptor epfd.  It requests that the operation op be per‐
formed for the target file descriptor, fd.

//函數簽名
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

// op 類型 EPOLL_CTL_ADD / EPOLL_CTL_MOD  /EPOLL_CTL_DEL

// 返回值
When successful, epoll_ctl() returns zero.  
When an error occurs, epoll_ctl() returns -1 and errno is set appropriately.

//epoll_ctl
//說明
The  epoll_wait()  system call waits for events on the epoll(7) instance referred to by the file descriptor epfd.  The memory area pointed to by events will
contain the events that will be available for the caller.  Up to maxevents are returned by epoll_wait().  The maxevents argument must be greater than zero.

//函數簽名
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

//返回值
When successful, epoll_wait() returns the number of file descriptors ready for the requested I/O, or zero if no file  descriptor  became  ready  during  the
requested timeout milliseconds.  When an error occurs, epoll_wait() returns -1 and errno is set appropriately.
epoll_create(1024)                      = 5
... ...
bind(6, {sa_family=AF_INET6, sin6_port=htons(6379), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
listen(6, 511)                          = 0
... ...
bind(7, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(7, 511)                          = 0
... ...
epoll_ctl(5, EPOLL_CTL_ADD, 6, {EPOLLIN, {u32=6, u64=6}}) = 0
epoll_ctl(5, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=7}}) = 0
epoll_ctl(5, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=3, u64=3}}) = 0

write(...)
read(...)
epoll_wait(5, [], 10128, 0)             = 0

1、進程啟動時通過epoll_create() 創建epoll instance,成功時返回一個非負數的fdn,失敗返回-1還有錯誤碼

2、調用epoll_ctl(上一步epoll_create 返回的fd,op,fd6,事件類型<accpet>)

3、調用epoll_wait() 監聽內核事件,調用成功時返回該fd。例如當c1請求redisserver 時,首先需要通過fd6建立連接,此時通過epoll_ctl() 中對fd6 的accept()調用可以監聽到該請求,并將fd6傳給epoll_wait()

4、redis server端 從epoll_wait() 獲取需要IO操作的fd,發現c1 通過fd6請求建立連接,為其分配fd7,并在epoll_ctl()注冊一個監聽,例如epoll_ctl(fdn,op, fd7, <read>)

更多相關知識點文章:

redis多路復用原理是什么以及常見問題有哪些

redis多路復用技術的示例分析

看完上述內容,你們對redis server的多路復用機制大概了解了嗎?如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

措美县| 贞丰县| 深州市| 慈溪市| 莱阳市| 长子县| 汉阴县| 三门县| 绍兴县| 西安市| 年辖:市辖区| 慈利县| 嘉兴市| 四子王旗| 旺苍县| 岢岚县| 和平区| 莱州市| 历史| 怀安县| 敦煌市| 武川县| 珠海市| 明溪县| 新巴尔虎右旗| 锦屏县| 平定县| 康保县| 陇川县| 新野县| 绥宁县| 镇远县| 澄迈县| 成武县| 泾川县| 含山县| 额敏县| 莎车县| 富阳市| 忻州市| 西乡县|