面试官:Redis为什么快?
我:内心:不知道为什么一直问这个问题。
- 纯内存操作
- 单线程操作,避免了频繁的上下文切换
- 合理高效的数据结构
- 采用了非阻塞I/O多路复用机制
实际上Redis服务器是一个事件驱动程序,分为文件事件和时间事件,就主要讲一下文件事件。
Redis基于Reactor模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器
- 文件事件处理器使用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器
- 当被监听的套接字准备好执行连接应答、读取、写入、关闭等操作时,与操作相对于的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
- 简单点:就是一堆套接字请求,被一个叫做I/O多路复用程序监听,通过文件事件分派器一个一个和事件处理器绑定在一起去处理。
I/O多路复用程序是有常见的select、epoll等系统调用所实现的。有个小故事,自行理解BIO、NIO、select、poll、epoll等
故事情节为:老李去买火车票,三天后买到一张退票。参演人员(老李,黄牛,售票员,快递员),往返车站耗费1小时。
往返车站可以看成系统调用,调用一次一小时
老李去火车站买票,排队三天买到一张退票。
耗费:在车站吃喝拉撒睡 3天,其他事一件没干。
老李去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。
耗费:往返车站6次,路上6小时,其他时间做了好多事。
2比1多了个自己轮训调用
- select/poll
老李去火车站买票,委托黄牛,然后每隔6小时电话黄牛询问,黄牛三天内买到票,然后老李去火车站交钱领票。
耗费:往返车站2次,路上2小时,黄牛手续费100元,打电话17次
实际上,就是自己不断调select(像个船一样,装了很多描述符)询问哪些描述符可读可写,比如又一个可读了,咱就调用可读系统调用就ok了
- epoll
老李去火车站买票,委托黄牛,黄牛买到后即通知老李去领,然后老李去火车站交钱领票。 耗费:往返车站2次,路上2小时,黄牛手续费100元,无需打电话
实际上,自己不用管了,当有可读的时候,直接中断你,然后你自己去读
老李去火车站买票,给售票员留下电话,有票后,售票员电话通知老李,然后老李去火车站交钱领票。
耗费:往返车站2次,路上2小时,免黄牛费100元,无需打电话
不要黄牛了,省了这个单线程,系统通知你,你收到以后自己去读
老李去火车站,告诉售票员要买票,售票员买到票之后,打电话通知老李把票放在某某储物箱,老李根据储物箱地址自己去取票。
耗费:往返车站1次,路上1小时,免黄牛费100元,无需打电话
只需要注册一次,得到消息之后,就去另外一个地址上取走票
黄牛是多路复用,他不仅可以帮你买票,还可以其他人买票,还可以买飞机票,高铁票等。