【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?-- Redis多线程

简介: 【5月更文挑战第21天】Redis启用多线程后,主线程负责接收事件和命令执行,IO线程处理读写数据。请求处理流程中,主线程接收客户端请求,IO线程读取并解析命令,主线程执行后写回响应。业界普遍认为,除非必要,否则不建议启用多线程模式,因单线程性能已能满足多数需求。公司实际场景中,启用多线程使QPS提升约50%,或选择使用Redis Cluster以提升性能和可用性。

2024-05-22-20-43-21-image.png

你这样介绍整个设计。

当Redis启用了多线程之后,里面的主线程就要负责接收事件、创建连接、执行命令。Redis的IO线程就负责读写数据。

我用一个请求的处理过程来解释一下整个设计。当客户端发出请求的时候,主线程会收到一个可读的事件,于是它把对应的客户端丢掉可读的客户端列表。一个IO线程会被安排读写这个客户端发来的命令,并且解析好。紧接着主线程会执行 IO 线程解析好的命令,并且把响应放回到可写客户端列表里面。IO 线程负责写回响应。整个过程就结束了。 所以整个 Redis 在多线程模式下,可以看作是单线程 Reactor、单线程 Acceptor 和多线程 Handler 的 Reactor 模式。只不过 Redis 的主线程同时扮演了 Reactor 中分发事件的角色,也扮演了接收请求的角色。同时多线程 Handler 在 Redis 里面仅仅是读写数据,命令的执行还是依赖于主线程来进行的。

紧接着你要补充一个业界比较多人认同的观点,就是不到逼不得已不要启用 Redis 多线程模型。

虽然说现在 Redis 的 IO 改成多线程之后能够有效利用多核性能,但是大部分情况下都是不推荐使用多线程模式的。道理很简单,Redis 在单线程模式下的性能就足以满足绝大多数使用场景了,那么用不用多线程已经无所谓了。

接下来,你根据你们公司的实际情况来选择一个回答。第一个回答是介绍你们公司使用了多线程模型。

我司的 Redis 早期的时候就触及了单线程的性能瓶颈,后来在开启了多线程之后,能支撑的 QPS 大概提升了 50%,效果还是很不错的。

你最好在自己公司里面测试一下性能提升的幅度。有些时候面试官可能会问你用了几个线程,你回答公司的实际情况就行。另外一个回答是你们公司没有用多线程模型。

早期我们公司虽然遇到过 Redis 的性能瓶颈,但还是没有启用多线程模型,而是改成了使用 Redis Cluster(或者扩大了 Redis Cluster 规模)。我个人认为,Redis Cluster 一样能够解决性能瓶颈问题,而且相比多线程模式,Redis Cluster 的可用性更好,解决性能问题的效果也更好。

目录
相关文章
|
6月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
310 0
|
6月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
7月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
523 5
|
10月前
|
缓存 NoSQL 中间件
Redis的线程模型
Redis采用单线程模型确保操作的原子性,每次只执行一个操作,避免并发冲突。它通过MULTI/EXEC事务机制、Lua脚本和复合指令(如MSET、GETSET等)保证多个操作要么全成功,要么全失败,确保数据一致性。Redis事务在EXEC前失败则不执行任何操作,EXEC后失败不影响其他操作。Pipeline虽高效但不具备原子性,适合非热点时段的数据调整。Redis 7引入Function功能,支持函数复用,简化复杂业务逻辑。总结来说,Redis的单线程模型简单高效,适用于高并发场景,但仍需合理选择指令执行方式以发挥其性能优势。
275 6
|
11月前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
438 20
|
11月前
|
安全 Java C#
Unity多线程使用(线程池)
在C#中使用线程池需引用`System.Threading`。创建单个线程时,务必在Unity程序停止前关闭线程(如使用`Thread.Abort()`),否则可能导致崩溃。示例代码展示了如何创建和管理线程,确保在线程中执行任务并在主线程中处理结果。完整代码包括线程池队列、主线程检查及线程安全的操作队列管理,确保多线程操作的稳定性和安全性。
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
256 1
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
279 3
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
156 2
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
231 2