面试回答Redis是单线程的所以很快,让我回去等通知...

数据库 其他数据库
所以Redis之所以快,并不是仅仅因为它使用了单线程模型,还得益于它高效的数据结构、内存的高效使用、I/O多路复用、网络优化以及持久的机制等多方面的因素。

今天给大家分享一下Redis为什么速度这么快的原因,之前有一个小伙伴对Redis的内核原理掌握的一知半解,跟我们说出去面试的时候,面试官问他为什么Redis速度这么快,结果他就说一个Redis是单线程的,回答的非常简单。

结果呢,自然面试官是非常的不满意了,后来随便问了几个问题就让他走了回去等通知了,实际上也不能说回答的就不对,但是必须要说的是,人家问你redis为什么快,结果你就回答一个因为是单线程,那肯定回答的是很不好,而且很不全面!!!

因为redis的超高性能决定了他能抗超高并发,不知道大家能否理解这里的关系?比如说我现在有一个线程来处理请求,一个请求需要耗费100ms,那我一秒也就处理10个请求,对不对?那如果我一个请求耗费1ms呢?我每秒可以处理1000个请求对不对?那如果我一个请求只要微秒级呢,比如就0.1ms,或者0.01ms呢?

是不是我就可以每秒处理了10000个请求,甚至10w个请求了?这是不是就可以高并发了?所以大家可以记住一个关键点,高性能并不一定是为了高并发去做的,但是如果你要实现高并发是肯定要高性能的!

哪怕你是开多线程,甚至是开多个虚拟线程,协程等,你确实可以n多并发请求一起处理,但是只要你每个请求处理太慢了,那一定是歇菜,最后你的实际并发处理能力还是会拉下来的!所以大家往往都知道redis是高性能而且高并发的,但是对这个底层的原理一定要能够全面的掌握,出去面试聊到redis,要全面的把redis说清楚!

下面我们就来系统性的分析一下redis为什么会这么快?

一、Redis的单线程模型

首先,我们要明确一点,Redis确实是单线程的。但这并不意味着Redis就只有一个线程在工作。实际上,Redis的工作模型是基于事件的,它使用了一个主线程来处理所有的客户端请求,而其他的后台线程则负责数据的持久化、客户端连接的管理等任务。

Redis的单线程模型简化了数据结构的访问和修改操作,避免了多线程环境下的竞态条件、线程切换和锁的开销。这使得Redis在执行命令时能够保持极高的效率。

所以聊到redis很快的时候,单线程模型是没问题的,确实是单线程在处理所有的请求,而且走了一个io多路复用,所以可以一个线程监听和处理大量客户端并发发过来的请求,但是大家可以考虑一下,正如上面我们说的,如果你要高并发的话,是不是你每个请求的处理速度要超快?基本上就得在0.1ms这个级别,然后才能单机轻松每秒上万并发,对不对?

所以,其实redis速度超快的一个核心原因,还在于他所有的操作都是基于内存来做的!也就是说redis可以认为是一种基于内存的kv数据库,当然你也可以认为他是一种缓存系统,但是其实把他内存kv数据库也是没问题的!

所以正是因为他是基于内存的,所以redis 6.0以前都是用的是单线程工作模型,一个线程io多路复用监听所有客户端的请求,然后自己处理请求,基于内存做数据操作,单线程模型好处就在于不用对内存数据结构加锁了,避免了加锁同步的等待开销,进一步提升了性能,否则多线程模型还要频繁对内存数据结构加锁串行,也很影响性能!

不过要注意的事redis 6.0以后引入了多线程模型,但是在redis 6.0以前主要还是单线程模型为主的!

二、高效的数据结构

接着上面说,Redis之所以快,除了单线程模型外,还得益于它使用了一系列高效的内存里的数据结构。Redis的每种数据类型都有其特定的数据结构来支持,这些数据结构不仅优化了内存的使用,还提高了数据操作的效率。

例如,Redis的字符串类型使用了SDS(Simple Dynamic String)来存储,这种数据结构不仅能够动态地扩展和缩减内存,还能减少内存的碎片化。而列表类型则使用了双向链表或压缩列表来实现,这使得列表的插入和删除操作都能在O(1)的时间复杂度内完成。

正是有一堆高效设计的内存数据结构,所以redis基于内存数据结构实现数据操作的时候,效率非常的高!

三、内存的高效使用

