
Materialize 为集群控制器新增突发自动扩缩容与后台平滑重配置功能
来源标题:A Modular Cluster Controller for Burst Autoscaling and Graceful Reconfiguration
Materialize 为其集群控制器新增了突发自动扩缩容和后台平滑重配置能力。用户可在集群上设置自动扩缩容策略,在常规副本预热期间临时启动大规格副本加速完成,预热结束后再退役该突发副本。官方称此次改动同时改进了控制平面的架构设计。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
我们最近新增了一组集群功能:突发自动扩缩容和后台优雅重配置。下面我会通过示例来说明这些功能,但对我而言,更令人兴奋的是我们成功添加了这些功能,并改进了控制平面的架构方式。后者我会在探讨完示例之后再进行解释。
假设我们有一个已有的大型集合 demo_events,并希望在其上创建一个新索引。这需要创建一个新的数据流,而数据流的填充(hydration)可能需要相当长的时间。
为了减少等待时间,我们现在可以在集群上指定一种自动扩缩容策略,在常规稳态副本进行填充的同时,启动一个大型的突发副本。其思路是:突发副本规模大、运行成本高,但可以快速完成填充。而当(更小、更便宜的)稳态副本完成填充后,突发副本就会被退役。
CREATE CLUSTER burst_demo (SIZE = '100cc'); 2 3 ALTER CLUSTER burst_demo SET ( 4 AUTO SCALING STRATEGY = ( 5 ON HYDRATION ( 6 HYDRATION SIZE = '800cc', 7 LINGER DURATION = '60s' 8 ) 9 ) 10 ); 11 12 CREATE INDEX demo_events_idx 13 IN CLUSTER burst_demo ON demo_events (id); Copy sql 我们可以查询集群状态,在突发发生时进行观察:
SELECT name, replicas, activity 2 FROM (SHOW CLUSTERS) 3 WHERE name = 'burst_demo'; 4 \watch 1 Copy sql 填充突发期间的示例输出:
name | replicas | activity 2 ------------+--------------------------+--------------------------- 3 burst_demo | r1 (100cc), r2 (800cc) | hydration burst at 800cc 4 (1 row) Copy text 而当稳态副本完成填充、突发副本退役后,我们得到:
name | replicas | activity 2 ------------+------------+---------- 3 burst_demo | r1 (100cc) | 4 (1 row) Copy text 你可以在我们的文档中详细了解突发自动扩缩容策略:Autoscaling for hydration。
一段时间以来,我们一直有一个功能,允许在不造成停机的情况下重新配置集群:优雅集群重配置。当执行一条 ALTER CLUSTER [...] 语句(比如修改规模)时,我们会启动一个具有新规模的副本,保留旧副本,并且只有当新规模副本完成填充后,才退役旧规模的副本。这确实有效,但存在一个限制:在重配置进行期间,你必须保持 SQL 客户端会话处于打开状态。
作为突发自动扩缩容工作的一部分,我们借此机会改进了代码,将所有集群控制机制抽取到一个共享的集群控制器中。而作为一个“副作用”,我们还使得优雅重配置现在可以在后台运行,不再需要活跃的 SQL 客户端连接。
作为用户,你现在可以像下面这样使用它。在一个 psql 会话中持续查询:
SET cluster = burst_demo; 2 SELECT payload FROM demo_events WHERE id = 42; 3 \watch 1 Copy sql 在另一个会话中,调整规模并进行观察:
ALTER CLUSTER burst_demo SET (SIZE = '200cc'); 2 3 SELECT name, replicas, activity 4 FROM (SHOW CLUSTERS) 5 WHERE name = 'burst_demo'; 6 \watch 1 Copy sql ALTER 语句会立即返回,重配置将在后台继续进行。
在重配置期间,上述 watch 查询会返回类似如下的结果:
name | replicas | activity 2 ------------+--------------------------+----------------------------- 3 burst_demo | r1 (100cc), r2 (200cc) | reconfiguring size to 200cc 4 (1 row) Copy text 你也可以在我们的文档中了解集群规模调整:Cluster resizing
简而言之,Materialize 控制平面是一个 environmentd 进程,它驱动构成数据平面的 clusterd 进程。在 environmentd 内部,有一个我们称之为 Coordinator 的中央控制循环,它接收内部和外部命令,进行处理,并向自身或集群分发新命令。
用伪 Rust 代码来表示,你可以大致想象成这样:
loop { 2 select! { 3 cmd = internal_cmd_rx.next() { 4 process_internal_cmd(cmd).await 5 } 6 cmd = user_cmd_rx.next() { 7 process_cmd(cmd).await 8 } 9 [..] 10 } 11 } Copy rust 我们继承了这个设计,它来自 Materialize 最初的时期,当时使用一个中央串行化循环是提供 Materialize 正确性体验(读一致性)的最简单方法。它的缺点在于,一个必须处理所有事情的中央循环限制了你所能完成的工作量,因为一秒钟只有大约 1000 毫秒。随着时间的推移,我们积累了许多优化措施,将工作从这个中央循环卸载到后台任务和执行阶段,以从这个设计中挤出更多性能。但它有其局限性,而控制平面团队的一个长期目标就是使其在垂直和水平方向上都能“无限”扩展。
在我们开展集群控制器工作之前,现有的(前台)优雅重配置功能是作为消息和执行阶段实现的,由这个中央控制循环进行排序。而添加突发自动扩缩容的显而易见——但在我看来是错误的——方法,就是直接在现有优雅重配置所在的位置,以类似的方式添加该功能。
相反,我们所做的是退后一步,从整体上思考(长期)架构应该是什么样子,并朝着那个方向迈进。
控制平面的长期愿景要求 environmentd(或其替代进程)在垂直和水平方向上都能扩展。这里的垂直扩展意味着,当我们为进程提供更多 CPU 核心时,我们可以完成更多有用的工作,从而处理更大的查询工作负载、更多的对象和集群等等。这里的水平扩展意味着,我们可以有多个进程协调并共享给定环境的控制平面工作负载。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。