DynamoDB 的云原生之路 —— 流控策略的演进

简介: DynamoDB 的云原生之路 —— 流控策略的演进

概述:流控为啥重要

上云的好处在于池化资源,让多租户共享,然后按需分配,从而降低成本。但进行:

  1. 多租户隔离:用户要求可以使用其买到的流量,并且不会被其他租户影响。
  2. 资源共享:资源只能逻辑隔开,不能物理隔开,否则无法充分动态分配(超发)。

是一对相对矛盾的事情,我认为,也是云原生数据库最要解决的问题。不把这个问题解决好,则数据库:

  1. 要么平台不赚钱:比如资源静态预留,虽然可以让用户满意,总能随时用到卖给他的资源配额,但会存在巨大资源浪费,要么价格贵,要么用户不买单。
  2. 要么用户不满意:多用户共享物理资源,但非常容易进行互相影响,造成用户不能用到平台声称的配额。

DynamoDB 从静态分配开始,逐步演化出一套全局和局部组合的准入控制机制,从而实现了物理上资源共享,但又在逻辑上给用户以配额隔离,从而实现了数据库真正的云原生。下面,我依据 Amazon DynamoDB: A Scalable, Predictably Performant, and Fully Managed NoSQL Database Service[1] 这篇论文披露的细节,对其流控机制的演进过程做一个梳理,以飨诸君。

水平所限,谬误之处,欢迎在评论区指出。

木鸟杂记 https://www.qtmuniao.com/2022/09/24/dynamo-db-flow-control 转载请注明出处

开始:静态预留

这里面对的其实是一个常见的调度问题,如何将表的分片副本(table-partition-replication)调度到集群(一组物理机)上,并兼顾以下特性:

  1. 可用性:将物理机划分 AZ(Availability Zones,可用域),将不同副本调度到不同 AZ。
  2. 数据容量:其实是针对存储资源,每个物理机有容量总额,每个副本也有容量预期(能随着容量自动分裂,所以刚开始可能都比较小),表的分区副本创建时,需要为其寻找物理机资源余量大于其需求量的目标机器。比如,一个很简单的撮合策略是每次找集群中最空闲的那个机器。
  3. 流量:文中称 performance,其实包括计算资源网络带宽。分配方式和 2 类似。

本文关注重点主要在 3 上,并且引入了流量单位:读容量单位 (RCUs) 和写容量单位 (WCUs)。

最开始的策略是将表的总配额(provisioned capacity)平均分配给每个分区,比如表的总配额是 1000 RCUs,一共十个分区,每个分区 100 RCUs。则每个分区的流量不得超过 100 RCUs。

这种策略最大的优点就是实现简单,而缺点繁多。让我们仔细审视下该策略,发现它其实蕴含了一个假设:分区间的流量是均匀的。但在现实中,这种模型太理想了。而一旦分区流量不均匀,就有可能出现,某些分区由于流量大,达到了该分区配额 100 WCUs 而被限流;而另外一些流量小的分区的配额却被浪费。

初步:突发策略和自适应流量

为了给上述纯静态分配策略打个补丁,DynamoDB 开始引入了流量突发(busting)和流量自适应(adaptive)策略。

突发策略

为了应对某些分区短时突发流量(short-live spikes)的问题,DynamoDB 引入了一个补丁(workaround),如果发现某个分区瞬时流量较大,且分区副本所在节点还有余量,就临时给该副本调配一些。具体到实现上,DynamoDB 用了三个令牌桶:

  1. 分区预留令牌桶。对应前面例子中的那 100 RCUs,当分区流量不超过这个值时,允许读写且从该令牌桶中扣除相应数量令牌。
  2. 节点总量令牌桶。对应单机容量限制,所有请求到来时,都要消耗此桶中令牌。
  3. 分区突发令牌桶。当分区流量超过预留时,会检查节点总量令牌桶是否还有余量,如果有就允许该分区进行突发。

需要注意,RCU 配额用上述策略就够了,但对于 WCU 配额,DynamoDB 还加了一条限制:需要检查该分区所有副本的 WCU 总额是否超限。其想法是,RCU 可以适当多给,但 WCU 不行。实现也很朴素,每个分区(多副本会构成一个复制组) Leader 会充当协调者,进行容量信息收集和分发。

最后,该策略只用于解决 300 秒内的短时突发流量,超过了时间窗口,借调的流量是要被释放出来的。因为这部分流量属于机器中的超发流量,需要随时准备调配给本机上的其他分区副本使用。

自适应策略

那对于长时突发流量(long-live spikes)怎么解决呢?只能在不同分区中进行流量调配了。

DynamoDB 使用某个中心服务(论文中就叫 Adaptive capacity,不确定该组件是额外引入的还是属于某个中心服务的一部分),来监控每个表的总配额已耗容量

当某个表还有余量,但表的某些分区因为流量突发被限流时,可以通过按成比例控制算法(a proportional control algorithm,应该就是按流量大小比例)来给这些分区调配一些配额。并且,如果调配后,触到了所在存储节点整机配额上限,自动管理系统(autoadmin system)会将该分区迁移到相对空闲、可以提供所需配额增量的机器。

反思:分区和流控耦合

前两者最大特点是将流控分区过紧地耦合到了一块,即在分区级别做的流量控制,因此很难对一个表进行跨分区进行流量调度。而我们对用户提供的是表级别的配额抽象,因此最好隐藏分区这个物理实现,保证只要表的总配额还有余量,就能给有突发流量的数据进行分配。而不能说,一些分区流量小,但仍然占用着配额,另外一些分区流量大,但在用完了分配给其的配额后,就要被限流。

虽然自适应策略在跨分区方向做了一些改进,但仍然是补丁范畴,而不是将动态流控作为第一思想来设计。为此,DynamoDB 引入全局准入控制机制来彻底解决此问题。

改进:全局准入控制

全局准入控制(global admission control,GAC)同样使用令牌桶的实现方式,但与之前局部令牌桶不同,全局准入控制使用一种全局令牌桶,或者说分布式令牌桶。由 GAC 服务来产生令牌,请求路由实例消费令牌,来达到表粒度准入控制。

组件

image.png

                                       DynamoDB 架构

  1. GAC 服务:由一组 GAC 实例构成,以一致性哈希[2]的方式进行流量均摊。
  2. GAC 实例:使用令牌桶方式产生令牌,每个实例会维护一个或者多个表级别的令牌桶。
  3. 请求路由器:request router,GAC 的客户端,与 GAC 服务通信,获取令牌进行流控。其中,令牌是有时限的,过期不被消费也会自动销毁。

其中有个关键问题是,GAC 每次给某个请求路由实例分配多少令牌?

DynamoDB 会根据历史信息,追踪每个请求路由实例的消费速率,按速率等比例分配。那如何进行追踪呢?论文中没有提,估计是使用滑动时间窗口之类的,但这类信号也不太好做,总会出现刻画不准或延迟太大的情况,不知道 DynamoDB 具体是如何实现的。

动态均衡

与静态分区和流量配额不同,GAC 视角下的分区流量会随时变化。为了避免热点聚集导致某些存储节点被打垮,DynamoDB 实现了一套可以主动根据吞吐消耗存储量来对分区进行跨节点均衡的机制:

  1. 每个存储节点会各自进行资源用量核算,如果节点资源总用量超过节点某个百分比阈值,该存储节点就会主动向自动管理服务(autoadmin service)汇报,并给出一组待迁移副本候选列表
  2. 自动管理服务在收到请求后,会根据全局资源分布,为每个候选副本找到一个合适存储节点,同时满足开篇提到的可用性资源用量约束。

流量拆分

如果某个分区上有很大的热点,受限于所在节点负载可能仍会被限流。DynamoDB 会追踪这些热点,并统计该分区上数据的流量分布,按流量对分区进行切分。相比单纯的按中点(均衡存储资源)进行分裂,按流量分布(计算和带宽)进行切分,对于消除热点来说,可能更为本质。分区拆分后,可以按需进行迁移。

分区分裂的所需时间通常在分钟量级。

但有一些访问热点,并不能通过分区分裂来进行消除:

  1. 单数据条目热点
  2. 范围访问热点

DynamoDB 能够识别这类访问模式,从而避免在这样的分区上进行拆分。

自动配给

在创建表时就为表设定固定配额是一件很难的事情,就跟你需要预知将来一样。如果设置的多了,会造成资源浪费;设置的少了,又容易触发限流。这是静态配额的一个弊端,因此 DynamoDB 提供一种动态配额表on-demand provisioning table,然后按用实际用量计费,这也是云计算的一大特征)。

为了精确描述配额,DynamoDB 引入了衡量吞吐的概念:读写容量单位(read and write capacity units)。如果单纯用 QPS 刻画流量,显然不合适,因为每个请求所涉及的数据量是不等的。因此 DynamoDB 引入单位时间内单位流量额度:RCU 和 WCU 来对读写流量进行刻画。

在进行自动配额时,首先要准确追踪读写流量。在检测到流量突发且要触发限流时,会对配额进行指数扩充(二倍)。如果应用持续流量大于之前尖峰的二倍,则会通过按流量拆分分区等方法进一步提高整体配额。

小结

云上一个重要特征就是资源池化、按需分配精准计费,从而在整体上实现资源的充分利用,通过规模化优势抵消通用性带来的成本。

具体到云原生数据库中,便是多租户流量的自动配给。DynamoDB 通过论文披露了其从配额静态划分、打补丁演进,到全局动态划分的一个演进过程。对于国内各路号称要做云原生数据库的厂商来说,想要在保证用户体验(资源隔离)的前提下真正赚钱(资源共享),DynamoDB 的经验想必有诸多可借鉴之处。


我是青藤木鸟,一个喜欢摄影的分布式系统程序员,欢迎关注我的公众号:”木鸟杂记“,获取分布式系统入门指导和诸多论文翻译。如果感觉不错,就帮忙点个在看分享给更多人吧,感谢~参考资料

[1]Amazon DynamoDB: A Scalable, Predictably Performant, and Fully Managed NoSQL Database Service: https://www.usenix.org/system/files/atc22-elhemali.pdf

[2]wiki consistent hash: https://en.wikipedia.org/wiki/Consistent_hashing

