2012-09-19 18 views
8

我读集群模块的文档中的Node.js:
http://nodejs.org/api/cluster.html操作系统如何在接受同一套接字的多个进程之间进行负载平衡?

它声称如下:

当多个进程荷兰国际集团相同的底层 资源的所有accept(),该操作系统在它们之间的负载平衡非常有效。

这听起来很有道理,但即使是一对夫妇的谷歌搜索了几个小时之后,我还没有发现在所有的物品或东西会确认,或解释如何负载平衡逻辑在操作系统中工作。

此外,什么操作系统正在做这种有效的负载平衡?

+0

我想你找不到任何与之相关的东西,因为js不应该依赖于操作系统。我不知道为什么该文档提及操作系统,也许它将Chrome视为操作系统。 – jondinham

+0

感兴趣的,https://www.citi.umich.edu/u/cel/linux-scalability/reports/accept.html –

+1

@Paul - Node.js是一个服务器端框架,它不在浏览器中运行。 – Venemo

回答

9

“负载均衡”可能有点糟糕的选择,本质上它只是一个问题,操作系统如何选择唤醒和/或下一次运行哪个进程。一般来说,进程调度器试图根据标准来选择进程,例如给予相同优先级的进程的cpu时间的平等份额,cpu /内存局部性(不要在cpu周围反弹进程)等等。无论如何,通过使用google搜索你会发现大量的东西来阅读关于进程调度算法和实现。

现在,对于accept()的特殊情况,这也取决于操作系统如何实现唤醒等待accept()的进程。

  • 一个简单的实现是刚睡醒挡在了接受()调用每一个过程,然后让调度选择他们得到运行的顺序。

  • 以上内容很简单,但会导致“雷鸣群”的问题,因为只有第一个进程成功接受连接,其他进程才会回到阻塞状态。更复杂的方法是操作系统只唤醒一个进程;在这里可以通过询问调度器来选择唤醒哪个过程,或者例如只需在blocking-on-accept() - for-this-socket列表中选择第一个进程即可。后者是Linux自十年或更早以来所做的,基于已由其他人发布的link

  • 请注意,这只适用于阻止accept();对于非阻塞accept()(我确信node.js正在做的是什么),问题变成了select()/ poll()/哪些事件传递给哪个进程。 poll()/ select()的语义实际上要求它们都被唤醒,所以你再次遇到雷鸣的问题。对于Linux,也可能以类似方式使用其他具有系统特定高性能轮询接口的系统,可以通过使用单个共享epoll fd和边缘触发事件来避免雷鸣般的畜群。在这种情况下,事件将仅传递给epoll_wait()上阻塞的进程之一。我认为,与阻塞accept()类似,传递事件的过程的选择仅仅是在epoll_wait()阻塞的特定epoll fd的进程列表中选择第一个进程。

所以至少为Linux,既为与边缘阻挡接受()和非阻挡接受()触发epoll的,没有调度每选择来唤醒该方法时本身。但是OTOH,工作负载可能会在进程之间相当平衡,因为本质上系统会按照完成当前工作的顺序循环进程,并回到epoll_wait()的阻塞状态。

+0

太棒了,谢谢你的解释。所以基本上,这是否意味着不是实现任何负载平衡,而是仅仅相信内核通过将新连接提供给最不繁忙的进程来“做正确的事情”? – Venemo

+0

@Venemo:基本上,是的。 – janneb

+0

谢谢!我正在将此标记为已接受的答案! :) – Venemo

相关问题