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 *