本周该公司发布了一份内容冗长、极其详细的事后分析报告,描述了去年持续整整三天的重大故障事件,所有从事企业基础架构工作的人都应该认真读一读。
Roblox声称:“无论持续时间还是复杂程度,这次故障都是的。”而这种说法未免轻描淡写。在互联网上,三天这段时间实在太长了;去年10月的,Facebook宕机了短短几小时,全世界就一度为之抓狂。
Roblox管理自己的基础架构,这对于一家成立于2004年的公司来说并不罕见。
该公司在这套基础架构上拥有的服务器超过18000台,还部署和管理自己的存储设备和网络设备。
它广泛依赖HashiCorp公司开发的技术,包括 Nomad、Vault和Consul。
Consul 是一类名为服务网格(service mesh)的新兴企业技术的一部分,它在帮助厘清导致这起故障的情形方面发挥了关键作用。
与大多数故障一样,这次故障一开始时是无害的,但随后在用于运行Roblox基础架构的软件层的深处发现了一个新的错误(bug)。
像Consul这样的服务网格其功能类似网络上的交通管制员,允许各个微服务相互通信,并交换完成工作所需要的数据。
乍一看,这似乎只是运行Consul集群的硬件出现的简单故障,但更换所有服务器后,性能依然受到影响。
由Roblox工程师和HashiCorp工程师组成的联合团队最终查明,在Consul核心一个名为BoltDB的开源日志记录项目在设计上所做的选择导致了瓶颈,而这完全是因Roblox的独特架构而暴露出来的。
之所以花那么长的时间来诊断问题,一方面原因是团队无法确定导致问题的到底是Roblox的选择,还是Consul内部某个存在缺陷的组件。事实证明,这两个因素多少都有所牵涉。
在过去的三个月间,Roblox对其基础架构进行了数次更改。
该公司表示:“在一个Consul集群上运行所有Roblox后端服务使我们遇到了这种性质的故障。”因此,它增加了第二个数据中心来运行后端服务,还计划在那些数据中心区域里面实施可用区(AZ)。
HashiCorp还在开发新版本的Consul,以取代BoltDB。
但是尽管如此,三大云提供商的销售代表还是没有从Roblox获得任何大笔的新业务。
“总的来说,我们发现,公共云对于并不注重性能和延迟,且在规模有限的环境下运行的应用程序来说是一种很好的工具。然而,针对我们那些非常注重性能和延迟的工作负载,我们所做的选择是在本地构建和管理我们自己的基础架构,”该公司表示。
衷心感谢Roblox对这起可能是该公司发展史上最严重的事件之一进行了如此详尽细致的分析。不过幸运的是,其核心受众很快就忘了这荏事。
BoltDB问题似乎直接归咎于糟糕的设计。需要空闲链表(freelist)很好,在每次追加后都需要将整个空闲链表同步到磁盘很可笑很荒唐。
我是BoltDB的开发者。是的,这是糟糕的设计。该项目从未打算投入到生产环境中,而是作为LMDB的移植版,因此我可以理解其内部结构。我简化了空闲链表的处理,因为这是一个小儿科项目。当时(2014年前后)Shopify在LMDB或Go驱动程序方面遇到了一些严重的问题,几个月后我们还是无法解决,于是我们换成了Bolt。遗憾的是,我这个糟糕的设计仍然存在。
LMDB使用常规bucket用于空闲链表,而Bolt只是将该链表作为数组来存储。它在相当大的程度上简化了逻辑,在大多数使用场合下通常不会引发问题。只有当有人写入了大量数据,然后删除数据、从不使用这些数据时,才会出现这个问题。Roblox声称有4G的闲置页面,这意味着一个含有4字节页面数的庞大数组。
我认为设计方面的选择该由我来负责,但是与大多数开源软件(OSS)软件一样,责任还是在于最终用户。看到一个错误给其他人带来这么大的麻烦总是糟透了。
至于HashiCorp,他们是一群很出色的人。没有几个开发人员比他们的CTO Armond Dadger更受本人尊敬的了。他是个绝顶聪明的家伙。话虽如此,实际生产环境中还是有很多不定因素,有时候错误还是趁虚而入。