严格的测试对于我们的工程流程至关重要。我们核心的功能具有挑战性,要求我们满足严格的正确性和性能标准。不仅在正常操作期间,而且在各种故障场景下,都必须维护数据保证和事务完整性。同时,我们旨在实现诸如低延迟和接近线性的可扩展性等性能目标。为了应对这些挑战,我们使用了强大的仿真,实时性能测试和基于硬件的故障测试的组合方案。
仿真是测试系统正确性的强大工具。我们的仿真技术称为Simulation,它是由Flow(基于基于角色的并发的编程语言)启用并与之紧密集成的。除了生成有效的生产代码外,Flow还与Simulation一起用于模拟执行。
模拟的主要目的是确保我们在模拟而非现实世界中发现并诊断问题。仿真每天晚上进行数万次仿真,每一次仿真都会模拟大量的组件故障。根据我们运行的测试量以及场景中失败的加剧程度,我们估计在FoundationDB上运行的模拟时间大约相当于一万亿CPU小时。
仿真能够在单线程进程中对整个FoundationDB集群进行确定性仿真。确定性至关重要,因为它可以使模拟运行具有完美的可重复性,从而有助于受控实验解决问题。模拟逐步穿越时间,在整个系统中同步,以较少的模拟时间表示大量的实时时间。在实践中,我们的仿真通常具有大约10-1的实际仿真时间因子,这对于提高测试效率是有利的。
我们进行了广泛的模拟测试,测试了系统的各个方面。例如,我们运行一个循环测试,该测试使用排列在环中的键-值对执行事务以更改环的值,以维护环的完整性,从而明确测试事务隔离。
仿真从集群中的计算机数量和类型开始,模拟FoundationDB系统的所有物理组件。例如,仿真模型可以驱动每台机器上的性能,包括驱动器空间和驱动器填满的可能性。仿真还对网络进行建模,允许少量代码指定数据包的传递。
我们使用Simulation来模拟网络,计算机和数据中心级别的故障模式,包括连接故障,计算机性能下降,计算机关机或重启,计算机死机等。我们对所有这些故障模式进行压力测试,在非常短的间隔内使机器发生故障,导致异常严重的负载,并延迟了通信通道。
一段时间以来,工程团队内部进行了一场非正式的竞赛,以设计失败,发现最棘手的错误并最轻松地解决问题。经过一段时期的补习,这位在位的冠军被称为“抽izz”。要阻塞,首先要在集群中随机选择节点的子集。然后,您在几秒钟内一次“阻塞”(停止)它们的每个网络连接。最后,您以一个随机的顺序一次又一次地取消堵塞它们,直到它们全部起来。这种模式似乎特别适合发现仅在最罕见的现实情况下才会发生的深层问题。
模拟的成功超出了我们的预期,对我们的工程团队至关重要。如果没有这项技术,我们似乎不可能建立FoundationDB。
除了模拟之外,我们还继续在FoundationDB上运行系统的性能测试。每天晚上,我们使用“马戏团”环境运行一套自动化的性能测试套件。
对于每个马戏团测试,我们指定要使用的数据库的特征,例如20亿个键值对(具有16个字节的键)和随机生成的8-100个字节的值。该测试选择要运行的工作负载以及要在其上运行的集群。工作负载指定要执行的读取和写入的特征和比例。 (有关代表性示例,请参见“性能”页面。)测试可以并行或顺序运行工作负载。使用与仿真相同的代码指定工作负载,这有助于提高测试效率。
通过此过程,我们可以每天比较当前代码库与前几天的性能。性能是从许多测试的输出得出的多个维度上进行衡量的。我们的数据探究技术允许以图形方式探究此输出,并具有隔离和检查关键绩效指标的能力。