Foursquare 长达 11 小时的宕机

今天是个值得庆贺的日子

前几天 Foursquare 经历了长达 11 个小时的宕机,没错,11 个小时。网站官方的解释是 Shard 负载不均匀造成后续的连锁反应。很多人都知道 Foursquare 在线的 DB 是 MongoDB,今天又看到 10gen (MongoDB的开发与支持团队)的 Eliot Horowitz 在得到 Foursquare 许可后,通过邮件组详细介绍了宕机的过程:Foursquare outage post mortem,不用说,也有为 MongoDB 辟谣的意味在里面。

读罢 10gen 团队的介绍(或者说解释)之后,发现这是一个很好的研究样本。值得分享。

为了提高响应速度,Foursquare 使用 MongoDB 存储 Check-in 的数据已经有一段时间了。这部分数据的数据库起初跑在一个 66GB 内存的 Amazon EC2 单实例上(全部在内存里),两个月前,出于对容量增长的考虑,迁移到两台 Shard 集群上。每个 Shard 机器都是 66GB 内存,为了冗余,每个 Shard 都有复制到 Slave 实例。迁移的目标是所有的 Check-in 数据都保存在内存中。数据根据 ID 分成 200 个 Shard 分片,两台机器各占一半,也就说联机数据在每台机器上各使用 33GB 的内存。两个月相安无事。

问题来了,因为 Shard 算法导致的数据分散不均衡,其中一台(Shard0)数据增长到 67GB(另外一台 50GB),超过了 66GB 的限制,读写部分分散到磁盘上,性能急剧下降。从而,网站宕机。

首先尝试增加第三台 Shard 机器,上线后开始迁移,读取从三台进行,Shard0 的数据迁移到 5% 的时候,但是写操作还是让 Shard0 宕机了。这个时候发现Shard0 存在数据碎片(data fragmentation),即使数据迁移走,还是会占用原来的内存。每个Check-in 文档大约占用 300 字节,而 MongoDB 是 4KB 的页(Page),也就说十几个文档会填满一个页,而迁移 5% 反而造成了页更加稀疏,并不是将页全部删除。

这个时候已经到了第二天,随着网站全面宕机,技术团队开始用 MongoDB 的 repairDatabase() 功能来对数据库进行压缩,因为数据库太大和 EBS 慢,也因为 repairDatabase() 不能充分利用多核CPU 的能力,这个过程耗费了 4 个小时。之后这 5% 的内存空间终于释放出来,系统重新上线。

随着 Shard0 修复,第三台成功上线,进而添加了更多的 Shard 服务器,现在数据已经更加的均衡,通过在Slave上运行 repairDatabase(),然后将其切换到 Master ,每台 Shard 内存占用缩减到 20GB左右。整个故障时间已经延续了 11 小时之多。

产生问题的主要原因就是系统过载,前面介绍每台 Shard 承载原来 50% 的压力,到了问题发生的时候,单台 Shard 的负载已经超过 Shard 之前的系统负载,这时候已经积重难返了,在容量的临界点增加新系统资源,必然导致更多的停机时间。暴露了 Foursquare 团队在容量规划方面的不足之处,或许也因为业务增长太快了吧。另外,内存碎片化的问题在没有宕机之前,技术团队应该没考虑过这个问题,如果文档的大小超过 4K,碎片化问题就不严重了,这是特定应用场景造成的特定问题。10Gen 现在已经着手研究如何进在线压缩(online compaction)。再次,Shard 键值的顺序和插入顺序是不同的,这造成了迁移数据的时候 Chunk 的迁移不是连续的。

这个过程给我们的启示是:最近 NoSQL 已经成为一个热词,类似 MongoDB 这样的新事物当然值得尝试,但是不能冒进,因为驾驭起来并非易事。仅仅能够使用是不够的,系统没出问题一切都好,一旦出了异常,有足够的技术力量(设想一下 Foursquare 得不到 10gen 团队的支持会如何?) 支持么?在极端情况下如何控制? 如果回答不了这个问题,那么还应该暂缓。最好的办法就是…「等待」。

给我的另一个感慨是 Amazon 在云计算领域已经真的成为一个赢家,而且越来越得到 Web 2.0 Startup的信赖。前面说的 66GB 内存,应该指的是EC2 的 “High-Memory Double Extra Large Instance”,可提供的最大内存是 68.4 GB 。CPU 和内存能力都是可以接受的,存储方面的性能似乎还有点不足,也就是其中的 EBS ,指的是 Amazon Elastic Block storage。

–EOF–


25 thoughts on “Foursquare 长达 11 小时的宕机”

  1. Kimi

    很好的案例,值得关注一下,使用新技术最大的风险就是如何能在突发情况下得的解决方案。

    Reply ↓
  2. k8k4

    Foursquare 2.0版上线:多项功能得到调整… 【搜狐IT消息】北京时间9月21日消息,据Techcrunch科技网站报道,美国地理位置社交网站Foursquare已于20日宣布推出2.0版

    Reply ↓
  3. luckgo

    请教:
    能不能实现一种数据库表做堆栈用,或者说,实现固定记录数的表,比如固定100条记录,数据表满时,如果再插入,那么第一条记录自动删除,依次类推。
    程序可以实现,问题是性能问题不能确定,现在想到一个办法是定期删除过期记录(手动或计划任务),但感觉不是很爽,有没有爽的办法。还有是自增ID问题,假如记录数过多,自增ID也会超过最大值,从而导致错误,现在想到的办法是定期更新表结构,即删除自增ID列,再重新创建此列。请问下还有没有别的办法?

    Reply ↓
  4. gengmao

    仔细看了10gen的邮件,MongoDB把数据文件mmap到virtual memory,依赖os paging去完成disk读写——这也太省事了!
    市面上数据库有几个不是自己管理内存和I/O的?对MongoDB的印象大打折扣了

    Reply ↓
  5. 王新坤

    很切实际,面对现实有点无奈。另外问一下,实习生招聘这么快就结束了,难道我没机会了?

    Reply ↓
  6. Xinyu

    个人认为,对特定应用如SNS来说,NoSQL是趋势。相关的支持技术、管理人员都会逐步跟上。foursquare这次事件,对其自身是坏事(其实也不完全),对其他公司包括正在用和考虑用的,都是好事。

    Reply ↓
  7. LAONB

    太专业,看不懂。都是DBA的活。
    4SQ在国内用GPRS速度不给力,不过优点是可以认识更多的同城好友。

    Reply ↓

Leave a Reply

Your email address will not be published. Required fields are marked *