Redis 单线程原理

Redis 使用单线程处理命令,通过辅助线程处理阻塞操作,提高性能。单线程避免了复杂的锁机制和上下文切换,但限制了耗时操作。Redis 通过内存数据库、高效数据结构、多路复用网络模型等优化实现快速响应。数据组织方式采用哈希表,负载因子控制扩容缩容,渐进式重分布减少对主线程的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis 是不是单线程 ?

在这里插入图片描述

  • redis 单线程指的是命令处理在一个单线程中
  • 主线程:redis-server → 命令处理、网络事件的监听
  • 辅助线程
    • bio_close_file:异步关闭大文件。
    • bio_aof_fsync:异步 aof 刷盘。
    • bio_lazy_free:异步清理大块内存。
    • jemalloc_bg_thd:后台线程,进行内存分配,内存释放。
    • io_thd_*IO 多线程,负责 read / writedecode / encode
  • 辅助线程负责处理阻塞的操作,这样可以不阻塞主线程,让主线程最大限度地处理命令,优化性能。

命令处理为什么是单线程 ?

  • 为什么不采用多线程
    • redis 有多个对象类型,每个对象类型又有多种数据结构的实现,导致加锁复杂、锁粒度不好控制(操作临界资源所需要的时间)
    • 频繁的 CPU 上下文切换,抵消多线程的优势
  • 单线程的局限:不能有耗时的操作,比如 CPU 运算、阻塞的 IO,会影响 redis 的响应性能。
  • redis 处理 IO 密集型:
    • 磁盘 IO
      • fork 进程,在子进程做持久化。
      • 使用 bio_aof_fsync,另起线程做持久化(异步 aof 刷盘)。
    • 网络 IO
      • 服务多个客户端,造成 IO 密集;数据请求或返回数据量比较大。
      • 开启 IO 多线程。
  • redis 处理 CPU 密集型:
    • 数据结构切换:redis 会根据当前数据量的大小,选择一个数据结构去存储。
    • 渐进式数据迁移:当数据量小的时候,会分配一个小的内存,当数据量大的时候,会分配一个大的内存(翻倍扩容),那么就需要将原来内存中的数据迁移到新的内存中,redis 不会将原数据一次性都挪过去,而是采用一定的策略逐渐挪过去。

redis 单线程为什么快 ?

  • 采用哪些机制:
    • redis 是内存数据库,大部分情况下:操作完内存后会立刻返回给客户端,不需要关注写磁盘的问题。特殊情况:使用 aof 持久化方式 + always 策略:每一次操作完内存后,都必须持久化到磁盘中,然后再返回给客户端
    • 数据结构高效:在执行效率与空间占用间保持平衡,可以进行数据结构切换。
    • 采用高效的 reactor 网络模型:IO 多路复用 + 非阻塞 IO
  • 做了哪些优化:
    • 耗时阻塞的操作,另起线程处理
      • 异步关闭大文件。
      • 异步释放大内存块。
      • 异步 aof 刷盘。
      • IO 多线程。
    • 将大的操作拆分成小的操作
      • dict 渐进式 rehash

redis 数据组织方式:

typedef struct redisDb {
   
	dict *dict; // 存储所有的 key 和 value
	dict *expires; // 存储所有过期的 key
	dict *blocking_keys; // 存储阻塞连接的 key
	dict *ready_keys; 
	dict *watched_keys; // 被检测的 key ( MULTI/EXEC )
}

struct dict {
   
	dictType *type;
	
	dictEntry **ht_table[2];
	unsigned long ht_used
### Redis 单线程模型原理 Redis单线程模型并非完全意义上逐个执行请求的传统方式,而是通过事件驱动机制 I/O 多路复用技术实现了高效的并发处理能力[^1]。具体来说,Redis 将所有的客户端连接注册到一个事件循环中,当某个连接上有数据可读或者可以写入时,I/O 多路复用会通知主线程去处理这些操作。 这种设计的核心在于利用操作系统提供的 epoll/kqueue 等接口来管理多个文件描述符上的事件监听,从而让单线程能够在不阻塞的情况下快速响应大量的网络请求。 ### 性能分析 #### 优点 1. **高效率** Redis单线程架构避免了多线程环境下的上下文切换以及锁竞争等问题,极大地减少了系统开销并提升了运行效率[^3]。 2. **简单性稳定性** 单线程的设计简化了程序逻辑,降低了开发复杂度的同时增强了软件的稳定性可靠性。因为不存在多线程间的资源争抢情况,所以更容易预测行为模式并且调试起来更加方便。 3. **低延迟特性** 对于大多数内存级存储场景而言,CPU 并不是瓶颈所在;而磁盘 IO 或者网络传输才是主要耗时环节。因此,在这样的前提条件下,即使只有一个工作线程也可以达到非常高的吞吐率,并保持较低的服务端响应时间。 #### 缺点 尽管如此,仍然存在一些局限性: 1. **计算密集型任务受限** 如果某些命令涉及复杂的 CPU 计算(比如 `SORT`),那么整个服务器可能会被长时间占用而导致其他请求得不到及时服务。这表明对于那些需要大量运算的操作,Redis 可能表现不佳[^2]。 2. **扩展性有限** 随着硬件设备向多核方向发展迅速,仅依赖单一核心工作的 Redis 显得有些不合时宜。虽然自版本 4.0 开始引入了一些基于多线程的功能改进措施,但在整体上依旧维持着以单线程为主导的工作流程。 ```python import redis # 创建 Redis 连接池实例 pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) # 设置键值对 r.set('foo', 'bar') # 获取键对应的值 value = r.get('foo') print(value) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值