redis的IO模型

一、什么是IO模型

我们的应用都是部署在linux系统中,linux系统也是一种应用,它是基于计算机硬件的一种操作系统软件。当我们接收一次网络传输,计算机硬件的网卡会从网络中将读到的字节流写到linux的buffer缓冲区内存中,然后用户空间会调用linux对外暴露的接口,将linux中的buffer内存中的数据再读取到用户空间。这一次读操作就是一次IO。同样写也是这样的。

不同的操作系统,IO模型不一样,下面介绍的是Linux系统的几种IO模型

这样做是为了保护Linux操作系统,避免外部应用或者人为直接操作内核系统。

当线程操作在用户空间时候的状态称为:用户态
当线程操作在内核空间时候的状态称为:内核态

IO的性能瓶颈:
a.用户态与内核态的切换(数据拷贝)
b.读写线程的阻塞等待

linux的IO模型就是针对这两点去优化的

image.png

二、Linux的IO模型

1.阻塞IO模型

当用户应用线程调用linux操作系统的recvfrom函数读取数据的时候,如果内核的buffer内存中没有数据,那么用户线程会阻塞等待,直到内核的buffer内存中有数据了,才去将内核的buffer内存中的数据拷贝到用户应用内存中。
类似于你排队买包子,但是包子这时候没有了,但是你不知道还有没有包子,如果没有,你只能在那等待包子出炉,什么也做不了,干等着,直到包子出炉了,你才能拿到包子,放到自己的口袋中。

image.png

问题:
当一个线程阻塞住了,会导致后续所有的线程都阻塞住,即使后面的读写数据已经就绪,也无法进行读写。

2.非阻塞IO模型

当用户应用线程调用linux操作系统的recvfrom函数读取数据的时候,如果内核的buffer内存中没有数据,那么用户线程会直接拿到结果(没有数据)不需要等待,于是又会发起一次recvfrom函数调用,直到内核的buffer内存中有数据了,才去将内核的buffer内存中的数据拷贝到用户应用内存中。
类似于你排队买包子,老板直接和你说没有包子了,你已经知道了结果,你一遍又一遍的问老板,还有没有包子了,直到老板出炉了包子,告诉你,你才能拿到包子,放到口袋中。

image.png

问题:
如果一直没有数据的话,线程会死循环的调用recvfrom函数,频繁使用CPU资源,导致CPU资源的浪费。

3.IO多路复用

文件描述符(FD)

内核kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。文件包含音频文件,常规文件,硬件设备等等,也包括网络套接字(Socket)。
IO多路复用就是利用单线程去监听多了文件描述符FD,并在某个文件描述符FD可读,可写的时候接收到通知,避免无效的等待,充分利用CPU资源。

select模式

用户应用线程调用select函数去监听多个FD文件描述符,如果没有数据,还是要等待,如果有就绪的文件FD,说明有数据,那就去读对应的FD就绪的文件数据,此时内核会将文件FD集合拷贝到用户内存中,然后去遍历FD集合,找到可以读的数据的FD,然后再去读取,读完了之后会将FD的集合再拷贝到内核内存中。
类似于你去餐厅排队点餐,这时候有一个服务员,服务员通过平板监控后厨,你只需要询问服务员有没有东西吃就可以了,如果没有你还是需要等待,但是如果有了,服务员通过监控就知道有东西可以吃了,就会让你点餐了。

image.png

select模式的问题:
a.需要将整个FD数组从用户空间拷贝到内核空间,select结束还要再次拷贝到用户空间
b.select无法得知是具体的哪一个FD就绪,需要便利整个FD集合(数组
c.select监听的FD集合(数组)大小固定是1024,底层设计写死是1024个。

poll模式

poll模式其实和select模式原理差不多,不同的点在于,poll模式底层加上了一个event事件,分成读事件,写事件,异常事件等等。
流程:
a.先添加需要监听的事件,是读事件,还是写事件,可以是多个事件
b.将监听到的事件FD,转换成链表,保存在内核缓冲区
c.内核缓冲区将事件FD链表拷贝到用户缓冲区,并返回就绪的FD数量
d.用户缓冲区判断就绪的FD数量,如果大于0则开始便利事件FD链表

poll模式的问题:
a.需要将整个FD链表从用户空间拷贝到内核空间,poll结束还要再次拷贝到用户空间
b.poll无法得知是具体的哪个就绪的FD事件,需要便利整个FD事件(链表

对比select模式
由于使用了链表,理论上事件个数可以是无数个,但是随着事件个数增多,链表的遍历性能会下降,而且当没有就绪事件的时候还是需要等待。

epoll模式

epoll模式是在poll模式的基础上再次改进,首先将存储事件的FD链表改成了红黑树(理论上也是无上限的),红黑树的遍历性能稳定,其次就是将具体的就绪事件单独复制出来然后拷贝给用户缓冲区,用户缓冲区拿到的是已经就绪的事件,无需遍历性能再次提升。
流程:
a.先将注册的监听事件
b.将所有的FD挂载在一个红黑树中
c.当FD就绪调用回调函数将对应的FD复制到一个链表中
d.将链表从内核缓冲区拷贝到用户缓冲区,并返回链表大小n
e.用户线程直接判断n大小,当n不为0的时候,直接读取链表(全部是就绪的FD)的数据即可

信号驱动IO

当用户应用线程调用linux操作系统的sigaction函数,直接返回,然后该线程去做其他事情了,当有数据来了的时候,内核空间会去递交信号给用户空间,此时用户空间会调用recvfrom函数去将数据从内核空间缓冲区拷贝到用户空间缓冲区,并处理数据。
类似于你点餐点完了,服务员会给你一个号码,然后你的餐好了,服务员会叫你的号码,然后你就去拿餐。

image.png

问题:
当调用的线程过多,对应的信号量会增多,SIGIO函数处理不及时,会导致保存信号的队列溢出;而且内核空间与用户空间频繁的进行信号量的交互,性能很差。

异步IO

性能上来说也是不错的,就是在实际开发中,需要控制它的线程并发数,所以实现起来会非常麻烦,所以使用很少

总结

三种IO多路复用对比来说epoll的效果是最好的。解决了select和poll模式中存在的问题。

而redis就是使用的epoll模式的IO模型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358

推荐阅读更多精彩内容