瞎扯淡 使用 Go 代替 Ruby 将服务器数量从 30 降到 2

kewin · 2013年03月14日 · 最后由 yfractal 回复于 2017年09月29日 · 11730 次阅读

摘要:将服务器数量缩减到之前的十五分之一,并且降低了服务器 CPU 的使用率,Iron.io 成功的做到了。Iron.io 在遭遇了 Ruby 的限制后,大刀阔斧般的使用 Go 语言重写其名下服务 IronWorker。 使用另一种语言去重写一个服务,听起来是不是很折腾?然而云服务供应商 Iron.io 就这么做了,并成功的将服务器从 30 台降至了 2 台。Iron.io 在其官方博客上公布了整个事件的始末,下面来了解一下: Iron.io 与 IronWorker

Iron.io 起初为帮助其它公司建立应用程序的咨询公司,现为云服务供应商。Iron.io 开发 IronWorker 的理由同样很老套: 之前说过 Iron.io 曾是家咨询公司,而在 IronWorker 开发的那段时间,AWS 和 Ruby on Rails 是两个非常火的领域。而 Iron.io 有几个客户建立的硬件设施会不断的(7X24 小时)给其发送数据,为了收集和处理这些数 据,Inro.io 建立了他们自己的内部服务“worker as a service”。至于发行的原因就很老套了,在自己使用的同时,忽然觉得其它机构可能也会有类似的需求(很类似“书贩子”Amazon?),于是就诞生 了发行版 IronWorker。

理所当然,IronWorker 首发版使用的是 Ruby 和基于 Rails 的 API。起先,IronWorker 表现的很不错,花很少的精力和时间就可以支撑相当重的负载。然而很快 IronWorker 就受到了 Rails 的限制:

又是 RoR 惹的祸

为了保持服务的流畅,Iron.io 一直将其服务器 CPU 使用率保持在 50-60%;CPU 使用率一旦超过这个范围,就会增加服务器数量。当然如果不介意一直增加服务数量,这也是可行的,然而很快他们就介意了!

当某个“巨大”请求连接到它们的服务器,很可能就会产生一个多米效应导致整个服务器集群的崩溃:

一旦某些线程占用高于 50% 以上,Rails 服务器 CPU 使用率将随之飙升到 100%,而这个服务器将变的异常缓慢。负载均衡器则会认为这个服务器 发生故障,将其从服务器集群中移除;但是被移除服务器上的作业将会被分配到剩余的服务器上,于是问题就发生了——导致整个事件发生的线程并未被移除或得到 处理。就这样恶性循环产生,集群中的服务器被一台又一台的移除,直至整个系统崩溃。

唯一避免这个问题产生的方法就是增加足够的计算能力,这就意味着巨额成本的产生。基于多年的优秀(使用更少资源承担更多负载)开发经验,Iron.io 决定重写 API,做掉罪魁祸首的 Rails,这样首先他们面临的就是究竟该使用什么编程语言。 Go 的脱颖而出

首先他们考虑的就是回到 Java 的性能优势上来,然而经过多年使用 Ruby 的简洁、明了及有趣,Java 因为编码效率上的劣势被抛弃。接着是又考虑 了一些比 Ruby 具备更高性能的脚本语言,比如:Python、JavaScript/Node;Java 的派生物,比如:Scala 和 Clojure;还有一些其它语言,比如:Erlang、Go 等。而在一些原型和性能测试后,最终他们选择了 Go。 而在当时的那个环境下选用 Go 伴随着很大的风险,因为:当时 Go 还没有很大的社区,也没有许多开源项目,同样也没有许多成功的用例。使用 Go 有太多不可预测性存在,比如招聘优秀的工程师;不过这些大部分都没有发生。

Go 版本使用情况

Go 版本推出后,Iron.io 的服务器数量直接从 30 台减到了 2 台,附加的两台实现冗余服务器更是从未用到。CPU 的使用率不到 5%,而初始化过程中对比 Rubby 使用接近 50M 的内存,Go 版本只是用了不到几百 K。 原文链接:How We Went from 30 Servers to 2: Go(编译/仲浩 审校/王旭东) 转自 http://www.oschina.net/news/38585/how-we-went-from-30-servers-to-2-go

consulting company + Ruby on Rails + Go is fun

感觉很不好...

#1 楼 @Saito 别这么说,Chef 还是改用 Erlang 了...

现在这 IT 网站都喜欢雇一些编辑来翻这些无聊文章啊..

#5 楼 @hooopo 这可是上过 HN 首页的无聊文章啊

#6 楼 @bhuztez 你以为编辑去哪里找资源翻译?

匿名 #8 2013年03月14日

我是多么希望我所在的公司也能遇见这种瓶颈啊~ :)

#4 楼 @bhuztez 单机 10000 台,Ruby 内存还是撑不住。不知道他们有没有试过 celluloid . 说不定用 Go 内存会更小,Erlang 也不少吃内存。

#9 楼 @Saito 这个规模你还想只用一台机器顶住?

#9 楼 @Saito Erlang 虽然吃得多,但吐出来也快,因为内存碎片造成内存页不能被操作系统回收的概率比别的自带 GC 的语言小太多了。对于运行时间很长的服务,这就意味着内存占用小。因为对操作系统来说你占的内存就是你占了多少内存页...

#10 楼 @bhuztez 这次 Chef 11 的迁移主要是 Facebook 后面协助,如果达不到指标的话,Facebook 可能就不会用 Chef 继续搞了。单机 10000 台,这是最终他们达到的指标,已经很好了。小公司大可以放心用。大公司也比较满意。

而 Iron.io 有几个客户建立的硬件设施会不断的(7X24 小时)给其发送数据,为了收集和处理这些数 据,Inro.io 建立了他们自己的内部服务“worker as a service”。

这和 Postrank 差不多嘛 可是 Postrank 却诞生了goliath

其实不管先用哪个,后用哪个,改写后一定会变快的...

#14 楼 @luikore 也可以变慢的,就是他们不会说出来了...

之前看过 HN 上的评论(不是这篇文章)说,迁移之前已经积累了经验和教训,知道寻找怎样的合适工具,所以迁移后获得了成功。所以这并不代表他们一开始就用 Go 就不会走弯路

开发人员数量从 2 上升到 30

#17 楼 @kgen 嗯!明白人哦!!

@kgen 人工比服务器贵多了,这年头

#17 楼 @kgen 开发人员 30:30 差不多吧...

#17 楼 @kgen 一针见血,用 Ruby 一年光工资就要省多少服务器

我觉得 Iron.io 使用 Go 是不明智的,直接上 Erlang!不管什么问题,绝对统统地搞定! 直接无视 Ruby,Python,C,C++, Java,Go...,它们的出现简直就是在衬托 Erlang 的伟大、光明、正确。 向万能的 Erlang 致敬!

#22 楼 @skandhas 来人,把这个异端拉出去弹 jj 一百下 O(∩_∩)O 哈哈~

用 goliath/eventmachine 应该也会好很多吧

#22 楼 @skandhas Erlang 这么神啊,但现在 CouchDB 用 C++ 重写,缘何呢

#22 楼 @skandhas 感觉好像不止 Erlang 中枪...

Go 版本推出后,Iron.io 的服务器数量直接从 30 台减到了 2 台,附加的两台实现冗余服务器更是从未用到。CPU 的使用率不到 5%,而初始化过程中对比 Rubby 使用接近 50M 的内存,Go 版本只是用了不到几百 K。

我觉得他们之前对 Ruby 的使用也很有问题。不过,这篇是我看过最好的 Go 语言的软文了,特别是最后这么一段,把 Ruby 痛斥的体无完肤。

Erlang 写复杂逻辑要你死。Ruby 这种语言,我说难听点,我老婆都可以写点测试脚本。

erlang mochiWeb hello world 你去看看 https://github.com/mochi/mochiweb/blob/master/examples/https/https_store.erl

Go 版本 https://github.com/hlxwell/performance_evaluation/blob/master/ruby-vs-go/tracking-server/server.go

感觉上就是 Go 稍微简单了。

Erlang 不是万能的,他在做简单业务但是要求高可用性的东西,是先天性的好。复杂业务方面,写 Rails 让你有种吃了撒尿牛丸后那种爆的感觉

#30 楼 @hlxwell mochiweb 其实就相当于 rack,只提供了一个最基本个核,其余都得自己来...Erlang 并不是不能处理复杂逻辑,只是适用的情况,语法,编码习惯都比较特殊。

#30 楼 @hlxwell

你对 Erlang 的 HTTP Hello, World!的要求真高,要支持 HTTPS,还 GET/PUT/DELETE 一个不能少。

Go 代码就只要记录 Referer,请求的 URL 和客户端地址就好了。

Erlang 不是万能的,显然处理不了几种逻辑。复杂的逻辑,得看何种类型的逻辑。

如果是普通的业务逻辑,Erlang 其实会比 Go 什么的好太多了。毕竟是从 Prolog 上发展出来的。

看这个 Presentation,他们都直接让非程序员写业务逻辑了 http://www.erlang-factory.com/conference/SFBay2012/speakers/RichardCarlsson

#26 楼 @ruchee 柯南兄,现在的 CouchDB 还是用 Erlang,你说的应该是 原 CouchDB 的作者另起的一个新项目 CouchBase,这个项目中他放弃了 Erlang,而是用 C 来实做 (不是用 C++)。

@bhuztez 那个例子不是好例子。其实由于 coffeescript 写多了,erlang 的语法还是突然之间很习惯了。

#30 楼 @hlxwell 你这个帖子让 @bhuztez 大大 来 K 就好了 ;)

Iron.io 打开网站看,IronMQ is the Message Queue for the Cloud,这不是 Rails 的应用场合了,把主要部分用其他对异步/并发支持更好的语言重写是正常的。

Erlang 看过一点,函数式语言给我不少启发,不过在 web 这样的应用场合,不想用这种思考模式来编程。需要性能和并发一类的任务,我也会选 go,语法更易理解。

