为了掌握一些Redis的基础知识,我看到了一篇有趣的博客文章。

作者说:

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

我当然误解了整个线程的事情,因为我发现这个声明令人费解。如果一个程序是单线程的,它如何并发地做事情?如果服务器是单线程的,那么为什么Redis操作是原子的呢?

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


当前回答

这取决于你如何定义并发性。

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

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

这里讨论了这个问题: 并发和并行的区别是什么?

还有罗伯·派克的演讲。

单线程程序可以通过使用I/O多路复用机制和事件循环(这就是Redis所做的)在I/O级别上提供并发性。

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

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

其他回答

这取决于你如何定义并发性。

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

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

这里讨论了这个问题: 并发和并行的区别是什么?

还有罗伯·派克的演讲。

单线程程序可以通过使用I/O多路复用机制和事件循环(这就是Redis所做的)在I/O级别上提供并发性。

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

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

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

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

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