为什么Twitter不能像Facebook那样通过增加服务器来扩展规模?

52

我一直在寻找twitter为什么需要将其中间件部分从Rails迁移到Scala的解释。是什么阻止了他们通过增加服务器来扩展其用户群,就像Facebook那样呢?更具体地说,Ruby/Rails技术有什么阻碍了Twitter团队采取这种方法吗?


5
据我所知,Twitter并没有用Scala取代RoR。他们将一些组件替换为Scala,但前端仍然是Rails。我想是这样的。去年,我看到了来自Twitter的某位发言人做的演讲,讲述了他们在提高Ruby运行速度方面所做的许多工作。 - Daniel C. Sobral
@luchosrock 那个链接已经失效了,还有其他地方可以找到吗? - Addison
@Addison https://web.archive.org/web/20120102102852/http://canrailsscale.com/ 哈哈哈哈 - luchosrock
7个回答

57
"Rails并非不可扩展,而是使用Ruby(或任何解释型语言)请求“实时”数据不可扩展,因为与编译型语言相比,它们在CPU和内存利用方面更加昂贵。如果Twitter是一种不同类型的服务,具有相同庞大的用户基础,但提供的数据变化较少,则可以通过缓存来使用Rails作为可行选项;即完全避免对Rails堆栈的实时请求,并转移到前端服务器和/或内存数据库缓存。这个主题有一篇优秀的文章:Basecamp Next如何变得如此快。然而,Twitter不仅仅因为扩展问题放弃了Rails,他们之所以转换是因为Scala作为一种语言,提供了关于应用程序状态的某些内置保证,而解释型语言无法提供:如果它能够编译,那么浪费时间的错误,例如打错字、调用不正确的方法、声明不正确的类型等简单不存在。"
Twitter认为TDD并不足够。Scala编程中Dijkstra的一句话表明了这一点:“测试只能证明错误的存在,而不能证明其不存在”。随着应用程序的增长,他们遇到了越来越难以追踪的bug。除了性能问题,神秘之旅正在成为一种阻碍,因此他们进行了转换。根据所有报告,Twitter对Scala的使用是一个极大的成功(尽管Facebook使用自己的超快C++预处理器,所以有点作弊;-))。总之,Twitter由于性能和可靠性方面的考虑进行了转换。当然,Rails往往处于创新前沿,因此世界上99%的非Twitter级别的流量应用程序可以通过解释性语言很好地运行(尽管我现在坚定地站在编译语言的一边,Scala实在太好了!)。

2
让我先说一下,虽然我更偏爱Ruby,但我真的很喜欢Scala。关于Dijkstra和静态类型的优势,我必须转述Rich Hickey的话,他说生产软件中所有的错误都有一个共同点,那就是它们通过了类型检查器和单元测试。顺便说一句:Facebook的HipHop是用C++编写的,而不是C。 - Michael Kohl
1
感谢您,已将Facebook的参考文献从C更改为C++。关于Hickey和错误来源,我完全同意,并且在解释性语言中没有类型检查器,因此必须在Ruby、PHP等单元测试级别上捕获编译语言中不存在的一类错误。展望未来,解释性或编译性语言是否是未来的趋势将是有趣的事情(我怀疑后者),无论如何都会很有趣;-) - virtualeyes
2
@MichaelKohl 嗯,Rich Hickey方便地没有提到所有带有漏洞的程序都有一个共同点:它们没有被证明是正确的。当然,由于他的理论基础是所有程序都有漏洞这一前提,所以这个观点不太适合他的演讲,不是吗? - Daniel C. Sobral
如果您的测试提供了100%的代码覆盖率,那么根据我的经验,拼写错误和其他类似的代码错误可以减少到接近零。我说接近零是因为我相信使用三元运算符可以使覆盖工具指示已覆盖一行,但实际上可能有一个分支没有被覆盖。但是,适当的测试和100%的覆盖率给我带来了与编译代码一样高的舒适度。 - Larry Gebhardt
@virtualeyes,你说的是对的。然而,我们追求100%的覆盖率不仅仅是为了类型检查。我认为类型检查只是额外的好处。这让我在像Ruby这样的语言中编写代码时更加自信。考虑到在编译语言中仍应该有100%的测试覆盖率,你可以说编译器的类型检查是多余的。 - Larry Gebhardt
显示剩余9条评论

11

没有任何平台可以在处理瞬息万变的复杂数据集的同时无限扩展。语言和基础设施很重要,但是您构建网站和数据访问模式的方式更为重要。

