Redis 到底是单线程还是多线程?

转载:https://www.cnblogs.com/javastack/p/12848446.html
其他文章:http://shangdixinxi.com/detail-1502161.html

这个问题你要从多个方面回答,如果你仅仅只回答 “单线程” 肯定是说不过去的,为什么呢?

Redis 单线程到底指什么?

没错,大家所熟知的 Redis 确实是单线程模型,指的是执行 Redis 命令的核心模块是单线程的,而不是整个 Redis 实例就一个线程,Redis 其他模块还有各自模块的线程的。

下面这个解释比较好:
在这里插入图片描述Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。
因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。

Redis 不仅仅是单线程

一般来说 Redis 的瓶颈并不在 CPU,而在内存和网络。如果要使用 CPU 多核,可以搭建多个 Redis 实例来解决。其实,Redis 4.0 开始就有多线程的概念了,比如 Redis 通过多线程方式在后台删除对象、以及通过 Redis 模块实现的阻塞命令等。

在redis6.0后:
在这里插入图片描述**这个 Theaded IO 指的是在网络 IO 处理方面上了多线程,**如网络数据的读写和协议解析等,需要注意的是,执行命令的核心模块还是单线程的。

所以,你要是再把 Redis 6.0 网络处理多线程这块回答上了,你也不至于 “请回” 了。

为什么网络处理要引入多线程?
之前的段落说了,Redis 的瓶颈并不在 CPU,而在内存和网络。

内存不够的话,可以加内存或者做数据结构优化和其他优化等,但网络的性能优化才是大头,网络 IO 的读写在 Redis 整个执行期间占用了大部分的 CPU 时间,如果把网络处理这部分做成多线程处理方式,那对整个 Redis 的性能会有很大的提升。

目前最新的 6.0X 版本中,IO 多线程处理模式默认是不开启的,需要去配置文件中开启并配置线程数

### Redis 线程模型概述 Redis 的线程模型经历了从单线程到部分多线程的发展过程。早期版本中,Redis 主要依赖于单线程架构来处理所有的操作,而自 Redis 6.0 版本起,则引入了多线程支持以提升特定场景下的性能。 #### 单线程工作原理 在单线程模式下,Redis 使用事件循环机制来管理客户端连接、命令执行以及持久化等任务。这种设计使得所有操作都在同一个进程中顺序完成,从而简化了程序逻辑并减少了竞争条件的发生概率[^1]。 具体来说: - **事件驱动**:通过 epoll 或 kqueue 实现高效的 I/O 复用; - **命令排队**:当有新的请求到来时会被加入队列等待被处理; - **串行执行**:每次仅有一个命令被执行,确保原子性和一致性。 由于大多数情况下 Redis 的瓶颈并不在于 CPU 计算能力而是内存访问速度或磁盘 I/O 效率,因此即使是在高负载环境下也能够保持良好的响应时间[^3]。 然而,面对某些特殊情况如大键(big key)的操作或是网络延迟较大的情况,单线程可能会成为性能瓶颈之一[^5]。 ```python import redis client = redis.Redis(host='localhost', port=6379) def single_threaded_operation(): client.set('foo', 'bar') value = client.get('foo') print(value.decode()) ``` #### 部分多线程的工作方式 到了 Redis 6.0 及以后的版本,为了应对日益增长的数据量和更高的吞吐需求,官方团队决定对原有的单线程结构做出调整,在保留原有优势的基础上增加了多线程的支持[^4]。 新特性主要表现在以下几个方面: - **I/O 多线程**:利用多个辅助线程专门负责接收来自不同客户端的消息包,并将其转换成内部可以识别的形式后再交给主线程进一步处理; - **后台任务异步化**:像 AOF 日志重写这样的耗时较长的任务也可以由独立的工作进程承担而不影响前台业务正常运转; - **文件描述符分配优化**:改进后的算法允许更加灵活地控制资源配给,提高了整体稳定性与可靠性。 值得注意的是,尽管引入了一定程度上的并发性,但对于具体的数据库读取/修改指令而言依旧维持着原来的同步调用链路不变,即仍然遵循先来后到的原则依次进行解析计算[^2]。 ```python from concurrent.futures import ThreadPoolExecutor, as_completed executor = ThreadPoolExecutor(max_workers=8) futures = [] for i in range(10): futures.append(executor.submit(client.incr, f'counter_{i}')) results = [future.result() for future in as_completed(futures)] print(results) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值