redis核心难点(Redis为什么这么快)
redis核心难点(Redis为什么这么快)注意:我们一直说的 Redis 单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的!然而,在Redis 4.0中,我们开始让Redis更加线程化。目前这仅限于在后台删除对象,以及阻塞通过Redis模块实现的命令。对于未来的版本,我们的计划是让Redis变得越来越多线程。CPU成为Redis性能瓶颈的情况并不常见,因为Redis通常会受到内存或网络的限制。例如,在 Linux 系统上使用流水线 Redis 每秒甚至可以提供 100 万个请求,所以如果你的应用程序主要使用O(N)或O(log(N))命令,它几乎不会占用太多的CPU。然而,为了最大化CPU利用率,你可以在同一个节点中启动多个Redis实例,并将它们视为不同的Redis服务。在某些情况下,一个单独的节点可能是不够的,所以如果你想使用多个cpu,你可以开始考虑一
硬盘数据库读取流程
内存数据库读取流程
因此,可以负责任地说,Redis这么快当然跟它基于内存运行有着很大的关系。但是,这还远远不是全部的原因。
Redis FAQ面对单线程的 Redis 你也许又会有疑问:敖丙,我的多核CPU发挥不了作用了呀!别急,Redis 针对这个问题专门进行了解答。
CPU成为Redis性能瓶颈的情况并不常见,因为Redis通常会受到内存或网络的限制。例如,在 Linux 系统上使用流水线 Redis 每秒甚至可以提供 100 万个请求,所以如果你的应用程序主要使用O(N)或O(log(N))命令,它几乎不会占用太多的CPU。
然而,为了最大化CPU利用率,你可以在同一个节点中启动多个Redis实例,并将它们视为不同的Redis服务。在某些情况下,一个单独的节点可能是不够的,所以如果你想使用多个cpu,你可以开始考虑一些更早的分片方法。
你可以在Partitioning页面中找到更多关于使用多个Redis实例的信息。
然而,在Redis 4.0中,我们开始让Redis更加线程化。目前这仅限于在后台删除对象,以及阻塞通过Redis模块实现的命令。对于未来的版本,我们的计划是让Redis变得越来越多线程。
注意:我们一直说的 Redis 单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的!
例如Redis进行持久化的时候会 fork了一个子进程 执行持久化操作
当一个网络IO发生(假设是read)时,它会涉及两个系统对象,一个是调用这个IO的进程,另一个是系统内核。
当一个read操作发生时,它会经历两个阶段:
①等待数据准备;
②将数据从内核拷贝到进程中。
为了解决网络IO中的问题,提出了4中网络IO模型:
- 阻塞IO模型
- 非阻塞IO模型
- 多路复用IO模型
- 异步IO模型
阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞时指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,不需要等到IO操作彻底完成。
阻塞IO模型在Linux中,默认情况下所有socket都是阻塞的,一个典型的读操作如下图所示:
当应用进程调用了recvfrom这个系统调用后,系统内核就开始了IO的第一个阶段:准备数据。
对于网络IO来说,很多时候数据在一开始还没到达时(比如还没有收到一个完整的TCP包),系统内核就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。
当系统内核一直等到数据准备好了,它就会将数据从系统内核中拷贝到用户内存中,然后系统内核返回结果,用户进程才解除阻塞的状态,重新运行起来。所以,阻塞IO模型的特点就是在IO执行的两个阶段(等待数据和拷贝数据)都被阻塞了。
非阻塞IO模型在Linux中,可以通过设置socket使IO变为非阻塞状态。当对一个非阻塞的socket执行read操作时,读操作流程如下图所示: