# Iron.io 从 Ruby 迁移到 Go：减少了 28 台服务器并避免了巨大的 Clusterf ** ks

> 原文： [http://highscalability.com/blog/2013/3/13/ironio-moved-from-ruby-to-go-28-servers-cut-and-colossal-clu.html](http://highscalability.com/blog/2013/3/13/ironio-moved-from-ruby-to-go-28-servers-cut-and-colossal-clu.html)

![](img/60fa20df9697ae26cfa43f92f27f70a6.png)

在过去的几个月中，我一直在使用 Go 编写系统程序，因此我一直在寻找信息以补充我的确认偏见。 当 Iron.io 用 Go 重写他们原来忙于工作的作业执行系统 IronWorker 时，Iron.io 写下了他们的[经验，这时机会突然出现，最初是用 Ruby 编码的。](http://blog.iron.io/2013/03/how-we-went-from-30-servers-to-2-go.html)

结果：

*   从 30 台服务器降至 2 台，第二台服务器仅用于冗余。
*   CPU 利用率降至 5％以下。
*   内存使用率下降。 只有“几百 KB 的内存（在启动时）与我们的 Rails 应用程序（约 50 MB）（在启动时）”。
*   级联故障现在已成为过去。
*   在数百台服务器上运行的新服务全部用 Go 编写。
*   他们相信使用 Go 可以使他们“制造出色的产品，成长和扩展并吸引 A 级人才。而且我相信它将继续帮助我们在可预见的未来发展。” 通常，建议根据人才库的规模选择一种语言，他们发现选择 Go 语言可以帮助他们吸引顶尖人才。
*   部署很容易，因为 Go 可以编译为一个静态映像。
*   Go 的次要缺点：学习新语言和有限的库。
*   对于将获得大量流量的服务器以及要为突然增长做好准备的服务器，Go 是一个不错的选择。

当然，不受第二系统效果影响的重写速度可能要快得多，但您可能还记得，LinkedIn 也有类似的经历： [LinkedIn 从 Rails 迁移到节点：27 台服务器被削减，速度提高了 20 倍](http://highscalability.com/blog/2012/10/4/linkedin-moved-from-rails-to-node-27-servers-cut-and-up-to-2.html)

这是 Go 问题解决的解释：

*   使用 Ruby，持续的服务器 CPU 使用率介于 50％和 60％之间。 添加服务器以将 CPU 使用率保持在 50％，以便可以正常处理流量高峰。 这种方法的缺点是需要水平扩展昂贵的服务器。
*   他们有一个非常有趣的失败模式。 当流量激增时，Rails 服务器将达到 100％CPU。 这导致服务器出现故障，这导致负载均衡器将流量路由到其余服务器，这导致更多服务器的 CPU 使用率达到 100％。 最终结果是级联失败。

使用 Ruby 的上市时间论点很有道理。 性能并不是一切，但在这里我们看到了性能的价值，尤其是在 Web 层之外。 优质的服务是鲁棒性和成本上的双赢。

通常，弱点被数量掩盖，数量昂贵且并不总是有效。

性能起到缓冲的作用，使系统能够吸收流量而不会中断，而在打卡机打孔后又能承受打卡机的冲击。 即时分配，拆分新实例需要花费时间，时间足够长，以至于流量峰值可能会导致级联故障。 通过为性能而不是上市时间进行编码，可以防止这些问题的发生。

## 去并不完美

如果您查看 Go 的 Google 小组，Go 并非没有[性能问题](https://groups.google.com/forum/?fromgroups#!searchin/golang-nuts/performance$20problem)。 这些问题通常可以被编码。 例如，使用 bufio.ReadSlice 而不是 bufio.ReadString 可以删除数据副本，神奇的是您的代码快了 X 倍。

学习这些技巧需要时间，尤其是使用这种新语言时。

Go 绝对处于劣势的地方是 JVM 和 V8 JavaScript Engine 多年来优化垃圾收集和代码生成的地方。 Go 可能需要一段时间才能赶上。

表演从来都不是免费的。 您必须编写聪明的代码。 最小化共享状态，不要浪费内存，不要像地狱那样配置文件，了解您的语言并通过它来做正确的事情。

## 相关文章

*   [低级可伸缩性解决方案-条件收集](http://highscalability.com/blog/2013/3/11/low-level-scalability-solutions-the-conditioning-collection.html)-将工作盲目地排入队列并不总是最好的方法。
*   [规模甚大甚至赢不了-Google 和 Facebook 示例](http://highscalability.com/blog/2013/2/11/at-scale-even-little-wins-pay-off-big-google-and-facebook-ex.html)
*   [Google：驯服长时延的尾巴-当更多的机器等于更差的结果时](http://highscalability.com/blog/2012/3/12/google-taming-the-long-latency-tail-when-more-machines-equal.html)
*   [黑客新闻](https://news.ycombinator.com/item?id=5365096)的原始文章
*   [发生了什么](http://jmoiron.net/blog/whats-going-on/)-现代语言中的 Hash 成瘾探索
*   [分析 Go 程序](http://blog.golang.org/2011/06/profiling-go-programs.html)

为什么去？ 为什么不选择 Erlang？

Go 与这个故事无关。 根本原因是 Ruby。 当 Ruby 消失并被任何工业语言（可能是 Java，C＃或任何经过验证的语言）取代时，问题也就消失了。

对于那些决定迁移到 Go 的用户，有[高度优化的库用于进程内缓存](https://github.com/valyala/ybc/tree/master/bindings/go/ybc)，[快速 Memcache 客户端库](https://github.com/valyala/ybc/tree/master/libs/go/memcache)和[为 SSD](https://github.com/valyala/ybc/tree/master/apps/go/memcached) 优化的 Memcache 服务器，全部以 走 ：）

仍然不知道您的问题是来自红宝石还是铁轨

为什么不使用 Python？

Waaat？ 从解释代码移至编译代码，并且性能得到改善？！ 这些“工程师”一定是天才！！！

它们从 30 台服务器减少到 2 台服务器，这一事实证明了 Ruby 最初的选择是多么的糟糕。 但是现在他们正在转向 Go-一种更加晦涩的语言？ 这使我怀疑他们是否考虑了客户的需求，或者他们是否只是想炫耀自己在最新技术方面的优势。