并发与吞吐量:为何更多并行反而会让数据库变慢

并发与吞吐量:为何更多并行反而会让数据库变慢

💡 原文英文,约1700词,阅读约需7分钟。
📝

内容提要

数据库并发与吞吐量并非线性关系。文章通过MySQL故障案例说明,高并发会因锁竞争和快照版本链重建导致吞吐量骤降。解决方案是降低事务池大小并引入排队机制,模拟线程池行为,以控制并发、吸收突发流量。核心原则是:面对共享资源竞争,限制并发反而能提升总吞吐量,需根据工作负载特性谨慎应用。

🔎

延伸解读

并发与吞吐量的非线性关系

文章通过MySQL故障案例说明,并发与吞吐量并非线性关系。当并发增加时,由于锁竞争和快照版本链重建,每个请求的执行时间会变长,导致总吞吐量下降。Gunther的通用扩展定律指出,当并发超过临界点后,协调开销(β项)会随并发数的平方增长,最终使吞吐量不升反降。因此,限制并发有时反而能提升整体性能。

线程池与事务池的差异

Cloud SQL的线程池在池满时排队等待,而Vitess的事务池在池满时直接报错。这种差异导致应用在迁移后无法处理池满错误,加剧了故障。解决方案是将事务池大小从一万降至一千,并引入排队机制,模拟线程池行为。这说明了中间件设计对系统稳定性的重要影响。

限制并发的适用场景

并非所有工作负载都适合限制并发。文章指出,对于使用悲观锁、存在热点行、长事务等场景,限制并发可能提升吞吐量。但对于其他类型的工作负载,可能需要不同的策略。因此,在应用此原则前,需仔细分析工作负载特性,避免盲目限制并发导致性能下降。

Q&A

为什么数据库并发越高,吞吐量反而可能下降?

根据通用可扩展性定律,并发增加会带来竞争(α)和一致性(β)成本,其中一致性成本与并发数的平方成正比。当并发超过临界点后,协调开销会主导,导致总吞吐量下降,即所谓的“倒退扩展”。

MySQL故障案例中,为什么一个长时间运行的事务会导致数据库崩溃?

一个批处理事务持有行锁15分钟,导致InnoDB需要为并发读取重建快照版本链,版本链不断增长,使得读取变慢,应用重试导致请求堆积,最终耗尽缓冲池,影响其他无关查询,引发级联故障。

在MySQL故障中,为什么提高事务池大小反而使问题更严重?

提高事务池大小到10000后,限制了Vitess控制背压的能力,允许过多请求进入存储引擎,加剧了快照版本链重建和缓冲池压力,导致吞吐量骤降。

如何解决高并发导致的数据库性能下降?

解决方案是降低事务池大小(从10000降至约1000),并引入排队机制,让请求在池满时等待而不是报错,模拟线程池行为,以控制并发、吸收突发流量。

哪些工作负载适合限制数据库并发?

适合限制并发的工作负载包括:使用悲观锁和共享状态竞争、热行被多工作者更新、对热门键执行SELECT FOR UPDATE、长事务持有锁但做无关工作、以及涉及计数器、余额、任务队列等场景。

PostgreSQL如何应对高并发问题?

PostgreSQL可以通过PgBouncer的事务池来限制服务器端并发,允许更多客户端连接但限制实际执行的并发数,从而避免高并发导致的性能下降。

什么是Little's Law,它如何解释并发与吞吐量的关系?

Little's Law指出在稳定状态下,在途请求数N等于吞吐量X乘以响应时间W,即N=X*W。如果增加并发导致每个请求的执行时间增加,那么吞吐量不会线性提升,甚至可能下降。

🏷️

标签

➡️

继续阅读