Redis为什么这么快,你真的清楚吗?

语言: CN / TW / HK

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

前言

工作中我们经常会用到Redis,单机的Redis的并发量可以支持万级别,那么为什么Redis为什么会如此的快呢?

关于这个问题我们可以从如下的几个方面来分析:

图片.png

读写操作单线程

通常很多人都说Reids是单线程的,其实这句话不够严谨,从严格意义上来讲Redis并不是单线程,Redis的单线程指的是:Redis的网络IO和相关键值对的读写操作是单线程的。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,还是有其他的线程完成的。

为什么Redis的读写会采用单线程操作,具体原因如下:

  • 1.多线程需要进行上下文的切换,而基于单线程无需进行上下文切换,节省CPU性能开销
  • 2.多线程会存在资源共享和并发问题,为了解决问题就会引入锁进制来进行保护,那么会降低系统代码的易调试性和可维护性。而基于单线程我们无需考虑这些问题。

基于内存实现

内存读写比比磁盘读写快10倍以上。而Redis是基于内存实现,相对于数据存在磁盘的数据库,节省磁盘磁盘I/O的消耗,所以速度很快。

高效的数据结构

Redis 的底层数据结构一共有6种,分别是,简单动态字符串,双向链表,压缩列表,哈希表,跳表和整数数组,它们和数据类型的对应关系如下图所示:

图片.png

例如Redis的List的数据结构存储,当满足以下条件时数据会使用压缩列表存储,否则会采用双向链表存储。 - 1.列表对象保存的所有字符串元素的长度都小于64字节 - 2.列表对象保存的元素数量小于512个。

高性能的IO模型

常见网络IO模型

常见的网络I/O模型分为:同步阻塞式IO、同步非阻塞式IO、 多路复用IO模型、 异步IO。

  • 同步阻塞式I/O:程序用IO调用开始,直到系统调用返回,在这段时间内,进程是阻塞的。直到返回成功后,应用程序开始处理用户空间的缓存区数据.简称BIO模型。

  • 同步非阻塞式I/O:当前连接就变成了非阻塞IO。使用非阻塞模式的IO读写,叫做同步非阻塞IO(None Blocking IO)简称NIO模型。

  • I/O多路复用:同一线程可以监视多个文件句柄,一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作。

  • 异步I/O:用户线程通过系统调用,向内核注册某个IO操作。内核在整个IO操作(包括数据准备、数据复制)完成后,通知用户程序,执行后续的业务操作。

Redis 多路复用I/O模型具体实现

Redis中采用的单线程Reactor网络模型,底层是基于IO多路复用,Redis多路复用具体实现如下:

图片.png

  • 1.内核可同时监听多个监听套接字和多个已连接套接字。
  • 2.一旦内核监听到套接字上有数据返回,就会触发相应的事件,这些事件会被放进一个事件队列,Redis单线程对该事件队列不断进行处理,事件进行处理时,会调用相应的处理函数,及时响应客户端。

所以Redis可以同时处理多个客户端请求,从而提升并发性。

I/O模型缺点

  • 1.一个线程支持处理的连接数非常有限CPU很容易打满,性能方面有明显瓶颈;
  • 2、任意一个请求在server中一旦发生耗时,都会影响整个server的性能,也就是说后面的请求都要等前面这个耗时请求处理完成,自己才能被处理到.

总结

本文从几个方面讲解了Redis为什么这么快,我们需要掌握其相关的原理,才能在使用过程中注意那些操作会影响到Redis的性能。