Redis为什么那么快

Redis多路复用模型

提到redis,我们就能想到快,但是,反问一下,单线程的redis为什么这么快?

这个问题有几个关键字,单线程,redis,快,我们依据这几个关键字一一分析

单线程

  1. 多线程可以提升系统的吞吐率,但并不是线性提升的,线程数增加,会增加对于共享资源管控的消耗

  2. 并发访问控制会增加系统的复杂度和降低可维护性

Redis

  1. Redis的单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成,像其他的数据持久化,异步复制,集群数据同步都是由其他的线程执行的

  2. Redis的单线程模型达到每秒十万级别的处理能力,就是Redis采用了多路复用机制

Redis快的原因主要有几个方面

a. Redis的大部分操作都是在内存上完成

b. 采用了高效的数据结构,如哈希表和调表

c. 采用了多路复用机制,在网络IO操作中能并发处理客户端大量请求,提高吞吐率

要了解多路复用机制,我们先要明白网络操作的基本IO模型和潜在的阻塞点,因为Redis是单线程执行,如果线程被阻塞了,就无法进行多路复用了

基本IO模型

在这里插入图片描述

在这个基础IO模型中,潜在的阻塞点在accept()和recv()。当Redis监听到客户端有连接请求,但是一直未能成功建立连接的时候,会阻塞在accept()方法,当Redis通过

recv() 从客户端读取数据时,如果数据一直无法到达,也会一直阻塞

非阻塞模型

Socket非阻塞模型,在这个模型中,不同操作调用后会返回不同的套接字类型,socket()方法会返回主动套接字,然后调用listen()方法,将主动套接字转化成监听套接字,可以监听来自

客户端的连接请求,最后,accept()方法接收到达客户端的连接,并返回已经连接的套接字

这里的套接字可以设置为非阻塞,Redis线程可以不用一直阻塞,有相应的机制在监听套接字上等待后续连接请求,并通知到Redis

基于多路复用的高性能I/O模型

Redis在只运行单线程情况下,允许内核中,同时存在多个监听套接字和已连接套接字,内核会一直监听套接字上的连接请求或数据请求,一旦有请求到来,会交给Redis线程处理

在这里插入图片描述

Redis框架调用epoll机制,让内核监听这些套接字,此时,Redis线程不会阻塞在某一个特定监听或者已连接套接字上,因为这个,Redis可以同时和多个客户端连接处理请求

回调机制

为了请求到达时可以通知到Redis线程,select/epoll提供了基于事件的回调机制,如上图,绑定了不同的事件队列,Redis单线程不断对事件队列进行处理,Redis不需要轮询是否有请求,而是通过回调

的机制避免CPU的浪费,能及时响应客户端的请求,提升Redis的响应性能

最后,用一个实例说明,解释下整个流程,连接请求和读数据请求

连接请求: 对应上面的AcceptEvent,当Linux内核监听到有连接请求是,就会触发Accept事件,内核就会回调Redis相应的accpet函数进行处理

多路复用的机制有Linux系统的select/epoll实现,也有FreeBSD的kqueue实现,还有基于Solaris的evport实现

TODOS

Redis的数据结构优化

内存操作细节,一条命令的执行流程

select/epoll技术细节,零拷贝是指什么?

Redis高可用,Redis Cluster和Codis部署区别

Redis持久化是怎么实现的?

Redis事务(隔离级别)

猜你喜欢

转载自blog.csdn.net/hugenshen/article/details/114988029