我从 Ruby 转到了 Go,就一个感觉,写 Go 也可以很爽。至于语言用在哪些地方合适,怎么用,我的资历还不够,不好说什么。

36 楼 @bhuztez 嗯,我上面说的不准确。 Coushbase使用了多种语言。 couchbase-server_src-1.8.1 的代码中: C 文件:290 个 Erl 文件:166 个 (集中在 ns_server) C++ 文件:70 个 (集中在 ep_engine)

#17 楼 @kgen 这个是亮点。

@huobazi @ruchee @hlxwell @saiga @Rei

我在 #22 楼的帖子是个玩笑贴,本来是想模仿一下 @bhuztez 大大 对 Erlang 的热情;) 没想到你们也太不幽默了~。报上你们的经纬度!哼!

#38 楼 @miracle 哪里爽了。你 Ruby 写了 1 个月,然后写了 3 个月 Go 当然爽了

#38 楼 @miracle Go 最让人不爽的是:借用的是 C 语言的语法,却将变量的声明次序给变了,而且在面向对象风行的今天,加个 class 关键字会死啊

@hlxwell 我 Ruby 写了 4 年了,现在写 Go 也还是挺爽的。哦哦哦,啊啊啊。

#44 楼 @ruchee 你确定加上class就能面向对象了?

#46 楼 @bhuztez 貌似你偏离问题了,我只是想说,加上会方便很多

#12 楼 @Saito Puppet 还是全用 Ruby 写的,而且吹牛皮说自己三四年前就达到了这个规模,不知道是不是真的。

这个没法比,用 go 语言永远做不出来 rails 这样的框架,再高水平的高手也做不出来

#45 楼 @sunfmin 这么爽啊。都哦啊哦啊了啊。有没有 go 版本的 Qor 在整啊。

#45 楼 @sunfmin 飞哥要把 ThePlant 变成杭州最大的 Go 开发公司了啊。

#52 楼 @kewin 那这篇文章里面说的 Ruby 的问题会不会有点夸大,单台 Puppet 服务器带一万个 agent 的压力不比这文章中的场景小吧

#53 楼 @goinaction 我们这的现在带 1000 台左右(puppet report 在~ 100K)

#54 楼 @kewin 配合了 MCollective、MQ 和 nginx 的吗?

还停留在期望手上做的东西遇到流量和性能/压力问题的阶段,惭愧。

之前 go 刚出来的时候看过,当时库很少,现在都这么多库可以用了啊,打算拿个应用试试,我也感觉 go 好亲切的样子

come on 大神们,语言贴又开了。好奇的问一下 @kewin 是什么公司,有这么多的服务器?

#43 楼 @hlxwell 好吧,我只想说说我的感觉,并没有说谁不好,这和语言的使用时长关系不大吧。我觉得爽只是我的个人感觉,纯属个人喜好,我也没有说用 Ruby 写不爽,我觉得 Ruby 也很爽 😄

@miracle 是啊。我觉得 ruby 写爽了,够需求了当然就没有必要去企切到别的语言去。但是比较关注 go 界内动态。

我觉得是 高级黑

#60 楼 @hlxwell boss 让我用 Go,我目前不敢拍胸膛说我用 Ruby 能做得更好啊,所以…… 不过用 Go 真的不错,也开阔一下思维,不算什么坏事。

什么时候 Go 的 BDD 测试能达到 Ruby 的水平我会继续转会 Go 去研究的

#反正访问不了 go 的官网#

#64 楼 @keer2345 add to hosts : 173.194.71.141 golang.org

66 楼 已删除

#62 楼 @miracle 挺好的,领导给你时间和机会去接触一些你不抵触,而反而有兴趣的东西。那不是正好吗。多试试没错的。我是真心试过 erlang 觉得,写起来真心不容易上手,变量只能赋值一次的,这个要习惯一段时间才行。go 倒是还行。语法变化没那么大。

首页两个坑 一个是操作系统坑 一个是语言坑 这两个都是万年老坑 大家都爱跳 而且都跳的挺欢乐 总争先恐后的证明自己屁股坐对了位置

看了一下 wikipedia 上面給出的 go 語言的範例,我就果斷拋棄了學習 go 的念頭了. 不想讓自己有生之年只寫代碼的我,果斷喜歡上 Ruby.

一个脚本语言,一个需要编译成可执行文件的语言,没什么可比性,你用 erlang 比用 go 效果更好,话说那 ruby 代码写得也够烂的,跑成那样

Go 使用 struct 來實現面向對象的設計相當精巧...其實不需要 class

清华大学开源映像站 提供 GO 语言 影响和网站 http://go.tuna.tsinghua.edu.cn/

#72 楼 @kewin 居然是 1。02 版本的。。

#73 楼 @daweiba 抱歉没注意这些 你可以联系他们的管理员

hlxwell 回复

Erlang 写复杂逻辑要你死。Ruby 这种语言,我说难听点,我老婆都可以写点测试脚本。

不懂编程的人,都能写 ruby 代码,是对 ruby 的赞誉啊。。。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号