百度空间 | 百度首页 
 
查看文章
 
Google App Engine 上应用开发的性能优化
2009-09-02 16:34
前段时间一直太忙了,所以planet 2的开发处于停滞状态,这两天重新捡起来,首页要做的是性能优化。

我们之前写的代码性能实在是很差,逻辑处理已经比较复杂了,所以要理清这些东西不是件轻松的事情。

一开始,我们的主要页面响应时间为10秒左右,这绝对是不可接受的,所以开始了我们的优化之旅。

首先,把各个class中调用数据库的地方全部统一,因为之前每个API自己要查询数据库的时候,都是把数据全部掉出来查一遍,然后再filter,这样的效率是极其低下的,因为如果某个逻辑处理需要连续调用很多不同的API,就要重复查询数据库N次。

所以我集中把数据库查询初始化在了class的 __init__(self)里,这样只要class初始化一次,就能够满足所有同时调用的API的请求。

其次,光这样还不够,同样会效率非常低下,频繁的查询数据库也会造成CPU飘高。于是我开始把查询出来的数据全部丢入了memcache,API调用的时候就先看看memcache里有没有这些数据,如果有,就直接从memcache里拿了,如果没有,再去查询数据库,同时把查出来丢到cache里。

这项改进做出后,性能果然大大提高,10倍左右吧,原来需要10秒才能完成的工作,在数据被cache后,缩短到了1秒左右。

但是这又带来另外一个问题,就是逻辑有点混乱。因为不同的API都会去读写memcache,这样有时候写操作后,memcache没刷新,返回的页面还是旧数据。这些地方一多,逻辑关系就很难理清了。

同时还发现了另外一个问题,CPU time还是没有降下来,而GAE对CPU time是有限制的,如果过高,很容易就达到了限制,从而要额外缴费。

于是我想把CPU time降下来。GAE提供了专门的API用于性能测试,如下:
import logging
from google.appengine.api import quota

start
= quota.get_request_cpu_usage()
do_something_expensive
()
end = quota.get_request_cpu_usage()

logging
.info("do_something_expensive() cost %d megacycles." % (start - end))
使用这个API,在函数调用的前后插入,然后记录到log里,就可以再admin console里看到信息了。

注意这个API只能在线上环境用,本地测试环境不能用。这也导致我直接在线调试,一天发布了好多次。

这是个体力活,经过一系列追踪后,我终于发现了罪魁祸首!

template.render(path, values)

这个django里的模板渲染函数效率极其低下,而且非常吃CPU!!

怎么办? 第三方库里的东西不好改,改了还不好升级。

于是我走了另外一条路,把所有的页面全部丢进memcache!

具体是这样做的:

1. 根据url请求缓存该页面,如果下次有对该url相同的GET请求过来,则直接从memcache中返回缓存页面
2. 约定所有的写操作全部通过POST完成,如果写操作执行后,则删除memcache中缓存的对应页面,页面需要重新生成进缓存

这样做后,性能再次提高了10倍,在我的本地测试,响应时间大概在60-80ms,比原来1秒左右提高了十倍,比原来的10秒左右提高了100倍!!


除了利用好memcache外,还有一些常规的性能优化技巧,比如增加静态图片、js、css等的浏览器缓存时间,还有一些技巧,google下可以找到很多,就不在这里赘述。

值得一提的是静态文件缓存,GAE的配置文件中直接提供了此功能:
比如在 app.yaml中这样写
handlers:
- url: /css
static_dir: static/css
expiration: "30d"

- url: /js
static_dir: static/js
expiration: "3d"

- url: /pic
static_dir: static/pic
expiration: "30d"

意思就是缓存30天

"3d 5h 2m 8s"
就是3天,5小时,2分钟,8秒,规则很简单。更多的可以查阅开发手册。

加上这个后,webserver就会自动给response增加 cache-control 和expire 头。

但是经过我测试,发现只有IE认识,FF居然不认!

悲剧啊,

FF 只认 Last-Modified 头,但是这个实现则需要自己写了,配置文件里管不到。

网上也有现成的解决方案

http://www.ipsojobs.com/blog/2008/06/17/how-to-create-a-simple-but-powerful-cdn-with-google-app-engine-gae/

但是出于成本考虑,我就不折腾了。

附上两张效果图
调优前后


调优前首页的响应时间是 18.09秒, 调优后响应时间是 88毫秒

可以看到性能提高了200多倍

以上就是我的一点实践经验了,希望可以帮助一些有需要的朋友少走弯路。

类别:象牙塔 | 添加到搜藏 | 浏览() | 评论 (7)
 
最近读者:
 
网友评论:
1
2009-09-02 17:43 | 回复
我还有个问题,Google阅读器里面为什么可以查看到订阅频道里的以往数据,而planet中只能得到当前最新的

我翻了些RSS协议说明,貌似没有翻页功能啊,也自己伪装了个RSS让Google来读,也没有看到日志里有多余的动作啊...

难道他们是全部频道早就开始后台订阅并存储了?
 
2
2009-09-02 19:44 | 回复
回复Mix:汗,google的所有数据都存在他的服务器里啊,所以能够查。planet也存了,但是没做展示,新版本的planet会提供这个功能,查询历史数据
 
3
2009-09-02 22:55 | 回复
在我本机电脑是80ms 左右,放在GAE上,则是 30ms 左右
 
4
2009-09-03 09:13 | 回复
顶!严重期待planet 2
 
5
2009-09-03 10:00 | 回复
GAE上有memcache可以用?
 
6
2009-09-03 10:53 | 回复
回复ak:有的
 
7
2009-09-08 11:09 | 回复
原来如此...我等不及planet 2了,写了个小程序直接从访问google reader的临时文件中搜索分离出所有我要的文章~刚好搜集了666篇文章,很顺,哈哈
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu