为什么说Redis是单线程?为什么Redis这么快?

大家好,我是一安,Redis是面试中绕不过去的槛,下面就做个介绍说明

Redis简介

Redis 是完全开源免费的, 遵守 BSD 协议, 是一个高性能的 key-value 数据库。

Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

Redis 不仅仅支持简单的 key-value 类型的数据, 同时还提供 list, set, zset, hash 等数据结构的存储

Redis 支持数据的备份, 即 master-slave 模式的数据备份。

Redis 读写性能优异,读的速度是 110000 次/s,写的速度是 81000 次/s 。

Redis为什么这么快

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用非阻塞的I/O多路复用模型;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

以上几点都比较好理解,针对单线程和多路 I/O 复用模型进行简单的探讨:

单线程

指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程。

多路I/O复用

I/O是网络I/O;多路是多个TCP连接(socket或channel);复用是指负责一个或多个线程。

为什么说Redis是单线程?为什么Redis这么快?客户端,产生多个不同操作的socket请求。

服务端,I/O多路复用器会把消息放入队列,然后通过文件事件分派器,转发到不同的事件处理中。

客户端与Redis一次通讯流程解释图:

为什么说Redis是单线程?为什么Redis这么快?

注意:由于redis处理请求单线程,所有不要在生成环境执行耗时命令,如keys *、flushall、flushd

题外话:

有小伙伴说Redis6.0引入了多线程

这里引入多线程主要是为了提高网络IO读写性能,读写网络的read/write系统调用占用了Redis执行期间大部分CPU时间,瓶颈主要在于网络的IO消耗(还有一个瓶颈是内存),但执行命令仍然是单线程顺序执行。

Redis6.0的多线程默认是禁用的,只使用主线程,并且建议只在4核以及更多核心的机器上开启。如需开启需要修改配置文件redis.conf的io-threads-do-reads=true。开启多线程后,还需要设置线程数,否则是不生效的,同样需要设置配置文件 redis.conf的io-threads属性,4核的机器建议设置为2或3个线程,8核的建议设置为6个线程。

多线程之后的请求处理流程:

  • 主线程仍然是负责接收连接请求,并负责监听各种事件。
  • 读事件(收到请求)到来时,主线程会将该Socket加入一个等待队列,队列满了之后会将队列中的Socket通过Round Robin算法(RR)分配给IO线程组中的线程,Socket和对应的IO线程绑定。
  • 此后主线程等待IO线程组将Socket中的请求数据读取并解析完成(这里只是读数据和解析,并不执行);
  • 如果所有的Socket都读取完毕,那么主线程按照队列顺序依次执行所有命令,保证执行命令时是单线程的。
  • 命令执行完毕之后,再次阻塞等待所有的IO线程组将数据写回Socket完毕,最后主线程中解除Socket和IO线程的绑定。
    为什么说Redis是单线程?为什么Redis这么快?
    详细流程解释图:
    为什么说Redis是单线程?为什么Redis这么快?

    特点:

    IO 线程要么同时在读 socket,要么同时在写,不会同时读或写

    IO 线程只负责读写 socket 解析命令,不负责命令处理


总结

Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器(file event handler)。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。

  • 文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
  • 当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时, 与操作相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

虽然文件事件处理器以单线程方式运行, 但通过使用 I/O 多路复用程序来监听多个套接字, 文件事件处理器既实现了高性能的网络通信模型, 又可以很好地与 redis 服务器中其他同样以单线程方式运行的模块进行对接, 这保持了Redis 内部单线程设计的简单性。

至于速度快,因为数据存在内存中,所以快为什么说Redis是单线程?为什么Redis这么快?

号外!号外!

如果这篇文章对你有所帮助,或者有所启发的话,帮忙点赞、在看、转发、收藏,你的支持就是我坚持下去的最大动力!

为什么说Redis是单线程?为什么Redis这么快?

Redis缓存失效问题:缓存穿透-缓存雪崩-缓存击穿


实际开发中,如何保证数据库和缓存双写一致性


实现多数据源切换(读写分离经典案例)


为什么说Redis是单线程?为什么Redis这么快?


原文始发于微信公众号(一安未来):为什么说Redis是单线程?为什么Redis这么快?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/44751.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!