技术解读 GaussDB (for MySQL) 流控机制
本文分享自华为云社区《【华为云MySQL技术专栏】GaussDB (for MySQL)流控技术解读》,作者:GaussDB 数据库。
本文主要介绍 GaussDB (for MySQL) 在不同服务层次上是如何实现过载保护的,具体包括反馈式和主动平滑流控两种机制。
1.背景介绍
GaussDB (for MySQL)是存储计算分离架构的云原生数据库,如图 1 所示:
GaussDB (for MySQL)存算分离架构,主要分为 3 层:
SQL 计算层,包括多个数据库实例,每个实例有 1 个主节点和多个只读节点;
DFV 存储层,由 DFV 存储服务的多个节点组成,这些节点协同,为上层应用提供高效的日志读写与页面读取能力。
SAL 层,即存储抽象层,位于 SQL 计算层和存储层之间。其中位于计算节点的部分,称为 SAL-SQL 层。
DFV 存储层对数据按照 slice 进行分片(每个分片 10G),SAL 层则根据 Slice 粒度进行数据管理。
在计算层,不同租户的多个数据库实例会共享同一个存储服务。当其中一个或多个用户实例处于压力过载时,可能会对共享存储池产生冲击,造成存储服务的 CPU、内存或者 IO 资源的瓶颈,进而影响服务稳定性。
GaussDB(for MySQL) 的过载保护机制分布在 SQL 层、SAL 层以及存储层多个层级,能够基于不同维度进行分级流控。
2. 分层级的流控机制
按照流量控制方向,GaussDB(for MySQL) 的过载保护分为两种机制:第一种是由下层到上层的反馈式流控,即存储层流控后,驱动计算层流控;另一种则是计算层主动流控,精细化控制上层流量。
2.1 存储层反馈式流控
存储层的反馈式流控是存储过载保护的主要机制。由于存储服务的每个 Server 会管理不同数据库实例的多个 Slice,因此,需要在存储节点级过载保护的基础上,完成实例级、Slice 级别的精确流控和分级限流。
整个流程概括为以下几个步骤:
第一步,对存储节点的关键资源和业务指标进行监控,并生成资源状态、指标统计等;
第二步,在存储层流控,基于以上状态和统计进行策略判断和决策;
第三步,将过载信息反馈计算层流控。
2.1.1 存储层流控策略
在存储节点的消息处理流程中,通过增加多处限流检查点,分别观测内部消息处理队列、任务队列、内存资源。例如,回放日志所需的 Delta Cache、待处理 Pending Table 等,均可以作为输入监控指标。
在以上的限流检查点,可以采用多种策略进行控制:
第一种方式:通过关联较少的资源,设置单一阈值进行限流,对上下游影响较小。这里以盘级流控为例,如图 2 所示,每个存储节点管理多块存储磁盘,每个磁盘处理读写请求相互独立。通过监控每个磁盘的读写频率和读请求时延,来判断其是否超过阈值。如果超过,则为热点盘。
热点盘上有多个活跃 Slice,如果某个 Slice 的写速度超过平均速度,则按照阶梯进行限速。图中 Slice4 的写入速度 30MB/s 超过平均速度 20MB/s,因此,需要将 Slice4 进行限速。
第二种方式:对 Delta cache,Pending Table 等内存资源,进行使用率实时统计,识别出活跃 Slice,再按照周期汇总计算出下一周期的可用配额,对当前活跃 Slice 进行公平分配;基于使用情况,可设置多个级别实施不同梯度的控制策略。例如,占比 60%为流控触发点,进入基础限流阶段,设置 80%为过载点,90%为停止服务阈值。其中,基础阶段采用线性流控,过载阶段则采用比例限速。
如图 3 所示,3 个数据库实例共有 6 个 Slice 分配到当前存储节点,当前周期总的写入速度是 30MB/s, 平均分配给每个 Slice 的配额是 5MB/s。
第三种方式,对于节点的 IO 资源,系统也支持根据租户设置的 QoS(Quality of Service,即服务质量)阈值,来触发流控机制。例如,对某租户的 Slice 进行标记,在 IO 流控时,可以给予更大的配额。
基于上一周期的流控情况,迭代更新下一周期的流控策略,这样能够达到快速调整实时流控,并及时反馈到计算层,进而触发计算层的流控。
SQL 节点的用户查询需要及时响应,可视为前台业务,而存储节点内部的数据合并等操作,通常不需要及时响应,可作为后台业务。针对前后台业务的差异性,GaussDB(for MySQL)支持优先级策略,并能够识别故障组件并进行隔离,从而避免少量业务影响整个系统运行。
此外,流控后也能够及时恢复,快速解除限流状态。
2.1.2 计算层流控策略
存储层流控时,通常设置每个 Slice 一个周期的可写入流量上限阈值,即 WAL 阈值(Window Access Limit)。例如,当前时间窗口 Slice1 的写入上限为 2MB,SAL-SQL 层查询得到该上限阈值,基于此,可以在数据流转过程中进行有效限速。
如图 4 所示,计算层数据库实例的限速点分布在 SQL 层和 SAL-SQL 层。
第一个限速点在 SAL-SQL 层。SliceFlush 线程将每个 Slice 的日志发送给存储服务,此时,系统需要进行限速判断,具体这里包括以下几点:
首先,Flush 机制是积攒日志量到一定数量(例如 64K)或者一定时间后才会 Flush,避免频繁发送过小的请求;
其次,判断逻辑按照周期进行(目前周期为 1s),根据每个周期的写入量和写入配额(即 WAL,Write Access Limit)来决策,分为以下几种情况:
如果待发送的数据量小于当前周期的配额,则直接发送;
如果超过当前配额,且当前窗口配额没有被预消费,则超发当前数据,并且预消费接下来周期的配额;
如果当前窗口已经被之前的窗口预支,则需要补偿,限流不发送数据。
另一个限流点是 SQL 层。在 mtr(mini-transaction)提交时,检查 SAL 层的流控状态、内部资源情况,再结合 Slice 维度统计的日志积累情况,进行多级别的流控策略。其中,主关键指标是 TLB(Transport Log Buffer)的使用情况。TLB 是 SAL 层内部按照 Slice 把上层写入日志整理合并,并发送给一个 Slice 的 Log buffer。详细策略包括:
当内部资源处于基本限流阶段,即 mtr 涉及到的 Slice 处于流控时,则系统会根据日志积累量,换算出相应的等待时间,从而执行睡眠操作,以实现 Slice 的缓慢提交。
当内部资源过载阶段,则禁止提交 mtr,直到过载解除。
同时,按照相同顺序进行限速和解除限速,避免不公平的限速导致某些线程饿死。
2.2 计算层主动平滑流控
单个数据库实例在读写压力过载,甚至超过资源瓶颈时,也可能出现雪崩现象,导致整体业务响应出现异常。例如,某种子业务突增,引发大量的并发批量读请求,会导致同一实例的其他业务请求也受到影响,因此,对计算层进行流控也是必要的。
在计算层数据库节点上,分别针对读写请求,进行细粒度平滑流控,可以避免计算节点本身过载。
首先,在 SAL-SQL 层,数据库节点会统计每个周期的日志写频率和页面读取频率,作为核心指标。这些统计包括同步请求和异步请求,将其统称为页面更新频率。统计过程具体是在 SAL 层日志写链路和页面读取接口实现。
其次,根据数据库节点的读写能力,按照不同规格预设合适的读写阈值上限。当统计到的页面读写频率超过对应的读写阈值时,触发主动平滑流控机制。
主要的控制逻辑分为两种:
Strong 限流,即需要当前线程 sleep,直到指标降低到阈值内;
Weak 限流,通过算法计算出等待时间,并 sleep 一定时间。
目前有 3 个控制点:
Redo 日志加入 SAL-SQL 层调度线程时,如图中限流点 1 所示,如果日志写频率超过写阈值时,则进行 Strong 限流,否则按需进行 Weak 限流。
在每个 Slice 刷新线程中进行 Weak 限流,如图中限流点 2 所示。
在页面读取链路中,根据页面读取频率和阈值进行 Weak 限速。
概括来说,等待时间是基于放大倍数和一个基础步长来决定的。其中,放大倍数能够快速放大等待时间,达到快速流控的效果。放大倍数是根据页面频率超过阈值的比例来决定的,目前设置 4 个级别,分别对应 1-4 倍。基础步长是权衡性能消耗和流控灵敏度之后的一个预设参数值。
同时,在限速阶段,采用串行队列管理机制来处理并行提交的请求,确保按照先来的请求先得到处理。
3. 流控效果
为了演示反馈式流控,我们对多个数据库实例同时进行压力测试,包括:
2 个 8U,2 个 16U,13 个 32U 规格实例,按照某真实业务读写比例 1:4 的业务模型进行 sysbench 读写压测,每个实例 64 张表,单表 1000 万行;
5 条数据迁移链路,其中 5 个 32U 规格实例作为目标端,插入数据。实验过程中,通过人工降低存储层流控触值,模拟触发流控场景。
可以观察到压力上涨触发存储层流控后,较大写入压力的计算节点实例的 QPS 下降,系统处于限流状态。恢复阈值后,限流状态解除,业务 QPS 恢复,如图 6 QPS 所示。同时,较小写入压力的计算节点实例,对 QPS 无影响,如图 7 QPS 所示。
图示数据对比说明,反馈式流控可以精准的控制大压力数据库实例。
接下来演示计算层主动平滑流控。
首先,对一个 4U16G 实例进行 sysbench 读写混合模式压测,观察其读写的页面频率指标。其日志写频率为 6093 次/秒,页面读频率为 3195 次/秒。
其次,通过运维平台设置较小的读写阈值。
本实验设置日志写阈值为 4500 次/秒,页面读阈值为 3000 次/秒,随后可以观察到很快触发平滑限流,业务 QPS 快速下降,且较为平稳的维持在一个限流后的水位,并该状态一直持续到测试结束,整体效果图 8 所示。
4. 小结
本文详细分析了 GaussDB (for MySQL) 在不同层级的流控机制,包括反馈式流控在存储层和计算层的策略和流程,以及计算节点的主动平滑流控的方案。作为过载保护的主要手段,流控一方面可以避免流量过大造成服务资源耗尽产生雪崩效应,另一方面也力求高效快速,尽可能地充分利用服务资源,产生更大价值。
评论