暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ClickHouse Smart Auto-Scaling: 双窗口实现成本大优化!

ClickHouseInc 2026-05-06
62

本文字数:6095;估计阅读时间:16 分钟

作者:Ashwath Singh and Manas Alekar


Meetup活动


ClickHouse 上海第3届 Meetup 火热报名中,详见文末海报!



引言

数据库资源自动扩缩容需要精细的平衡:扩容过慢可能导致性能下降;缩容过于激进则会引发持续的资源震荡。我们此前的自动扩缩容系统采用单一的 30 小时回溯窗口来做出扩缩容决策。这虽然保证了扩容的快速和稳定,却导致缩容策略在设计上趋于保守。在流量下降后,一个集群可能需要长达 30 小时才能完成规模调整。

本文将探讨我们如何通过一个双窗口推荐器 (two-window recommender) 来解决这一问题:这是一种能够更积极地扩容并更快地缩容的双窗口方案。我们将这个双窗口框架与一套全新的目标跟踪 CPU 推荐系统相结合,替代了之前在多窗口环境下表现不佳的 CPU 推荐算法。

最终成果是:显著加快了缩容速度,最大程度地减少了扩缩容震荡,并大幅降低了可变工作负载下的基础设施成本,所有这些都在保持生产数据库所需稳定性的前提下实现。