相关文章
|
1月前
|
运维 监控 Cloud Native
云原生时代的运维策略:从反应式到主动式的转变
在云原生技术日益成为企业数字化转型的核心动力时,运维团队面临着前所未有的挑战与机遇。本文将深入探讨云原生环境下的运维模式转变,从传统的反应式运维逐步向更加高效的主动式运维演进,以及这一转变如何影响企业的成本效益、系统稳定性和团队协作。文章将通过具体案例分析,阐述主动式运维的实践路径,并讨论其对企业运维文化的深远影响。
|
4月前
|
存储 弹性计算 监控
【阿里云云原生专栏】成本优化策略:在阿里云云原生平台上实现资源高效利用
【5月更文挑战第29天】本文探讨了在阿里云云原生平台上实现资源高效利用和成本优化的策略。通过资源监控与评估,利用CloudMonitor和Prometheus等工具分析CPU、内存等使用情况,识别浪费。实施弹性伸缩策略,利用自动伸缩规则根据业务负载动态调整资源。借助容器化管理和Kubernetes编排提高资源利用率,优化存储选择如OSS、NAS,以及网络配置如VPC和CDN。示例展示了如何使用Kubernetes的HorizontalPodAutoscaler进行弹性伸缩,降低成本。
208 4
|
4月前
|
机器学习/深度学习 运维 Cloud Native
构建未来:云原生架构在企业数字化转型中的关键作用构建高效机器学习模型的五大策略
【5月更文挑战第31天】 随着企业数字化进程的加速,传统的IT架构日益显示出其局限性。本文将探讨云原生架构如何成为推动企业敏捷性、可扩展性和创新能力的核心力量。通过深入分析云原生技术的基本原理及其在业务连续性、资源优化和跨云协作方面的应用,揭示了其在实现高效、灵活的企业IT环境中所扮演的角色。
|
4月前
|
存储 Kubernetes Cloud Native
【阿里云云原生专栏】云原生容器存储:阿里云CSI与EBS的高效配合策略
【5月更文挑战第29天】阿里云提供云原生容器存储接口(CSI)和弹性块存储(EBS)解决方案,以应对云原生环境中的数据存储挑战。CSI作为Kubernetes的标准接口简化存储管理,而EBS则提供高性能、高可靠性的块存储服务。二者协同实现动态供应、弹性伸缩及数据备份恢复。示例代码展示了在Kubernetes中使用CSI和EBS创建存储卷的过程。
227 3
|
4月前
|
监控 Cloud Native 数据库
【阿里云云原生专栏】性能优化之道:阿里云云原生平台上的监控与调优策略
【5月更文挑战第22天】本文介绍了阿里云云原生平台的监控与调优策略。阿里云提供如CloudMonitor、ARMS和ACK监控等工具,用于基础和应用监控,以及容器监控。调优策略包括资源、代码和架构优化,例如根据监控数据调整资源配置,优化代码性能,和利用微服务、容器化和无服务器化改进架构。示例代码展示了如何进行监控和调优操作,强调实时监控与针对性调优对提升云原生应用性能的重要性。
275 1
|
4月前
|
运维 监控 Cloud Native
构建高效稳定的云原生应用部署策略
【5月更文挑战第17天】 在现代软件工程实践中,云原生架构已成为实现敏捷开发、持续交付和微服务治理的关键。本文深入探讨了如何构建一个既能满足业务快速迭代需求,又能保障系统稳定性的云原生应用部署策略。通过分析容器化技术、微服务设计原则以及自动化部署工具的选择与使用,提出了一种综合部署流程优化方案。文章旨在为运维工程师提供一种系统性解决方案,以应对复杂多变的生产环境挑战。
60 1
|
2天前
|
运维 监控 Cloud Native
云原生时代的运维策略:从反应式到自动化
在云计算的浪潮下,运维领域经历了翻天覆地的变化。本文将带你领略云原生时代下的运维新风貌,探索如何通过自动化和智能化手段,实现从传统的反应式运维向主动、智能的运维模式转变。我们将一起见证,这一变革如何助力企业提升效率,保障服务的连续性与安全性,以及运维人员如何适应这一角色的转变,成为云原生时代的引领者。
16 8
|
15天前
|
安全 网络安全 数据安全/隐私保护
云原生技术探索:容器化与微服务架构的实践之路网络安全与信息安全:保护数据的关键策略
【8月更文挑战第28天】本文将深入探讨云原生技术的核心概念,包括容器化和微服务架构。我们将通过实际案例和代码示例,展示如何在云平台上实现高效的应用部署和管理。文章不仅提供理论知识,还包含实操指南,帮助开发者理解并应用这些前沿技术。 【8月更文挑战第28天】在数字化时代,网络安全和信息安全是保护个人和企业数据的前线防御。本文将探讨网络安全漏洞的成因、加密技术的应用以及提升安全意识的重要性。文章旨在通过分析网络安全的薄弱环节,介绍如何利用加密技术和提高用户警觉性来构建更为坚固的数据保护屏障。
|
1月前
|
人工智能 运维 监控
云原生时代的运维策略:从反应式到主动式的转型之旅
在云原生技术如雨后春笋般涌现的今天,传统的运维模式正面临着前所未有的挑战。本文将探讨如何从被动应对故障的反应式运维,转变为能够预见问题并主动优化的主动式运维。我们将通过实际案例分析,揭示现代运维团队如何利用云原生工具和实践来提升效率、增强系统的可靠性和弹性。文章旨在为运维专业人士提供一条明晰的转型路径,帮助他们在快速变化的云原生环境中保持竞争力。
|
1月前
|
运维 监控 Kubernetes
云原生时代的运维策略:容器化与自动化的融合之道
在数字化转型的大潮中,企业IT架构正经历着前所未有的变革。云原生技术以其灵活性、可扩展性和弹性成为推动这一变革的核心力量。本文将深入探讨云原生环境下,如何通过容器化技术和自动化工具实现高效运维,确保系统的稳定性和业务的连续性。我们将从容器化的基础概念出发,逐步引入自动化运维的实践方法,并结合真实案例,展示如何在保障系统性能的同时提升运维效率。最后,文章将指出未来运维工作面临的挑战与机遇,引导读者思考在不断变化的技术环境中,如何持续优化运维策略。

热门文章

最新文章