COOKPAD所使用的技术 — 基础设施篇

序:

本系列文章主要基于日本技术评论社的杂志的《WEB+DB Press》(总)第66卷(2012年1月25日发行,数据有点老,2年了。)的专题“COOKPAD开发Know How大公开”整理而成,部分数据可能会根据网上能搜集到的信息加以修改。

本特辑主要分为5部分,分别是:

1. 严守200毫秒 — 基础设施篇

主要介绍采用AWS,图像分发、处理,异步加载,缓存等内容。终极任务:确保服务器响应时间在200毫秒之内。

2. 大规模项目快速开发流程

TDD(测试驱动),原型法,频繁发布

3. 以用户为中心的开发

model user,用户访谈,EOGS

4. 高效的智能机应用开发

如何选择App和Web?自己独自的库,code snippet

5. 跨公司的团队氛围

DevOps、全部门工程师体制、AARRR指标

本文主要是第一章,基础设施,也就是infrastructure

COOKPAD是什么公司?

COOKPAD网站是1998年上线的,当然,那时还没有Rails。2005年曾经一度尝试过使用过Rails,但是没有成功。直到2008年后,才开始逐渐的转移到Rails。我曾在Ruby Kaigi 2007上见过他们的演讲,当时还在招聘Rails工程师。直到现在,每次Ruby或者Rails的各种会议,都有他们招聘的身影。

选择Rails的原因

当初选择Rails主要基于以下两点:
1. DRY,编写风格良好的代码,利于复用。
2. 框架本身鼓励测试。

基础架构

系统工程师有5人,架构也很普通:反向代理+应用服务器+数据库。具体来说如下:

■ 负载均衡