那既然Redis是一种基于内存的数据库,它的所有数据都存储在内存中。相比于磁盘I/O操作,内存访问的速度要快得多。而Redis在内存使用上也做了很多优化。

首先,Redis使用了一种叫做“内存分配器”的东西来管理内存的分配和释放。这个内存分配器能够根据数据的大小和类型来动态地调整内存的使用,减少了内存的浪费。

其次,Redis还使用了一种叫做“LRU(Least Recently Used)”的算法来淘汰长时间未访问的数据,这保证了内存的有效利用。

说白了就是redis为了保证高性能,一个单线程模型避免并发同步加锁,一个基于内存来高速操作,一个就是对内存的使用在内存数据结构和内存分配管理上做了深度优化,这些决定了redis的超高性能。

四、I/O多路复用

Redis使用了I/O多路复用技术来处理客户端的请求。这意味着Redis能够同时监听多个客户端的连接,并在有数据可读或可写时立即进行处理。这种技术使得Redis能够高效地处理大量的并发连接,而不需要为每个连接都创建一个线程或进程。这不仅减少了线程切换的开销,还提高了系统的吞吐量。

这个其实也很关键,因为redis速度要快,那么就必须可以一个线程同时监听大量的客户端连接的请求,这样大量客户端请求并发过来,一个线程才可以快速的轮询所有请求,每个请求都快速的 基于内存在0.1ms量级以内快速完成,甚至是0.01ms量级,这样就可以在每秒轻松处理1w甚至几万,十万个请求了!

五、网络优化

Redis在网络方面也做了很多优化来提高性能。首先,Redis使用了TCP/IP协议来进行网络通信,这使得数据的传输更加稳定和高效。

其次,Redis还使用了一种叫做“Pipeline”的技术来减少网络往返次数。通过Pipeline,客户端可以将多个命令一次性发送给Redis服务器,并由服务器一次性返回结果,这大大降低了网络延迟。

六、持久化机制

虽然Redis是一种基于内存的数据库,但它也提供了持久化的机制来将数据保存到磁盘上。Redis的持久化主要有两种方式:RDB和AOF。

RDB是一种快照式的持久化方式,它会在指定的时间间隔内将内存中的数据写入到磁盘上。而AOF则是一种追加式的持久化方式,它会将每个写操作都追加到文件的末尾。

这两种持久化方式都可以保证数据的可靠性,并且在恢复数据时也非常高效。

这个持久化的机制也很关键,因为他决定了redis可以把内存数据持久化到磁盘,也决定了redis不光是做缓存,还可以做kv数据库,而且基于后台线程异步持久化也可以保证redis纯内存操作,进一步确保了redis速度很快。

七、总结

所以Redis之所以快,并不是仅仅因为它使用了单线程模型,还得益于它高效的数据结构、内存的高效使用、I/O多路复用、网络优化以及持久的机制等多方面的因素。在未来的学习和工作中,我们要更加注重对技术细节的深入探究和理解,不断提高自己的技术水平。同时,我也希望这篇文章能够帮助到那些对Redis感兴趣的朋友们,让我们一起在技术的道路上不断前行!

责任编辑:武晓燕 来源: 石杉的架构笔记
相关推荐

2021-08-10 07:00:01

Redis单线程并发

2022-07-18 13:59:43

Redis单线程进程

2020-10-26 08:55:52

Redis单线程模型

2019-06-17 14:20:51

Redis数据库Java

2022-01-04 11:11:32

Redis单线程Reactor

2019-05-06 11:12:18

Redis高并发单线程

2022-11-16 17:10:25

MySQL数据事务

2009-07-10 09:05:20

SwingWorker

2024-08-05 01:26:54

2023-10-15 12:23:10

单线程Redis

2020-10-16 16:00:50

Redis单线程数据库

2019-11-25 10:13:52

Redis单线程I

2024-02-26 12:38:21

MySQLInnoDB跨度

2024-09-27 11:51:33

Redis多线程单线程

2021-12-28 09:50:18

Redis单线程高并发

2019-05-07 09:44:45

Redis高并发模型

2021-06-11 11:28:22

多线程fork单线程

2020-12-02 06:12:27

TCPIP面试

2020-10-30 16:20:38

Redis单线程高并发

2020-06-11 09:35:39

Redis单线程Java
点赞
收藏

51CTO技术栈公众号