如果您曾经玩过像《运输大亨》或《拓荒者》这样需要运输资源的游戏,您就会知道随着使用量的增加,您需要不断升级基础设施。

像Facebook和Twitter这样的平台的扩展是永无止境的任务。您有越来越多的用户,并且被迫添加更多功能和功能。这是一个不断升级一点,导致另一点压力增加的过程。

解决问题并不总是通过增加服务器,有时反而会引起更多问题。


9
http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster是一组关于改变的帖子链接,其中包括随着时间推移所采取步骤的详细历史。
简而言之,Ruby和Rails没有为服务提供所需的性能和可靠性。考虑到规模,这并不奇怪;在超大规模方面,大多数COTS解决方案都不令人满意。
High Scalability涵盖了许多关于顶级架构的问题,适用于其他网站,因此也有助于回答该领域更广泛的问题。

5

他们本可以通过增加硬件来解决问题,但这比编写更高效的代码要昂贵得多。像许多高级框架一样,Ruby on Rails 在许多方面表现出色,但高性能并不是它的强项。编译型语言将始终比解释型语言更快。


1
“更快”——就执行某些操作所需的CPU时钟周期而言,确实如此。在繁忙的平台上,通常是IO更具杀伤力。无论是因为您需要访问磁盘,还是等待远程服务器向您发送某些数据集。语言是一个因素,但除了某些有限的情况外,可能不是决定性因素。 - user111013
2
在这种情况下,如果您阅读了采访,就会非常明确地说明这是一种语言性能问题。 - sosborn
4
如果你比较了用新语言重写一个相当大的应用程序的成本和今天极低的硬件价格,那么在假设“仅仅”编写更高效的代码总是更便宜时,我会小心谨慎。 - Michael Kohl
@Michael 硬件确实很便宜,但是用户越多,代码效率就越重要,因为硬件成本与用户基数成正比,但代码复杂度则弱相关或根本没有关系。例如,如果您有1000万用户并需要通过硬件将容量翻倍,则其成本将是拥有100万用户的网站的10倍,但重新编写代码的成本相同。Twitter显然处于高用户基数的一端。 - Luigi Plinge
@MichaelKohl,当然你是正确的,但我是在谈论这个特定的情况,在那里他们可以在后端重写某些部分(而不是整个应用程序),而且他们正在面对绝大多数网站都没有见过的增长。 - sosborn
阅读https://blog.twitter.com/2013/new-tweets-per-second-record-and-how,从RoR转向Scala使Twitter能够在相同的硬件上提供50倍至60倍的请求,而他们最初估计只有10倍。这是一个不言而喻的选择。 - sayap

1
Facebook(和Google)通过添加更多服务器来扩展规模,但同时他们将应用程序拆分为各种服务。这些服务通过约定的接口和类型进行通信,现在可以自由地在任何他们认为合适的技术中构建这些服务。仅仅因为你读到Facebook使用PHP并不意味着他们所有的后端服务都是由PHP提供的(在SOA中选择任何技术堆栈都是有意义的)。
我认为这个视频是回答你问题的最佳答案:"从Ruby到JVM" https://www.youtube.com/watch?v=ohHdZXnsNi8

0
我认为这里缺少的一个重要因素是平台。是的,我们有编译与解释的争论和其他一些问题。 但是一个非常重要的方面确实是平台。有不同的Ruby虚拟机,但没有一个能够让Twitter满意,尽管他们对其进行了相当大的调整。但是Scala运行在JVM上,Twitter工程师对此有着非常好的经验。为什么他们没有尝试/选择JRuby呢?嗯,我想上面提到的原因在这里起作用。

如果我没记错的话,当时Rails不能在JRuby上运行。而且,如果我没记错的话,让Rails在JRuby上运行得到了Twitter的大力帮助。 - Daniel C. Sobral
好的!我的主要观点是,这不仅仅是因为语言本身,还因为JVM平台,Twitter做出了这个决定。 - AndreasScheinert
对不起,我在手机上误点击了踩。系统让我改变投票需要大约53分钟时间,除非您编辑您的答案。 - butch
似乎只有编辑才能让我修复意外的点赞。 - butch

0

线性收益与并行性(即多个服务器)非常罕见,而且非常依赖于应用程序。是的,它存在——这就是GPU完成大部分工作的方式。如果您提供静态页面且没有会话状态,那么也是如此。

然而,在大多数情况下,添加服务器不会线性增加性能(即,10个服务器不比1个服务器快10倍),这意味着在单个服务器上获得的任何收益都将比仅添加服务器更具影响力。Twitter难道没有一堆服务器吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接