使用了Amazon的ELB(Elastic Load Balancer http://aws.amazon.com/jp/elasticloadbalancing/

■ 反向代理

反向代理使用了Apache HTTP Server,css、JavaScript、图片等静态文件在反向代理上返回。通过使用mod_ proxy_balancer,来分配缓存服务器。

■ 缓存

缓存使用了Varnish,同时,Varnish也兼任了应用服务器的负载均衡功能。

■ 应用服务器

Rails程序跑在Nginx或Unicorm上。

■ 数据库

数据库使用了MySQL,由两台master和若干slave构成。Rails使用了ActiveRecord (COOKPAD改造过的)插件acts_as_readonlyable,查询语句只会到slave请求。update则会在master上执行。

此外,查询(全文检索)服务使用了Solr。

从数据中心到云计算

直到2010年,COOKPAD的服务器都在全国各地的数据中心。之后随着业务量的迅速增长,逐渐转向云计算。促使其转向云计算的原因除了日益增长的用户和访问量之外,还有不断推出的新产品和功能需求。

COOKPAD在使用AWS的过程中,开发了如下一些工具。

■ Elasticfox-ec2tag

COOKPAD通过EC2实例的标签来对实例进行管理,Elasticfox-ec2tag(https://github.com/cookpad/elasticfox-ec2tag)是对EC2的管理工具Elasticfox(http://aws.amazon.com/developertools/609?_ encoding=UTF8&jiveRedirect=1) 进行了标签功能的扩展。

■ IAM fox

IAM fox (https://github.com/cookpad/iam-fox)是GUI版本的AWS IAM(Identity and Access Management)管理工具。

■ R53 fox

看名字知道是 Route 53(http://aws.amazon.com/jp/route53/)相关的,一个GUI工具。主页在( https://github.com/cookpad/r53-fox)。

■ ec2ssh

ec2ssh (https://github.com/mirakui/ec2ssh)是将EC2实例的“Name”作为hostname,生成ssh_config 的CUI工具。使用这个工具,可以不用拷贝粘贴默认的EC2实例的domain名,可以自由的使用hostname来进行SSH连接。

图像处理问题

■ 存储问题

图像文件尺寸大,需要额外空间来保存。在Linux OS下的话,还需要注意目录结构构成问题。为了防止系统故障、人为失误等,还需要进行备份。此部分n工作会花费较多精力。

■ 缩略图生成问题

COOKPAD需要为用户上传的原图片,生成各种各样尺寸的缩略图来显示。生成方法主要有静态生成和动态生成。静态生成指得是在用户上传后,立刻生成各种尺寸的缩略图。动态生成即用户上传文件后,只保存原文件;只有在用户请求缩略图时,才去生成相应尺寸的缩略图。动态生成方式比较灵活,但是会增加服务器负荷,并增加响应时间。

曾经COOKPAD都是采用静态生成方式的,但是带来的问题是某新功能需要新尺寸的缩略图,那么就必须对已有图片进行批处理来生成新尺寸的缩略图。当时COOKPAD
使用的存储位NFS,由于年久失修,构造复杂,维护成本很高。

tofu 动态图片处理系统

此系统由成田(可不是成田机场:-))主持开发,在公司内部称作tofu(没错,就是豆腐的意思。),其设计思想主要包括

  • 动态生成缩略图
  • 与应用程序本身松耦合
  • 要简单
  • 可扩展

tofu基于AWS构建,文件都保存在S3上,服务器则运行在EC2上。

■ tofu请求

tofu通过URL来指定访问什么尺寸的缩略图。比如URL类似这样:

http://hostname/recipes/1234/120x120c/5879cb5984dd3f19dca3622b281ffd4e.jpg

其中recipes是model名,1234是ID,120*120c则是缩略图大小。

除了这些参数,还可以在URL中指定是否要crop,压缩质量等各种参数。

MD5:用来防止恶意请求。

■ 动态生成缩略图

tofu的图片服务器以Apache的module方式实现,称为mod_tofu。mod_tofu在接收到请求时,从S3取得图片资源,进行处理后,将图片返回给客户端。

■ 横向扩展

在7G内存,8个虚拟内核CPU的c1.xlarge机器上,能支持100req/sec的吞吐。
tofu的扩展只需要启动一个新的AMI实例,并配置到ELB之下即可。

■ CDN

tofu的CDN采用了Akamai(http://www.akamai.com/),之所以没有采用AWS的CloudFront,是因为基于自己的benchmark来说,Akamai的性能要好一些。

确保200ms的底线

COOKPAD的基础设施(运维)组严守着200ms这个底线,即客户请求都需要在这个时间内返回。如此要求,除了能带来用户体验的上升,还能节约成本(减少服务器数量等)。但是,高速化只是手段,而不是目的。(意思是不能为了高速化而与主营业务偏离)。这个200ms是一个开发成本(时间,代码可维护性等)与响应速度的一个折中数字,COOKPAD虽然能达到这个数字要求,但也绝非那么容易的事情。

Rails很慢么?

Ruby很慢?异议由来已久。

当初COOKPAD采用Rails就是因为它开发速度快,简洁,非常适合开发Web原型。我们虽然认为Ruby和Rails虽然算不上运行很快的语言,但是以我们的实践来说,用Rails做一个COOKPAD这样的网站,运行速度还是非常快的。

如果使用REE(Ruby Enterprise Edition http://www.rubyenterpriseedition.com/),使用社区最佳实践的话,200ms不是一个很难的目标。

检测网站速度

“不要推测,要检测”。COOKPAD采用若干种方法检测系统性能。

运维显示屏

这是COOKPAD的与众不同之处之一。运维组的桌子上摆放着一个显示屏,显示了现在的平均响应时间,错误数,数据库复制的延迟情况等。

使用Munin监测速度

使用监视工具Munin(http://munin-monitoring.org/),可以将实时性能数据图形化表示出来。除了能看到及时数据,还能看到长时间内数据的变化、趋势等。除了服务器的响应时间,还能通过JavaScript来测量浏览器渲染页面所花时间。

慢查询和NewRelic

大部分性能问题都是源于数据库的。虽然MySQL提供了慢查询功能,但是由于Rails的ActiveRecord的原因,查找慢查询语句就不那么方便了。COOKPAD使用了Rails业内有名的性能监视攻击NewRelic(http://newrelic.com/)服务。如果有设定值以上的SQL语句的话,就会将调用栈信息发送到NewRelic服务器,就能知道哪行执行了耗时操作了,而且还能看到EXPLAIN信息。

通过异步载入(Ajax)提高用户体验

COOKPAD几乎所有的页面都采用了异步载入技术。关于这部分没什么特别好说的,在现在Web开发里都是很基本的东西。

关于缓存

将耗时的响应缓存起来,能高效的解决性能问题。COOKPAD典型的缓存为页面缓存,即将响应(HTML)页面通过Varnish 整页缓存。页面(也包括其它类型)缓存的一个比较棘手问题就是缓存失效机制。页面缓存的时候,如果是大规模删除缓存,会给后台服务器带来很大负担。bug也可能带来缓存删不掉,缓存不该缓存的问题等。尽管COOKPAD使用了各种缓存技术,但是在COOKPAD里,一直遵循这“缓存只是最后的手段”,即除非实在别无它法,才考虑使用缓存。

— 本文完 —



Posted in Rails, Ruby, Tech Tagged with: , , , , ,

无觅相关文章插件,快速提升流量