213

试图掌握 Redis 的一些基础知识时,我偶然发现了一篇有趣的博客文章

作者指出:

Redis 是带有 epoll/kqueue 的单线程,并且在 I/O 并发方面可以无限​​扩展。

我肯定误解了整个线程的事情,因为我觉得这个说法令人费解。如果一个程序是单线程的,它如何同时做任何事情?如果服务器无论如何都是单线程的,为什么 Redis 操作是原子的如此之好?

有人可以解释一下这个问题吗?

4

2 回答 2

413

好吧,这取决于您如何定义并发。

在服务器端软件中,并发和并行通常被认为是不同的概念。在服务器中,支持并发 I/O 意味着服务器能够通过执行与这些客户端相对应的多个流程来为多个客户端提供服务,而这些客户端只有一个计算单元。在这种情况下,并行性意味着服务器能够同时执行几件事(使用多个计算单元),这是不同的。

例如,调酒师可以照顾几位顾客,而他一次只能准备一种饮料。所以他可以在没有并行的情况下提供并发。

这个问题已经在这里进行了辩论: 并发和并行之间有什么区别?

另请参阅Rob Pike 的此演示文稿

通过使用 I/O (de)multiplexing 机制和事件循环(Redis 就是这样做的),单线程程序绝对可以在 I/O 级别提供并发性。

并行性是有代价的:使用现代硬件上可以找到的多个插槽/多个内核,线程之间的同步非常昂贵。另一方面,像 Redis 这样的高效存储引擎的瓶颈通常是网络,远在 CPU 之前。因此,隔离的事件循环(不需要同步)被视为构建高效、可扩展的服务器的好设计。

Redis 操作是原子的这一事实仅仅是单线程事件循环的结果。有趣的一点是原子性是免费提供的(它不需要同步)。用户可以利用它来实现乐观锁定和其他模式,而无需支付同步开销。

于 2012-05-08T08:51:51.943 回答
24

好的,Redis 在用户级别是单线程的,OTOH,内核线程池和/或拆分级别驱动程序支持所有异步 I/O。

对某些人来说, “并发”包括将网络事件分发到套接字状态机。它是单线程的,在一个核心上运行(在用户级别),所以我不会将其称为并发。其他的不一样。。

'在 I/O 并发方面无限扩展'实际上是经济实惠的。如果他们说“可以比每个客户端一个线程更好地扩展,前提是客户要求不高”,他们可能会更有信心,尽管他们可能会觉得有必要添加“其他异步解决方案的繁重负载”在用户级别使用所有核心'。

于 2012-05-07T21:34:27.970 回答