Twitter“鲸鱼”故障技术剖析
很多人都熟悉Twitter访问故障时候那条白色的鲸鱼。今年新推出的Twitter Engineering Blog讲述了Twitter白鲸技术故障的原因及解决思路。这是到目前为止Twitter公开的最底层的一篇技术资料。
http://engineering.twitter.com/2010/02/anatomy-of-whale.html
当Web Server发生503错误后,Twitter配置了一个前端鲸鱼的显示页面。Twitter对鲸鱼页面有监控体系,当每秒超过100个鲸鱼就会引起报警。
为什么在单位时间内会有大量的”fail whale”呢?Twitter成立了一个小组来专门分析此原因。
1. 分析背景资料
“分析性能问题不是一门科学,而是一门艺术”。
鲸鱼页面实际上是对HTTP 503错误的前端展示,503错误通常是调用后台请求超时产生,为了避免用户长时间等待,Twitter的前端(Tim: 也可能是HTTP反向代理)给请求加了超时,避免用户无限制的等待。超时通常是由于单位时间内访问的用户数过大,也有可能是后台某个服务突然变慢造成。
由于Twitter网站每个时刻都有海量的数据流过,因此要简单的定位并解决此问题并不容易。
2. Web page请求分解
Twitter的页面请求后端分成2个阶段,在Twitter内部称为IO phase及CPU phase。IO phase指通过网络服务获取用户的关注关系及相关的Tweets。第2阶段为CPU phase,指将数据聚合、排序及按用户请求的条件输出。IO及CPU各自在1天内消耗的时间如下。
从图上看到,latency增大时IO是主要瓶颈。IO对应于Network service,因此可以判断是某个网络服务性能降级造成。
3. 深度分析
理想情况是网络服务在应答相同参数的请求消耗时间应该基本相同。但实际情况并非如此,我们大胆假设某一网络服务性能下降厉害,于是我们就从统计分析中去寻找这个服务,我们看到Memcached的统计图表如下
4. Memcached 竟然是鲸鱼故障的直接原因
可提高的空间及解决思路
- 从上图看,Memcached在 latency高峰的性能比低谷相差一倍,因此最简单的判断是增加硬件即可提高50%的性能。
- 另外一种思路就是优化Memcached程序,判断程序热点和瓶颈并进行优化。
分析
- 通过 Google perf-tools project 工具来分析, http://code.google.com/p/google-perftools/ http://github.com/tmm1/perftools.rb
- 通过自己些的一段分析代码来监控 http://github.com/eaceaser/ruby-call-graph
- 通过上面工具的call graph来分析热点和瓶颈
最后分析数据Memcached请求分布比例如下
get 0.003s get_multi 0.008s add 0.003s delete 0.003s set 0.003s incr 0.003s prepend 0.002s get 71.44% get_multi 8.98% set 8.69% delete 5.26% incr 3.71% add 1.62% prepend 0.30%
结论:从上面数据来看,调用热点和瓶颈主要集中在Get操作
因此回头取看Twitter页面执行流程代码,找出优化方法见注释。
get(["User:auth:missionhipster", # 将昵称转换成uid get(["User:15460619", # 获取user object(用于检查密码) get(["limit:count:login_attempts:...", # 防止密码字典攻击 set(["limit:count:login_attempts:...", # 大部分情况不需要, bug set(["limit:timestamp:login_attempts:...", # 大部分情况不需要, bug get(["limit:timestamp:login_attempts:...", get(["limit:count:login_attempts:...", # 重复调用,可记住 get(["limit:count:login_attempts:...", # 重复调用 get(["user:basicauth:...", # 防止解密的优化 get(["limit:count:api:...", # 请求数限制 set(["limit:count:api:...", # 设置请求数,大部分情况不需要,为什么? set(["limit:timestamp:api:...", # 大部分情况不需要, bug get(["limit:timestamp:api:...", get(["limit:count:api:...", # 重复调用 get(["home_timeline:15460619", # home_timeline业务调用 get(["favorites_timeline:15460619", # favorites_timeline业务调用 get_multi([["Status:fragment:json:74736693", # multi_get所有tweets内容
上面这段代码将17个请求优化成10个,部分重复调用通过本地cache避免,另外一些没必要的调用直接删除。通过一个简单的优化性能就提高了42%。
结论
- 在前文2010年的技术架构建议中提过Cache已经是Web 2.0系统核心元素。从Twitter的故障案例来看Memcached竟然成为了瓶颈并导致了Twitter服务的不稳定。由于在social应用中cache核心化的设计,“RAM is the new disk”,在cache广泛使用后也变得调用成本增加,需要考虑进行系统的规划减少不必要的调用。避免开发人员在代码中随意使用cache
- 如何定位瓶颈,可以借鉴Google perf-tools项目及上面其他分析工具的思路。
- Twitter页面执行流程值得参考
- 整个故障流程分析图如下
建议继续学习:
- Twitter/微博客的学习摘要 (阅读:8135)
- 别得瑟了,你很可悲! (阅读:6443)
- Twitter架构图(cache篇) (阅读:4740)
- PHP for Twitter OAuth 教学演示 (阅读:3540)
- Twitter新员工的入职过程是怎样的? (阅读:3307)
- 基于黄金分割率的Twitter新版页面布局探究 (阅读:2532)
- 新版twitter背后的技术 (阅读:2479)
- Twitter系统运维经验 (阅读:2459)
- SNS背后的科学 (2) ―― 割裂的Web和割裂的Twitter (阅读:2459)
- 继续说说新版Twitter设计方面的事儿 (阅读:2437)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Tim 来源: Tim[后端技术]
- 标签: Twitter 故障
- 发布时间:2010-03-09 09:12:37
- [53] IOS安全–浅谈关于IOS加固的几种方法
- [52] 如何拿下简短的域名
- [51] 图书馆的世界纪录
- [50] android 开发入门
- [50] Oracle MTS模式下 进程地址与会话信
- [49] Go Reflect 性能
- [46] 【社会化设计】自我(self)部分――欢迎区
- [46] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 程序员技术练级攻略
- [29] 视觉调整-设计师 vs. 逻辑