• Feeds

  • Posts Tagged ‘twitter’


    Twitter停用Cassandra原因分析

    Twitter在其7.9一篇官方技术博客Cassandra at Twitter Today提到暂停使用Cassandra来代替MySQL存储feed的计划,这是Twitter一个重要的架构策略调整,因为之前Twitter一直是业界Cassandra方向的领头羊。

    For now, we’re not working on using Cassandra as a store for Tweets. This is a change in strategy. Instead we’re going to continue to maintain our existing Mysql-based storage. We believe that this isn’t the time to make large scale migration to a new technology. We will focus our Cassandra work on new projects that we wouldn’t be able to ship without a large-scale data store.

    Twitter为什么要停用Cassandra

    我们来分析一下Twitter停止使用Cassandra的原因
    1. Cassandra仍然缺少大并发海量数据访问的案例及经验,Cassandra来源自Facebook,但是在Facebook内部Cassandra目前只用在inbox search产品上,容量大约有100-200T。且Inbox Search在Facebook的基础架构中也并非核心应用。并且还传出不少rumors说facebook已经放弃Cassandra。

    2. 新产品需要一定稳定期,Cassandra代码或许还存在不少问题,但是Twitter如果投入大量的精力来改进Cassandra和比较优化MySQL的投入来看有点得不偿失。在QCon Beijing上@nk也提到Cassandra在Twitter的内部测试中曾经暴露出不少严重的问题。

    Twitter为什么之前选用Cassandra

    此问题曾经在QCon Beijing 2010做过介绍,在去年的第一期广州技术沙龙也有过交流,类似Twitter这样的网站使用Cassandra的主要原因有
    1. 数据增长规模需要不断增加新服务器,传统的切分方案在面临增删硬件时候需要手工维护,当数据规模速度增快,业务又不运行停机维护,手工维护的成本增加造成系统运维不堪重负。
    2. 不能简单增加服务器解决请求量增长的问题,需要数据架构师精细的规划。
    3. 每一个新的特性都需要重复评估数据拆分及访问优化的问题,架构师需要投入大量精力review几乎相同的业务场景。

    Twitter的调整对于MySQL业界来说或许是一大利好,MySQL虽然受近期Oracle收购阴影的影响,但是对于目前大多数拥有海量数据访问的网站依然是他们第一选择。MySQL简单,可靠,安全,配套工具完善,运维成熟。业界碰到的大部分可扩展性方面的问题在MySQL中其实都有清晰明确的解决方法。虽然重复sharding的问题很烦,增删机器相关的运维工作也很繁琐,但是这些工作量还是在可以接受的范围内。

    究竟Twitter这次策略改变是NoSQL运动的一次挫折还是前进中的一段小插曲?我们拭目以待。目前另外一大Web 2.0巨头Digg仍然在使用Cassandra。

    构建可扩展的微博架构(qcon beijing 2010演讲)

    在使用Twitter几年的时间里面,经常思考微博如何更好的实现,恰好最近几个月也参与了相关工作,大部分都是工程实践,总结实践会促生更具实际价值的理论。因此在QCon Beijing 2010这次演讲参考了不少网友的意见后选择了《构建可扩展微博架构》的题目。
    由于在决定选题时知道来自Twitter总部有30万followers的@nk也会讲一个类似的题目,心中当时有点忐忑,最大的顾虑就是要讲的领域更他重叠,如果他讲得更深入,我就没必要班门弄斧了。后来考虑到以下几个原因还是决定继续

    • Twitter架构是单IDC设计,从它递增的tweet id就可以看出,后来当面向@nk提问也得到了证实。
    • 中美网络环境差异,单IDC和多IDC有很多设计上的不同
    • 大部分参会人员未必能对英文演讲有深入理解及感悟,中文的演讲可以讲一些细节解释更透彻。
    • Twitter对故障的容忍度大,国内公司对服务故障通常更敏感。因此国内架构师会考虑设计方案尽量简单可靠,服务需要更稳定。国外开发团队更倾向追求在工作中应用技术创新,因此会导致架构设计理念的不少差异。

    演讲的slide如下,登录slideshare之后可以下载。

    这里再补充在qcon演讲未来得及考虑成熟的一个方面,用户规模影响设计,具体是指用户数每上一个数量级,许多设计需要重新考虑。

    10万用户级别

    • 单服务器,前端、后端、cache、db在一起。

    百万级

    • db和cache单独部署服务器,db或按业务进行拆分(sharding)
    • cache或使用一致性hash扩展。
    • 前端后端还是在一起,但是根据业务拆分,每个业务可分配不同数量的服务器

    千万级

    • 开始重视架构设计,有专门技术架构师
    • 需跨机房部署,前端在远程增加反向代理加速,数据库在异地机房使用slave数据库副本
    • 后端拆分出来,系统内部需要远程调用,内部需远程调用协议。

    亿级

    • 架构更细分,或增加数据架构师,cache架构师,分布式架构师
    • 数据库sharding碰到烦恼,开始考虑分布式数据服务
    • 数据访问需要根据业务特点细分。
    • 开发、运维、测量、调优具备有自己的专有工具。
    • 所有服务需要地理多机房分布,具备IDC容灾设计。
    • 服务可降级

    上面的数字仅供理解“用户规模影响设计”,数字本身并无具体指导价值。

    另外在slide中也提到了,目前新浪微博团队急需人才,对上面相关技术领域感兴趣的架构师及各层次开发人员(熟悉PHP,Java, C或数据架构任意一种)可随时跟我联系,工作地点为北京,联系方式见博客首页。

    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 竟然是鲸鱼故障的直接原因

    可提高的空间及解决思路

    1. 从上图看,Memcached在 latency高峰的性能比低谷相差一倍,因此最简单的判断是增加硬件即可提高50%的性能。
    2. 另外一种思路就是优化Memcached程序,判断程序热点和瓶颈并进行优化。

    分析

    1. 通过 Google perf-tools project 工具来分析, http://code.google.com/p/google-perftools/ http://github.com/tmm1/perftools.rb
    2. 通过自己些的一段分析代码来监控 http://github.com/eaceaser/ruby-call-graph
    3. 通过上面工具的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%。

    结论

    1. 在前文2010年的技术架构建议中提过Cache已经是Web 2.0系统核心元素。从Twitter的故障案例来看Memcached竟然成为了瓶颈并导致了Twitter服务的不稳定。由于在social应用中cache核心化的设计,“RAM is the new disk”,在cache广泛使用后也变得调用成本增加,需要考虑进行系统的规划减少不必要的调用。避免开发人员在代码中随意使用cache
    2. 如何定位瓶颈,可以借鉴Google perf-tools项目及上面其他分析工具的思路。
    3. Twitter页面执行流程值得参考
    4. 整个故障流程分析图如下