今天是个值得庆贺的日子
前几天 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--
也反应一点,他们的监控做得不够,在问题出现之前,应该在监控的时候,会有反应的。
谢谢分享
要做到未雨绸缪 提前规划
所谓 无远虑 有近忧
谢谢分享
今天的确是个值得庆祝和纪念的日子。
很好的案例,值得关注一下,使用新技术最大的风险就是如何能在突发情况下得的解决方案。
现在好像还不能访问
亚马逊云计算部门有个DBA伙计,刚上班两个月,就在圣诞节加班两个通宵. 外面看着风光, 里面辛苦呀.
新东家的全部服务器跑在Amazon上,包括测试环境。目前略知一二 :p
好像还不能访问
跟五月份Reddit在Cassandra上遇到的情况差不多,平时没有注意到性能瓶颈,等到发现再去补救已经无力回天,越增加节点越糟糕。分布式Key-Value数据库好像都没有太好的办法对付这种情况。
http://blog.reddit.com/2010/05/reddits-may-2010-state-of-servers.html
我来学习了。
Foursquare 2.0版上线:多项功能得到调整... 【搜狐IT消息】北京时间9月21日消息,据Techcrunch科技网站报道,美国地理位置社交网站Foursquare已于20日宣布推出2.0版
这么长时间?真恐怖&!@
请教:
能不能实现一种数据库表做堆栈用,或者说,实现固定记录数的表,比如固定100条记录,数据表满时,如果再插入,那么第一条记录自动删除,依次类推。
程序可以实现,问题是性能问题不能确定,现在想到一个办法是定期删除过期记录(手动或计划任务),但感觉不是很爽,有没有爽的办法。还有是自增ID问题,假如记录数过多,自增ID也会超过最大值,从而导致错误,现在想到的办法是定期更新表结构,即删除自增ID列,再重新创建此列。请问下还有没有别的办法?
这样的实现成本是是不是太高了呢?
倒也算个方法,但是异常会比较难处理。
仔细看了10gen的邮件,MongoDB把数据文件mmap到virtual memory,依赖os paging去完成disk读写——这也太省事了!
市面上数据库有几个不是自己管理内存和I/O的?对MongoDB的印象大打折扣了
MongoDB性能不过如此,到跟宕机并没有直接关系吧?
很切实际,面对现实有点无奈。另外问一下,实习生招聘这么快就结束了,难道我没机会了?
DB简单一点,就需要监控用点心。
关于Foursqure宕机,这里也有一篇文章值得看看 Troubles with Sharding - What can we learn from the Foursquare Incident? http://highscalability.com/blog/2010/10/15/troubles-with-sharding-what-can-we-learn-from-the-foursquare.html
都不记得Foursquare什么时候无法访问的了
个人认为,对特定应用如SNS来说,NoSQL是趋势。相关的支持技术、管理人员都会逐步跟上。foursquare这次事件,对其自身是坏事(其实也不完全),对其他公司包括正在用和考虑用的,都是好事。
不是在升级么?无比的nosql
太专业,看不懂。都是DBA的活。
4SQ在国内用GPRS速度不给力,不过优点是可以认识更多的同城好友。
这是为什么?