Linux上是否存在Thundering Herd问题?

时间:2010-02-06 16:30:30

标签: linux scalability

许多linux / unix编程书籍和教程讲的是"Thundering Herd Problem"在select()调用中阻塞多个线程或分叉时发生的情况,等待侦听套接字的可读性。当连接进入时,所有线程和分叉都被唤醒,但只有一个“胜利”并成功调用“accept()”。与此同时,浪费了大量的cpu时间无缘无故地唤醒所有线程/分叉。

我注意到project为linux内核中的这个问题提供了“修复”,但这是一个非常古老的补丁。

我认为有两种变体;一个是每个fork执行select()然后是accept(),另一个执行accept()。

现代unix / linux内核在这两种情况下仍然存在Thundering Herd问题,还是只有“select()then accept()”版本?

4 个答案:

答案 0 :(得分:10)

这是一个非常古老的问题,而且大部分都不存在了。 Linux内核(过去几年)在处理和路由数据包到网络堆栈方面发生了许多变化,并包括许多优化以确保低延迟和公平性(即最小化饥饿)。

也就是说, select 系统仅通过其API就存在许多可扩展性问题。当您拥有大量文件描述符时,select调用的成本非常高。这主要是由于必须构建,检查和维护传入和传出系统调用的FD集。

现在,使用 epoll 进行异步IO的首选方法。 API更简单,并且可以在各种类型的负载(许多连接,大量吞吐量等)上进行非常好的扩展。

答案 1 :(得分:10)

多年来,大多数unix / linux内核序列化对accept(2)s的响应,换句话说,如果多个人在一个打开的文件描述中阻塞accept(2),则只唤醒一个线程。

OTOH,很多(如果不是全部)内核在你所描述的select-accept模式中仍然存在雷鸣般的群体问题。

我编写了一个简单的脚本(https://gist.github.com/kazuho/10436253)来验证问题是否存在,并发现linux 2.6.32和Darwin 12.5.0(OS X 10.8.5)存在问题。 / p>

答案 2 :(得分:2)

我最近看到测试了一个场景,其中多个线程在监听的unix-domain套接字上轮询,然后接受了连接。所有线程都使用poll()系统调用唤醒。

这是linux内核的自定义构建而不是发行版构建,所以可能有一个内核配置选项可以更改它,但我不知道它会是什么。

我们没试过epoll。

答案 3 :(得分:2)

请参阅以下链接,其中讨论epoll的单独标志以避免此问题。

http://lwn.net/Articles/632590/