【问题标题】:why Redis is single threaded(event driven)为什么 Redis 是单线程的(事件驱动)
【发布时间】:2018-01-03 23:28:33
【问题描述】:

我正在尝试了解 Redis 的基础知识。 无处不在的是,Redis 是单线程的,它使事情变得原子化。但我无法想象这是如何在内部工作的。我有以下疑问。

如果是 IO 绑定应用程序(如 Node.js),我们不设计一个服务器单线程,其中线程在启动 IO 操作后获得另一个请求,并在 IO 操作完成后返回数据给客户端(提供并发) .但是在redis的情况下,所有数据都在主内存中可用,我们根本不会做IO操作。那么为什么Redis是单线程的?如果第一个请求花费太多时间会发生什么,剩下的请求必须保持等待?

【问题讨论】:

标签: multithreading redis event-driven single-threaded


【解决方案1】:

TL;DR:单线程让redis更简单,redis还是IO绑定的。

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

除非内存和网络速度突然提高几个数量级,否则单线程通常不是问题。如果您需要扩展超过一个或几个线程(即:主从从设置),您已经在查看 Redis 集群。在这种情况下,如果您因某种原因 CPU 不足并希望最大化线程数,您可以为每个 CPU 内核设置一个集群实例。

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

redis耗时长时其他请求会怎样?

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

【讨论】:

  • 如果我错了,请纠正我。假设 redis 收到两个请求 Req1 IO 绑定(花费太多时间)然后 Req2 来了 Req2 需要很少的 IO 然后 Req2 将立即被服务但是如果 Req1 是 CPU 密集型的(在 Redis 中的一些大列表中搜索) Req2 将不得不等待直到 Req1 没有完成。
  • @carl 很好,很正确 - 请看我的附录(或者也许是新时代的前奏?)
  • @Nishat 你是对的,但这可能会在未来的版本中改变
【解决方案2】:

当然,正确的答案是卡尔的。但是。

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

【讨论】:

  • 也就是说,一个运行时间很长的请求有可能允许其他请求同时运行。
猜你喜欢
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 2010-12-25
  • 1970-01-01
  • 2017-05-28
  • 2020-05-29
  • 1970-01-01
相关资源
最近更新 更多