你肯定想不到,一个小小的表情包能惹出多大的祸。这个表情包来自经典美剧《老友记》第九季第20集,就是詹妮弗·安妮斯顿演的瑞秋听说要在楼顶办肥皂剧派对,高兴得手舞足蹈的那段。它大小只有1.6MB,但因为特别受欢迎,在一个叫Discourse的社交平台上被反复用了24万6千多次。



问题是,每次用的时候,系统都会把它重复备份一遍。结果这些备份加起来达到了377GB,还生成了超过24万次硬链接,直接冲破了Linux文件系统的容量上限,把备份机制给搞崩了。

Discourse这个开源软件,给超过两万两千个线上社区提供技术支持,里面的实时聊天功能可以插表情和GIF图。但它有个特殊的“安全上传”机制:当文件在不同安全场景之间转移时,比如从私信转发到公开帖子,系统会生成一个带随机加密值的新副本。文件本身一点没变,可系统就当它是新文件。所以一张热门图片或表情包在帖子、转发、私信里不断传的时候,每次都会生成一个新副本。

其实Discourse早就知道有重复文件挤爆系统的问题,最初的解决办法是用哈希值来追踪原始文件,备份时按哈希值分组,每组只下载第一个文件,重复的就创建硬链接。这方案听着不错,但Discourse用的Linux系统是ext4文件系统,虽然支持单个文件最大16TB、整个文件系统最大1EB,但每个文件最多只允许六万五千个硬链接。所以这套方案做不到24多万个重复文件只下载一次,到了上限之后,系统除了第一次下载,还额外多下载了大约18万次备份。

换句话说,搞崩系统的不是那些庞大的备份文件,而是疯狂的硬链接数量。

好在Discourse最后找到了完美的解决办法,思路还是创建硬链接,但一旦文件系统报出“链接数过多”的错误,就改在本地复制一份对应的文件,把新文件设为“主文件”,然后以它为基准继续创建硬链接,直到再次碰到上限。Discourse挺满意地说,这个新办法适用于所有文件系统,不用额外配置。在没法改文件系统的前提下,这么做完全能接受。

最后Discourse还调侃了一句:现在才知道,詹妮弗·安妮斯顿还能用来测试服务器压力。