MySQL如何实现每秒百万次查询?

发表时间: 2023-06-28 14:17

【编者按】本文主要介绍 PlanetScale 是如何通过 MySQL 的水平分片支撑每秒一百万个查询(QPS)的。

原文链接:https://planetscale.com/media/one-million-queries-per-second-with-mysql

未经允许,禁止转载!


作者 | Jonah Berquist 译者 | 明明如月
责编 | 夏萌
出品 | CSDN(ID:CSDNnews)

本文主要介绍 PlanetScale 是如何通过 MySQL 的水平分片支撑每秒一百万个查询(QPS)的。

如果你使用的数据库拥有良好的扩展性,用起来会更省心。我们推出了基于 Vitess 的 PlanetScale,旨在最大程度上利用其出色的可扩展性。水平分片是他们在扩展性方面的一个重要优势。为了展示水平分片的实力,我们决定做一些基准测试。

我们设定了一个 PlanetScale 数据库,开始运行一些常见的 sysbench-tpcc 工作负载的基准测试。我们此次的目标并不是追求严格的学术基准,而是想使用一个广泛知晓且实际的工作负载进行测试。在将来,我们会发布更多基准测试的文章,并且我们已经开始和一家学术机构合作,他们不久后将公布自己的研究成果。

这篇文章的目标有两个:一是展示 PlanetScale 处理大规模查询的能力。为此,我们设定了每秒处理一百万次查询的目标。从 Vitess 的视角来看,这并不是个大集群。虽然有许多 Vitess 集群的查询量更大,但我们认为这是个合理的基准。二是通过水平扩展来展示可预见的扩展性。提高吞吐量的能力就像添加更多机器一样简单。


增加分片数量实现拓展


我们的初始数据库并未进行分片,随后我们设定了一个虚拟模式并开始分片操作。我们倾向于选择 2 的幂作为初始的分片数量,因此我们选择了从两个分片开始,并在接下来的操作中逐步翻倍分片数量。在每个分片级别,我们都会运行若干次 sysbench,每次运行时的线程数量也会逐渐增加。在每一轮的迭代过程中,我们观察到一个现象:超过一定程度后,线程数量的增加不再引导吞吐量的增长,反而当吞吐量达到上限后,查询的延迟会有所提升。

在下图,你能看到的是对一个含有 16 个分片的数据库进行操作的结果。你可以看到,随着 sysbench 线程数量的增加,连接数量也同步上升。同时,随着线程数量的提升,每秒的查询吞吐量也相应增长。


达到极限


然而,当每个分片所占用的资源逐渐达到其容量上限时,我们开始观察到系统的性能提升效果逐渐减弱。这一点在比较 1024 线程与 2048 线程间以及 2048 线程与 4096 线程间的 QPS 增长时尤为突出。同样,在下面展示的 vtgate 指标中,当我们的吞吐量接近峰值时,我们观察到查询的延迟开始升高 ,尤其是在 p99 延迟中尤为明显。

到了这一步,我们就知道是时候要增加更多的分片进一步提高吞吐量了。


增加更多分片


在下面数据中,你可以看到,随着我们翻倍增加分片数量,每秒的查询数量也大体上成倍增长。当我们拥有 16 个分片时,我们的最大 QPS 约为 42万。而当我们增加到 32 个分片时,我们达到了 84 万QPS。尽管我们有能力无限地增加分片数量,但我们设定了一个目标,那就是实现每秒一百万次查询的能力。


实现每秒一百万次查询


需要强调的是,虽然我们更偏向选择 2 的幂作为分片数量,但这并非硬性规定,我们完全可以采用其他数量的分片。考虑到我们在拥有 32 个分片时,QPS 刚好超过 80万,我们推算出,大约 40 个分片应该能满足我们 100万QPS 的需求。当我们启动该数据库并使用并行的 sysbench 客户端对其进行测试时,结果如我们所期待一样:在运行 5 分钟的时间内,每秒查询量超过了一百万次。

我们在一个单租户环境下进行了这项基准测试,基准测试中使用的资源级别是针对企业级客户准备的。为了适应这个 sysbench 工作负载,我们还进行了一些非标准的配置调整,包括调高一些查询和事务的超时设置。