为了掌握Redis的一些基础知识,我遇到了一篇有趣的博客文章。
作者指出:
Redis是带有epoll / kqueue的单线程,并且在I / O并发方面可以无限扩展。
我肯定会误解整个线程问题,因为我发现此语句令人困惑。如果程序是单线程的,它如何并发执行任何操作?如果服务器仍然是单线程的,为什么Redis操作是原子的那么好呢?
有人可以阐明这个问题吗?
为了掌握Redis的一些基础知识,我遇到了一篇有趣的博客文章。
作者指出:
Redis是带有epoll / kqueue的单线程,并且在I / O并发方面可以无限扩展。
我肯定会误解整个线程问题,因为我发现此语句令人困惑。如果程序是单线程的,它如何并发执行任何操作?如果服务器仍然是单线程的,为什么Redis操作是原子的那么好呢?
有人可以阐明这个问题吗?
Answers:
好吧,这取决于您如何定义并发。
在服务器端软件中,并发性和并行性通常被视为不同的概念。在服务器中,支持并发I / O意味着服务器能够通过仅使用一个计算单元执行与那些客户端相对应的多个流来为多个客户端提供服务。在这种情况下,并行性意味着服务器能够同时执行多个操作(使用多个计算单元),这是不同的。
例如,调酒师能够照顾几个顾客,而一次只能准备一种饮料。因此,他可以在没有并行的情况下提供并发。
这个问题已经在这里讨论过: 并行和并行之间有什么区别?
另请参见Rob Pike的演示文稿。
通过使用I / O(解复用)机制和事件循环(Redis所做的事情),单线程程序肯定可以在I / O级别上提供并发性。
并行性是有代价的:由于您可以在现代硬件上找到多个插槽/多个内核,因此线程之间的同步非常昂贵。另一方面,像Redis这样的高效存储引擎的瓶颈通常是网络,远早于CPU。因此,孤立的事件循环(不需要同步)被视为构建高效,可伸缩服务器的良好设计。
Redis操作是原子的这一事实完全是单线程事件循环的结果。有趣的一点是原子性是免费提供的(不需要同步)。用户可以利用它来实现乐观锁定和其他模式,而无需支付同步开销。
好的,Redis在用户级别OTOH是单线程的,内核线程池和/或拆分级别的驱动程序支持所有异步I / O。
在某些情况下,“ 并发 ”包括将网络事件分发到套接字状态机。它是单线程的,在一个内核上(在用户级别)运行,因此我不会将其称为并发。其他都不同。
“ 根据I / O并发无限扩展 ”只是说实话。如果他们说“可以提供比每个客户端一个线程更好的扩展能力,只要客户端要求不高”,他们可能会更加相信,尽管他们随后可能会觉得不得不“放弃其他异步解决方案带来的繁重负担”在用户级别使用所有内核”。