Redis是单线程的,那么它如何执行并发I / O?


169

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

作者指出:

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

我肯定会误解整个线程问题,因为我发现此语句令人困惑。如果程序是单线程的,它如何并发执行任何操作?如果服务器仍然是单线程的,为什么Redis操作是原子的那么好呢?

有人可以阐明这个问题吗?

Answers:


359

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

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

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

这个问题已经在这里讨论过: 并行和并行之间有什么区别?

另请参见Rob Pike的演示文稿

通过使用I / O(解复用)机制和事件循环(Redis所做的事情),单线程程序肯定可以在I / O级别上提供并发性。

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

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


135
不错的酒保类比:)
塞尔吉奥·图伦采夫

3
v4在这方面是改变游戏规则的人-请在stackoverflow.com/a/45374864/3160475上查看我的回答:)
Itamar Haber

1
关于答案和比较,我唯一不喜欢的是它使并发似乎无法并行工作,并且可以肯定,因为我可以通过异步运行任务来测试并最终完成工作被认为是并行的。该文章中的并行性是指能够在多线程上运行的多核性质。即为什么提到它是线程安全的。
基督教马修

在2020年仍然有效?
罗伯托·曼弗雷达

21

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

在某些情况下,“ 并发 ”包括将网络事件分发到套接字状态机。它是单线程的,在一个内核上(在用户级别)运行,因此我不会将其称为并发。其他都不同。

根据I / O并发无限扩展 ”只是说实话。如果他们说“可以提供比每个客户端一个线程更好的扩展能力,只要客户端要求不高”,他们可能会更加相信,尽管他们随后可能会觉得不得不“放弃其他异步解决方案带来的繁重负担”在用户级别使用所有内核”。


可能没有上下文,但是每个更新操作(如INCR命令)是否都带有锁?如果有1000个并发请求和一个键(每个请求)上的一个增量操作,是否可以确保变量仅增加1000次?
阿曼达
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.