42|0

74

帖子

0

资源

一粒金砂(初级)

redis server多路复用机制是什么? [复制链接]

redis server多路复用机制是什么?相信大部分人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,话不多说,一起往下看吧。
redis server 启动时调用bind() 传入文件描述符fd6 绑定端口6379,调用listen()监听端口,并通过accept() 等待连接
root@pmghong-VirtualBox:/usr/local/redis/bin#strace-ff-o/data/redis_strace/redis./redis-serverroot@pmghong-VirtualBox:/proc/22330/fd#ls/data/redis_strace/-ltotal48-rw-r--r--1rootroot347413月1410:37redis.25102-rw-r--r--1rootroot1343月1410:37redis.25105-rw-r--r--1rootroot1343月1410:37redis.25106-rw-r--r--1rootroot1343月1410:37redis.25107root@pmghong-VirtualBox:/proc/22330/fd#vi/data/redis_strace/redis.25102......epoll_create(1024)=5socket(PF_INET6,SOCK_STREAM,IPPROTO_TCP)=6setsockopt(6,SOL_IPV6,IPV6_V6ONLY,[1],4)=0setsockopt(6,SOL_SOCKET,SO_REUSEADDR,[1],4)=0bind(6,{sa_family=AF_INET6,sin6_port=htons(6379),inet_pton(AF_INET6,"::",&sin6_addr),sin6_flowinfo=0,sin6_scope_id=0},28)=0listen(6,511)=0fcntl(6,F_GETFL)=0x2(flagsO_RDWR)fcntl(6,F_SETFL,O_RDWR|O_NONBLOCK)=0......root@pmghong-VirtualBox:/proc/25102/fd#lltotal0dr-x------2rootroot03月1412:05./dr-xr-xr-x9rootroot03月1410:37../lrwx------1rootroot643月1412:280->/dev/pts/0lrwx------1rootroot643月1412:281->/dev/pts/0lrwx------1rootroot643月1412:052->/dev/pts/0lr-x------1rootroot643月1412:283->pipe:[104062]l-wx------1rootroot643月1412:284->pipe:[104062]lrwx------1rootroot643月1412:285->anon_inode:[eventpoll]lrwx------1rootroot643月1412:286->socket:[104063]lrwx------1rootroot643月1412:287->socket:[104064]lrwx------1rootroot643月1412:288->socket:[256344]第一阶段:BIO(阻塞IO)

Redis Server 启动后通过文件描述符fd6 监听系统内核
Client1 / Client2 分别通过fd7,fd8 请求访问redis

在BIO的场景下,redis server 会调用read()方法并进入阻塞状态,也就是直到fd7 有请求过来,处理完才能处理其他请求
这个模式缺点很明显,就是阻塞IO导致效率低
第二阶段 NIO (非阻塞IO)

跟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)=0listen(6,511)=0fcntl(6,F_GETFL)=0x2(flagsO_RDWR)fcntl(6,F_SETFL,O_RDWR|O_NONBLOCK)=0该模式的问题在于,定时轮询调用read(fdx)系统调用,当多个client 请求过来时,需要频繁的进行内核态/用户态切换,上下文切换开销大
第三阶段 select 同步非阻塞

intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);select()andpselect()allowaprogramtomonitormultiplefiledescriptors,waitinguntiloneormoreofthefiledescriptorsbecome"ready"forsomeclassofI/Ooperation(e.g.,inputpossible).AfiledescriptorisconsideredreadyifitispossibletoperformacorrespondingI/Ooperation(e.g.,read(2)withoutblocking,orasufficientlysmallwrite(2)).目标是同时监听多个fd,直到一个或者多个fd 进入ready 状态,才会调用read()等系统调用处理业务逻辑,而不像上述的NIO场景下,需要轮询调用x个read()

select 只能解决事件通知问题(即哪些进程能读,哪些不能读的问题),但到了内核态,仍需在内核中遍历x个fd,看哪个client 发生了IO,再通知select 把结果集返回给server端,接着由sever端向指定的fd发起read() 系统调用
第四阶段 epoll 多路复用

epoll 机制包括 epoll_create / epoll_ctl / epoll_wait 3个系统调用
//epoll_create//说明epoll_create()createsanepoll(7)instance.//函数签名intepoll_create(intsize);//返回值Onsuccess,thesesystemcallsreturnanonnegativefiledescriptor.Onerror,-1isreturned,anderrnoissettoindicatetheerror.//epoll_ctl//说明Thissystemcallperformscontroloperationsontheepoll(7)instancereferredtobythefiledescriptorepfd.Itrequeststhattheoperationopbeper‐formedforthetargetfiledescriptor,fd.//函数签名intepoll_ctl(intepfd,intop,intfd,structepoll_event*event);//op类型EPOLL_CTL_ADD/EPOLL_CTL_MOD/EPOLL_CTL_DEL//返回值Whensuccessful,epoll_ctl()returnszero.Whenanerroroccurs,epoll_ctl()returns-1anderrnoissetappropriately.//epoll_ctl//说明Theepoll_wait()systemcallwaitsforeventsontheepoll(7)instancereferredtobythefiledescriptorepfd.Thememoryareapointedtobyeventswillcontaintheeventsthatwillbeavailableforthecaller.Uptomaxeventsarereturnedbyepoll_wait().Themaxeventsargumentmustbegreaterthanzero.//函数签名intepoll_wait(intepfd,structepoll_event*events,intmaxevents,inttimeout);//返回值Whensuccessful,epoll_wait()returnsthenumberoffiledescriptorsreadyfortherequestedI/O,orzeroifnofiledescriptorbecamereadyduringtherequestedtimeoutmilliseconds.Whenanerroroccurs,epoll_wait()returns-1anderrnoissetappropriately.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)=0listen(6,511)=0......bind(7,{sa_family=AF_INET,sin_port=htons(6379),sin_addr=inet_addr("0.0.0.0")},16)=0listen(7,511)=0......epoll_ctl(5,EPOLL_CTL_ADD,6,{EPOLLIN,{u32=6,u64=6}})=0epoll_ctl(5,EPOLL_CTL_ADD,7,{EPOLLIN,{u32=7,u64=7}})=0epoll_ctl(5,EPOLL_CTL_ADD,3,{EPOLLIN,{u32=3,u64=3}})=0write(...)read(...)epoll_wait(5,[],10128,0)=01、进程启动时通过epoll_create() 创建epoll instance,成功时返回一个非负数的fdn,失败返回-1还有错误码
2、调用epoll_ctl(上一步epoll_create 返回的fd,op,fd6,事件类型)

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, )

更多相关知识点文章:
redis多路复用原理是什么以及常见问题有哪些
redis多路复用技术的示例分析
看完上述内容,你们对redis server的多路复用机制大概了解了吗?如果想了解更多相关文章内容,欢迎关注Vecloud行业资讯频道,感谢各位的阅读!
此帖出自信息发布论坛

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

最新文章 更多>>
    关闭
    站长推荐上一条 1/10 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表