什么是限流器?

限流器是一个服务或组件,其目的是限制接收请求的流量,以确保系统有能力处理所有的请求而不会被压垮。在这系列文章中,我们将讨论数据库系统限流器的设计考量,包括指标选择、粒度、行为、影响、优先级等话题。其核心目标是维护整个数据库系统的健康运行。


限流哪些请求?

数据库中的请求限流有不同的方式。在这里,重点关注异步任务、批量操作以及非关键时效的大型任务的限流。例如:

  • ETL(数据提取-转换-加载);
  • 数据导入;
  • 在线 DDL 操作;
  • 数据清理;
  • 数据分片调整等。

限流器会对这些操作进行限制,因为它们可能持续运行几分钟、几小时甚至几天。当然,限流器也可能作用于在线事务处理(OLTP)生产流量,本文的讨论对两者同样适用。
举个例子,假设一个任务需要向数据库导入 1000 万行数据。与一次性导入所有数据不同,这个任务会将最终操作拆分成更小的子任务,例如每次导入(写入)100行数据。在每次导入之前,任务会向限流器请求许可。
部分限流器实现支持协作,假定客户端会遵守其指令;而其他限流器则作为应用程序和数据库之间的屏障。无论是哪种方式,如果限流器判断数据库负载过重,任务就应该暂停一段时间,然后再次请求许可;此过程会一直重复,直到获得许可为止。每个子任务需要足够小,以确保不会单枪匹马压垮数据库的处理能力,同时保持效率以弥补限流器带来的开销,并实现任务的有效进展。


限流器如何定义限流?

某些通用限流器通过限制请求的固定速率来预测可处理流量的能力。然而,对于数据库而言,情况并不那么清楚。数据库在任何时间点或指定的时间段内只能处理有限数量的查询。此外,并非所有查询都是同等的。这种处理能力受以下因素影响:

  • 查询的范围;
  • 数据的热点或冷点;
  • 数据页缓存的状态;
  • 查询影响的数据重叠程度;
  • 数据是否在内存中,等等。

因此,我们需要解决以下问题:

  • 如何判断数据库是“健康”的?
  • 如何判断它是否已经“超载”?

为此,我们寻找定义或预测数据库服务级别目标(SLO)的指标。然而,事情并非总是简单明了。我们从一个被广泛用作限流判断的指标开始,看看它的特殊之处。


复制延迟(Replication Lag)

复制机制在数据库集群中尤其常见,比如主从(leader-follower)架构。复制延迟定义了从主库发生写操作到副本库完成或展示该操作之间的时间间隔。
在 MySQL 世界中,复制延迟可能是使用最广泛的限流指标。许多第三方和社区工具通过它来推迟长时间运行的任务。原因如下:

  • 易于测量:复制延迟直接反映主库和副本之间的状态。
  • 对业务的影响显著:例如,在数据库故障转移时,复制延迟会影响副本服务器的提升和写入能力。另外,低复制延迟让副本可以服务部分读取流量,例如支持即时读取写入后的数据(Read-after-write)。

因此,业务可能对复制延迟设有具体限制:低于这个延迟允许请求,高于这个延迟则推迟处理请求。


其他指标的考量

另一个常见的 MySQL 指标是 threads_running,它表示服务器上当前正在执行的并发查询数。尽管表明了数据库负载,但其“可接受值”难以界定。原因如下:

  • 某些值可能在清晨是接受的,但在流量高峰时则不适用;
  • 随着产品演进,查询数量和负载随之增加;
  • 部分查询的资源消耗显著不同,因此不能一概而论。

threads_running 更像是一个**症状**而不是实际原因的指标。比如:

  • 活跃查询数激增可能是某些查询停留在提交队列(commit queue);
  • 查询因争夺数据热点而等待锁;
  • 请求的数据页不在内存中,导致查询在页面缓存中产生拥堵;

对于限流器而言,与其将 threads_running 信息看作无用,不如深入分析这一指标背后的潜在原因。


队列现象的观察

复制延迟和活跃查询数一样,它们往往是队列(queue)的症状。例如:

  • 繁忙磁盘 I/O 堵塞副本导致复制延迟积累;
  • 网络延迟同样可能是复制延迟的原因。

尽管实际原因复杂多样,但复制作为队列的机制很直观:主库的写操作转化为复制事件,在副本处等待消费(处理)。复制延迟就是事件在队列中经历的时间。从另一个角度来看,事务提交时间延迟也可以测量为事务队列延迟。
但设定“良好阈值”仍取决于硬件环境和对指标的理解。例如,事务提交延迟取决于磁盘写入/刷新时间,硬件性能直接影响其表现。此外,队列长度(剩余等待请求数)也是常用的指标。虽然长队列不一定是坏事,但它能预测等待时间。有时候,当很难测量等待时间时,队列长度则是替代指标。


数据库连接池使用率

一个重要指标是应用程序的数据库连接池使用情况。通常情况下,如果池中有足够的连接,执行查询时即可分配到连接而无等待成本。但如果池耗尽,应用程序可能需等待新连接或抛出失败错误。高连接池使用率暗示了操作拥堵。池大小虽可能是任意的,但其选择通常基于硬件性能或数据库限制,并且池耗尽是系统负载过高的重要指标。


多指标组合的重要性

限流器应能够根据**多种指标**组合进行限流,而不仅限于单一指标。例如:复制延迟、事务队列长度、连接池使用率等。管理员可以为每种指标设置阈值,甚至动态添加新的指标。


限流器下的系统行为

启用限流器后,系统通常表现为以下行为:

  • 操作会触及限流器的阈值,比如复制延迟上升到允许范围。
  • 当限流器控制下,数据迁移或大规模操作会稳定在阈值附近运行(如复制延迟保持在 5 秒上下)。
  • 系统始终保持健康,而不会因操作增加而崩溃。

检测间隔及粒度对限流器的影响

限流器收集指标的间隔以及指标粒度将显著影响其效果。例如:

  • 较长的检测间隔(如 5 秒)可能会错过系统负载激增的信号,需数秒后才能反应过来,从而降低整个数据库的操作能力;
  • 粒度过低时,可能会导致更多系统资源的浪费。

总结

限流器是系统中的重要组件,它能根据负载的动态变化自适应推迟任务请求,从而避免系统被压垮。通过多指标组合、合理校准粒度与间隔,以及对限流系统行为的分析,数据库可以在处理高负载任务时始终维持健康状态,保证服务的稳定性和性能优化。



窥探限流器架构:第一部分插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:https://choupangxia.com/2025/09/14/anatomy-of-a-throttler-part-1/