为什么 Redis 是单线程的(事件驱动)

why Redis is single threaded(event driven)

我正在尝试了解 Redis 的基础知识。 一个随处可见的是,Redis 是单线程的,这使得事情 atomic.But 我无法想象它是如何工作的 internally.I 有以下疑问。

如果它是 IO 绑定应用程序(如 Node.js),我们是否设计一个服务器单线程,其中线程在启动 IO 操作和 return 数据到客户端一次后获得另一个请求的空闲IO操作完成(提供并发)。但是在redis的情况下,所有数据都在主内存中可用,我们不打算在all.So处进行IO操作那么为什么Redis是单线程的?如果第一个请求花费了很多时间会发生什么,剩余的请求将有继续等待?

TL;DR:单线程让redis更简单,redis仍然是IO bound

内存为I/O。 Redis 仍然是 I/O 绑定的。当 Redis 负载很重并达到每秒最大请求数时,它通常缺乏网络带宽或内存带宽,并且通常不会使用很多 CPU。对于某些命令,这不是真的,但对于大多数用例,redis 将受到网络或内存的严重 I/O 限制。

除非内存和网络速度突然提高几个数量级,否则单线程通常不是问题。如果您需要扩展一个或几个线程(即:master<->slave<->slave 设置),您已经在关注 Redis Cluster。在那种情况下,如果您不知何故 CPU 饥饿并且想要最大化线程数,您可以为每个 CPU 核心设置一个集群实例。

我不是很熟悉 redis 源代码或内部结构,但我可以看到使用单线程如何轻松实现无锁原子操作。线程会使这变得更加复杂,并且似乎不会提供很大的优势,因为 redis 不受 CPU 限制。在 redis 实例之上的级别上实现并发似乎是一个很好的解决方案,这也是 Redis Sentinel 和 Redis Cluster 的帮助。

What happens to other requests when redis takes a long time?

当 redis 完成长请求时,其他请求将被阻塞。如果需要,您可以使用 client-pause 命令进行测试。

正确答案当然是卡尔的。然而

在 Redis v4 中,我们看到了从主要 单线程到选择性和谨慎 多线程的转变的开始。模块和线程安全上下文就是其中的一个例子。另外两个是新的UNLINK command and ASYNC mode for FLUSHDB/FLUSHALL。未来的计划是将主事件循环当前正在完成的更多工作(例如 IO 绑定任务)卸载到工作线程。