对线面试官 -Redis(五 为什么这么快为什么能抗住高并发)
面试官:Redis 为什么可以抗高并发?
派大星:首先,Redis 使用内存存储数据,避免了磁盘 I/O 的开销,提高了数据访问的速度。其次,Redis 拥有丰富的对象类型,包含八种类型,满足不同的需求。此外,Redis 采用了高效的数据结构,减少了内存占用和计算复杂度。Redis 还使用单线程模型,避免了多线程之间的上下文切换和竞争条件,提升了 CPU 利用率。最后,Redis 使用非阻塞 I/O 多路复用机制(多路复用 IO 模型实际也是传统阻塞型 IO 模型演化而来的),充分利用 CPU 和网络资源,提高了并发处理能力。
面试官:Redis 为什么使用单线程却依旧可以抗高并发?
面试官考察目的分析:
考察你对于 Redis 原理的理解程度;
考察你对于网络连接的理解程度;
派大星:首先 Redis 为什么选择单线程的实现方式:
从 Redis 自身特性来说,Redis 是基于内存的数据库,所以数据处理速度非常快。另外它的底层使用了很多效率很高的数据结构,如哈希表和跳表等。另外 Redis 从狭义上面来说他是单线程的,网络请求解析与数据读写都是由主线程完成。因此它内部就省去了很多多线程访问共享数据资源的繁琐设计,同时也避免了频繁的线程上下文切换因此减少了多线程的系统开销。
派大星:Redis 为什么可以抗高并发。
其次从 IO 模型角度来说,Redis 使用的是 IO 多路复用模型,使得它可以在网络 IO 操作并发处理数十万的客户端网络连接,实现非常高的网络吞吐率。这也是 Redis 可以实现高并发访问的最主要的原因。
还有一点就是常识问题:我们都知道磁盘的寻址是 ms 级别的,带宽是 G/M(也就是千兆位每秒或兆位每秒)。而内存寻址是 ns 级别的,并且带宽远比磁盘快得多。从这个角度来看 Redis 基于内存的数据库快是毋庸置疑的。
面试官:刚才你提到了 IO 多路复用模型,其实也就是 Redis 线程模型,能详细说下 Redis 的 IO 多路复用的原理吗?
派大星:好的。首先我们要明确知道 Redis 服务器是一个事件驱动程序, 服务器处理的事件分为文件事件
和时间事件
两类。
文件事件:Redis 主进程中,主要处理客户端的连接请求与响应。
时间事件:fork 出的子进程中,处理如 AOF 持久化任务等。
派大星:之所以 Redis 的文件事件是单进程,单线程模型,但是确保持着优秀的吞吐量,IO 多路复用起到了主要作用。
文件事件是对套接字操作的抽象,每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。
IO 多路复用程序负责监听多个套接字并向文件事件分派器传送那些产生了事件的套接字。文件事件分派器接收 IO 多路复用程序传来的套接字,并根据套接字产生的事件的类型,调用相应的事件处理器。示例如图所示:
派大星:而 Redis 的 IO 多路复用程序的所有功能都是通过包装常见的 select
、poll
、evport
和 kqueue
这些 IO 多路复用函数库来实现的,每个 IO 多路复用函数库在 Redis 源码中都有对应的一个单独的文件。
Redis 为每个 IO 多路复用函数库都实现了相同的 API,所以 IO 多路复用程序的底层实现是可以互换的。如图:
派大星:因此 Redis 把所有连接与读写事件、还有提到的时间事件一起集中管理,并对底层 IO 多路复用机制进行了封装,最终实现了单进程能够处理多个连接以及读写事件。这就是 IO 多路复用在 redis 中的应用。
面试官:Redis 有哪些性能优化好的地方?
派大星:首先 Redis 是一个偏向 计算向数据移动
、基于内存的、丰富的数据类型等等。
面试官:回答的不错
派大星:谢谢,如果对 Redis 的 IO 多路复用模型、以及 Redis 服务器处理的事件感兴趣,后续我可以出一片单独的文章进行讲解哈。
如有问题,欢迎加微信交流:w714771310,或关注微信公众号【码上遇见你】。
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/64840c589551aff737d1ba1c6】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论