注意:本文主要探讨垂直自动扩缩容,即调整每个副本的 CPU 和内存资源。有关水平扩缩容选项及用户侧配置,请参阅 ClickHouse Cloud 扩缩容文档(https://clickhouse.com/docs/manage/scaling)


问题:过长的回溯窗口

我们最初的自动扩缩容系统采用 30 小时回溯窗口来确定资源建议。这种方法有以下明显优势:

• 快速扩容 :当使用量激增时,系统会立即响应并进行扩容。

• 稳定性 :较长的窗口期有效避免了对瞬态波动的过度反应。

然而,它却在缩容方面造成了一个关键问题:

结果:在流量下降后,导致长达 30 小时的资源过度配置,不必要地增加了基础设施开支。

关键指标:系统追踪回溯期内的峰值(最大)使用量,而非平均使用量。如果基于平均值进行资源配置,则可能在高峰期造成容量不足,进而导致查询失败或性能下降。

我们需要一种方法,在保持快速、稳定扩容的同时,大幅提升缩容速度。


双窗口解决方案

我们不再只使用一个回溯窗口,而是使用两个时间范围不同的回溯窗口:

• 小窗口 (3 小时): 捕获近期使用模式,有助于更快地进行缩容 (scale-down)。

• 大窗口 (30 小时): 确保我们能一步到位地扩容 (scale-up) 到较长回溯窗口内观察到的最大使用量,而非多次渐进式扩容。这一点至关重要,因为扩容需要时间,并且会导致本地缓存失效;因此,一次性扩容更加安全。

在最终确定 3 小时之前,我们尝试了多种短窗口时长。1 小时窗口的响应过于灵敏,会导致缩容过于激进并引发系统振荡。而 6 小时窗口对缩容延迟的改善不够显著。最终,3 小时在响应速度和系统稳定性之间找到了恰当的平衡点。

每个窗口都会结合内存和 CPU 分析结果,独立生成一套推荐。系统随后会根据每个窗口所建议的扩缩容方向来合并这些推荐。



为每个窗口生成推荐结果


系统会为两个窗口并行生成推荐:

1. 小窗口 (3 小时): 分析近期的 最大 使用模式。

2. 大窗口 (30 小时): 分析历史的 最大 使用模式。

3. 前一个小窗口 : 获取上一次小窗口的推荐,用于趋势检测。

对于每个窗口,系统会并行执行基于内存和基于 CPU 的分析,并选择推荐资源更多的一方(由于 CPU 和内存以固定的 1:4 比例进行资源配比,因此这涵盖了两个维度)。随后,每个窗口的推荐将与当前的资源分配进行比较,以确定扩缩容方向:如果推荐更多资源则进行扩容,如果推荐更少资源则进行缩容,否则保持不变。



合并推荐结果


由于每个窗口关注的时间范围不同,它们可能会得出不同的结论。例如,小窗口可能观察到过去 3 小时内流量一直平稳,因此建议缩容;而大窗口可能还记得昨天的流量高峰,倾向于保持稳定,甚至建议扩容。此时的问题是:当它们的建议不一致时,我们应该选择哪一个?

大窗口(Large Window)
小窗口(Small Window)
最终建议(Picked Recommendation)
原因(Reasoning)
扩容(Scale-up)
扩容(Scale-up)
大窗口
一步到位扩展到长期峰值
扩容(Scale-up)
不变(No change)
小窗口
近期使用稳定,暂不扩容
扩容(Scale-up)
缩容(Scale-down)
抖动检查(Hunting check)
如果小窗口呈上升趋势,使用大窗口避免抖动;否则使用小窗口
不变(No change)
扩容(Scale-up)
不可能(大窗口包含小窗口数据)
不变(No change)
不变(No change)
小窗口
不变
不变(No change)
缩容(Scale-down)
抖动检查(Hunting check)
如果小窗口呈上升趋势,使用大窗口避免抖动;否则使用小窗口
缩容(Scale-down)
扩容(Scale-up)
不可能(大窗口包含小窗口数据)
缩容(Scale-down)
不变(No change)
大窗口
服务可能处于空闲/停止状态
缩容(Scale-down)
缩容(Scale-down)
小窗口
更快的缩容

当两个窗口的趋势一致时,我们选择小窗口进行缩容(速度更快),选择大窗口进行扩容(一步到位达到峰值)。当它们趋势不一致时,我们执行抖动检查(Hunting check)。某些情况根本不可能发生,因为大窗口完全包含了小窗口的数据。



防止抖动


为了防止抖动,系统会使用之前小窗口的建议。当窗口意见不一致时(例如大窗口建议扩容,而小窗口建议缩容),系统会检查小窗口的建议是否呈上升趋势。

示例:在高 CPU 使用率消退后,实际利用率(蓝点)下降,随后开始缓慢上升。大窗口(黄色)保持其建议不变。小窗口(绿色)在峰值过后迅速下降。如果没有抖动检查,双窗口合并逻辑将在两个窗口之间交替信任,从而产生红线,在缩容和扩容之间反复切换,导致系统震荡。抖动检查通过在小窗口呈上升趋势时信任大窗口来防止这种情况发生。

抖动检查条件current_small_window > previous_small_window

• 如果呈上升趋势 :信任大窗口(使用率正在上升,这可以防止抖动,并能一步到位地扩容,而非逐步扩容)。

• 如果稳定或下降 :信任小窗口(此时缩容是安全的)。

在双窗口框架 (two-window framework) 部署后,我们需要 CPU 和内存推荐器为每个窗口生成资源建议。然而,我们现有的 CPU 推荐器采用固定伸缩因子 (fixed scaling factors),存在一些问题,而双窗口方法使得这些问题显著加剧。


固定因子 CPU 伸缩问题

我们最初的 CPU 推荐器采用了一种基于阈值 (threshold-based) 的方法:

if utilization > 75%:  scale to 2× current recommendation

if utilization < 37.5%: scale to 0.5× current recommendation

otherwise: no change

将其与双窗口方法结合使用时,产生了两个主要问题:



跨窗口的级联扩容 (Cascading Scale-ups)


固定因子算法 (fixed-factor algorithm) 只能将上次推荐的资源量翻倍或减半,而无法直接根据实际峰值使用数据进行计算。由于两个窗口并行运行,这意味着即使 30 小时窗口观察到一个较大的峰值,也无法一步到位地调整到所需的合适规模。

例如,假设某个服务昨天达到 48 核的峰值,但此后已下降到 12 核:



短窗口下的震荡 (Oscillations)


对于较短的窗口,2 倍的伸缩因子 (scaling factor) 导致了严重的震荡:

Hour 0: 50 cores allocated, 40 cores used (80%) → Scale to 100 cores

Hour 3: 40 cores used 100 allocated (40%) → Scale to 50 cores

Hour 6: 40 cores used 50 allocated (80%) → Scale to 100 cores

Hour 9: Repeat...

结果:每隔几个小时就会出现持续的伸缩干扰,即使使用量只有微小变化。

我们需要一种基于实际使用量而非历史推荐进行伸缩的方法。


基于目标跟踪的 CPU 推荐


为解决这些问题,我们将固定因子算法替换为目标跟踪 (Target-tracking)。目标跟踪根据目标利用率指标 (target utilization metric) 来调整容量。它不再是将资源分配 (allocations) 加倍或减半,而是计算出维持目标利用率水平所需的精确资源量。



目标跟踪的工作原理


该算法根据当前资源分配和水位线 (watermarks) 计算出一个阈值区间 (threshold band)。只有当峰值使用量超出此区间时,才会触发伸缩:

min_threshold = current_allocation × low_watermark

max_threshold = current_allocation × high_watermark


if peak_usage outside [min_threshold, max_threshold]:

    new_allocation = peak_usage ÷ target_utilization

else:

    maintain current_allocation

该算法通过伸缩来达到目标利用率,从而创建一个稳定的区间,使使用量可以在目标值附近波动而不会频繁触发伸缩事件。在我们当前的实现中,目标利用率是水位线 (watermarks) 的几何平均值 (Geometric Mean)。



为何选择几何平均值?确保可逆伸缩 (Reversible Scaling)


目标利用率被设置为水位线 (watermarks) 的几何平均值:

target_utilization = √(high_watermark × low_watermark)

# Example: √(0.75 × 0.375) = √0.28125 = 0.53

这确保了可逆伸缩 (Reversible Scaling):如果使用量恢复到某个值,资源分配 (allocation) 也会相应恢复到该值。

Start: 100 cores, 80 cores usage

Scale up to: 80 0.53 = 151 cores


Later, usage drops back to 80 cores:

With 151 cores: 80 151 = 53% (within thresholds, no change)


If usage later spikes to 120 cores:

Calculate: 120 0.53 = 226 cores


If usage returns to 80 cores again:

With 226 cores: 80 226 = 35.4% (below 37.5% low watermark)

Scale to: 80 0.53 = 151 cores (same as before!)

将几何平均值用于目标利用率,提供了重要的数学保证:

• 可逆伸缩(相同的使用模式会返回相同的资源分配)

• 双向平衡的冗余空间

• 防止资源分配随时间漂移。



平滑瞬时峰值


为了避免响应瞬时峰值,系统基于每个副本计算的10分钟中位数滚动窗口来平滑 CPU 使用率。这有助于滤除短暂的尖峰,同时保留真实的持续增长。随后,系统会取所有副本中这些平滑值的最大值作为峰值使用量。

目标跟踪机制解决了 CPU 方面的难题。然而,CPU 并非全貌,每个窗口还需要生成一个基于内存的推荐值。


基于内存的推荐


与 CPU 推荐器类似,每个窗口也会生成一个基于内存的推荐值。内存推荐器会跟踪多种信号,例如查询内存、常驻内存以及 OOM 事件(Out Of Memory events,包括 ClickHouse 管理的和容器层面的),并应用基于使用量的乘数,以确保留有足够的冗余空间。

针对每个窗口,CPU 和内存的推荐值都是独立生成的,系统会选择资源推荐量更高的方案。由于 ClickHouse Cloud 保持固定的 1 CPU 核对 4 GB 内存配比,因此 CPU 和内存会同步进行弹性伸缩。

有关内存信号、基于偏差的乘数以及推荐公式的详细信息,请参阅弹性伸缩文档(https://clickhouse.com/docs/manage/scaling)

结合目标跟踪机制的双窗口推荐器,能够在活跃使用期间优化资源分配。但对于那些完全不活跃的服务,又该如何处理呢?


自动休眠

虽然双窗口推荐器在活跃使用期间优化资源分配,但 ClickHouse Cloud 还提供自动休眠功能作为一项独立的成本优化特性,专为完全不活跃的时段设计。

关键区别:自动弹性伸缩根据活跃期间的使用模式调整资源,而自动休眠则是在服务在设定的持续时间内未接收到任何查询时,彻底暂停服务。

当服务进入休眠状态时,计算资源会被挂起(不产生 CPU/内存计费),而数据则完整地保留在存储中。当有新查询到达时,服务会自动恢复。ClickHouse Cloud 还实现了自适应休眠机制:这是一套智能逻辑,当需要进行后台合并操作时,或者当服务初始化需要更长超时时间时,它会阻止服务进入休眠状态。

有关自动闲置、配置选项、用例以及自适应行为的完整详情,请参阅自动闲置文档(https://clickhouse.com/docs/manage/scaling#automatic-idling)


结论

采用目标跟踪 CPU 扩缩容的双窗口推荐系统 (two-window recommender) 带来了显著改进:扩缩容下调延迟从 30 小时缩短至 3 小时,最大程度地减少了震荡问题,解决了级联过度配置,并为可变工作负载大幅降低了基础设施成本。

核心洞察在于,不同的时间窗口擅长处理不同的任务:短窗口适用于快速响应的缩容,而长窗口则适用于稳定的扩容决策。通过整合这两个窗口的推荐,我们实现了两全其美。

结合基于内存的推荐系统和闲置机制,这些改进使得我们的 ClickHouse 自动扩缩容系统 (auto-scaling system) 运行更快、更稳定、更具成本效益,让客户能够更放心地运行生产级工作负载。

双窗口推荐系统和目标跟踪算法奠定了坚实的基础,我们将继续优化扩缩容算法,以便更精确地将资源分配与实际利用率相匹配。


Meetup 活动报名通知

好消息:ClickHouse Shanghai User Group第 3 届 Meetup 火热报名中,将于2026年5月16日在上海市浦东新区世纪大道1568号中建大厦33层 Optiver上海 举行,扫码免费报名


/END/


试用阿里云 ClickHouse企业版


轻松节省30%云资源成本?阿里云数据库ClickHouse 云原生架构全新升级,首次购买ClickHouse企业版计算和存储资源组合,首月消费不超过99.58元(包含最大16CCU+450G OSS用量)了解详情:https://t.aliyun.com/Kz5Z0q9G



征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:Tracy.Wang@clickhouse.com

文章转载自ClickHouseInc,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论