微信号:infoqchina

介绍:有内容的技术社区媒体

Node.js V0.12新特性之Cluster轮转法负载均衡

2014-03-19 17:48 InfoQ

Node核心代码的提交者Ben Noordhuis和Bert Belder会写一系列的文章来介绍Node 0.12的新特性,大概会有7到8篇的样子。在这第一篇文章中,Ben会讲一讲新的轮转法集群算法。


回顾Node内置的cluster模块


Node.js固有的单线程模型经常被认为是它的一个软肋。不管你的机器上有多少CPU内核,Node.js能用上的也仅仅是其中之一(某些操作会被有条件地卸载到线程池中。大多数程序只是在CPU的总时间上分了一杯羹,所以更好地利用可用的处理能力并不能起到多大作用)。


所以Node.js从v0.8开始,新增加了一个内置的‘cluster’模块。你可以用cluster模块设置一个主进程作为管理者,由一或多个工人进程完成实际工作。


让创建“发完就忘”的多进程服务器变得更容易是其目标之一。在完美的世界中,你应该可以一行代码都不用改,就能让一个已有的单进程程序繁衍出任意多的工人进程。


当然,事情不可能那么容易,但对于没有共享状态,或共享状态很少,或把共享状态存放在数据库或Web服务之类的外部资源中的程序而言,cluster模块的确让这件事变得简单直接了。


cluster模块最神奇之处在于所有工人线程都可以绑定到相同的请求处理端口和地址上。另外,它可以确保接进来的连接会被均匀地分配给监听着的工人线程...最起码理论上是这样的。


Node.js v0.8和v0.10中分配连接的算法很简单。当工人进程调用http.Server#listen()或net.Server#listen()时,Node.js会给主进程发送一条消息,让它创建一个服务器socket,绑定好,并分享给这个工人进程。如果已经有绑定好的socket了,主进程就会跳过“创建和绑定”那一步,只需分享已有的socket就可以了。


也就是说所有的工人进程监听的都是同一个socket。有新连接进来时,操作系统会唤醒一个工人进程。被唤醒的工人进程就会接受连接,开始提供服务。


一切都还不错。操作系统会针对运行中的进程收集大量的指标,所以应该最有资格决定唤醒哪个进程。


用现实检验理论


现在,我们进入了理论与杂乱的现实相遇的环节,因为它慢慢地水落石出了,操作系统并不能总是跟程序员想得一样做到‘最好’。特别是在某些情况下,我们观测到——特别是在Linux和Solaris中——大多数连接最终都落在了两或三个进程里。


从操作系统的角度来看这是可以理解的:上下文切换(挂起一个进程,然后重新激活另一个)是相当昂贵的操作。如果你有n个进程全都等在同一个socket上,那么唤醒最近被阻塞的进程是明智之举,因为那样可以最大限度地避免上下文切换。(当然,调度器是一种复杂而又多变的野兽;上面只是对真实情况泛泛的解释。基本前提是那些得到优待的进程会仍然受到优待)。


并不是所有的程序都会受到这个怪癖的影响,实际上大多数都不会,但那些确实会受到影响的会出现非常不均衡的负载。


一旦确定了根本原因,缓解措施就可以用上了。但还没有特别令人满意的。比如暂时放弃监听socket以便让其它工人进程有机会接受新连接,这有点儿用,但还不够。‘选定几个’中的连接数从90%下降到了60-70%,有改善,但还是不够好。更别提它对那些要处理非常短命的连接的程序的剧烈影响了。


更重要的是,我们清楚地意识到,就像随机数的生成一样,接入连接的分配太重要了,不能靠运气。经过多次讨论,我们达成了共识——我们最后,也是最好的希望是可以简单地抛弃目前的做法,切换到完全不同的东西上。这就是Node.js v0.11.2中的cluster模块换成了round-robin方式的原因,新连接由主进程接受,然后由它选择一个工人进程把连接交出去。


现在这个选择工人进程的算法还不是特别精巧。就像它的名字一样,它用的是轮转法——只是拿起下一个可用的工人进程——但经过核心开发人员和用户的测试,证明它很好用:连接在工人进程之间分配得很均衡。我们正在考虑将选定的算法变成可以由开发人员配置或插入的东西。


更多细节和注意事项请点击“阅读原文”。


***********************************

本文来自InfoQ微信公众账号:infoqchina

1、回复“今日新闻”,查看今天更新的新闻;

2、回复“今日英文”,查看今天英文站的更新;

3、回复“文章 +关键词”,搜索关键词相关内容;

4、回复“QCon”,了解QCon大会相关信息;

5、回复“活动”,了解最近InfoQ组织的线下沙龙;

6、回复“架构师”,获取《架构师》下载地址;

7、回复“投稿”,了解投稿和加入编辑团队的流程。

***********************************

 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 百分比布局支持库 Android 开发常用接口 Python基础教程3:基础语法 写好一份数据分析报告的13个要点 为什么女程序媛会这么少?