要点
币安利用容量管理来应对高波动性导致的流量激增的意外情况,确保业务需求得到充足、及时的基础架构和计算资源的支持。
币安在生产环境(而不是模拟环境)中进行负载测试,以获得准确的服务基准。此方法有助于验证资源分配是否满足已确定的负载。
币安的基础架构需要处理大量流量,为了维护用户对服务的依赖性,我们需要进行适当的容量管理和自动负载测试。
为什么币安需要专门的容量管理流程?
容量管理是保持系统稳定性的基石。容量管理需要以合理的成本,根据当前和未来的业务需求对应用程序和基础架构资源进行适当调整。为了实现这一目标,我们不断开发容量管理工具和渠道,以避免过载,同时为企业提供流畅的用户体验。
与传统金融市场相比,加密货币市场的波动期往往更有规律。这表明币安系统必须不时地承受来自用户对市场变动的反应而产生的流量激增问题。适当的容量管理能够让我们始终保持充足的容量来满足一般业务需求以及流量激增的情况。正是这一点,才使得币安的容量管理流程独一无二且富有挑战性。
先来了解一下经常阻碍流程并导致服务变慢或无法提供的因素。首先,我们会出现过载情况,一般由流量突然激增引起。例如营销事件、推送通知甚至DDoS(分布式拒绝服务)攻击都有可能造成这种情况。
流量激增和容量不足会影响系统功能,因为:
这项服务承担了过多的工作。
服务响应时间过长,导致客户端无法在超时时间内响应任何请求。服务性能下降通常由资源饱和(CPU、内存、IO、网络等)或服务本身或其依赖关系中的GC暂停时间过长引起。
最后导致的结果就是该服务无法及时处理请求。
分解流程
我们在前文已经讨论了容量管理的一般原则,下面让我们来了解一下币安如何将容量管理应用于业务中。以下是币安容量管理系统的架构,其中包含一些关键工作流程。
通过从配置管理数据库(CMDB)获取数据,生成基础架构和服务配置。。这些配置项即为容量管理对象。
指标收集器从Prometheus获取业务和服务层的容量指标数据,从基础架构监控系统获取资源层的指标数据,从调用跟踪分析系统获取跟踪信息。指标收集器将数据存储在容量数据库(CDB)中。
负载测试系统对服务进行压力测试,并将基准数据存储在CDB中。
聚合器从CDB获取容量数据,并将其按照每日和历史最高(ATH)维度进行聚合。聚合完成后,将聚合后的数据写回到CDB中。
通过处理CDB中的数据,后端API提供了容量仪表板、警报和报告系统接口,还提供了REST API及相关容量数据用于集成。
利益相关者可以通过容量仪表板、警报和报告系统了解容量。此外,还可以使用其他相关系统,包括使用Swagger容量管理系统提供的REST API来监测获取服务的容量数据。
策略
币安的容量管理和规划策略依赖于峰值驱动处理。峰值驱动处理是指服务的资源(web服务器、数据库等)在峰值使用期间所经历的工作负载。
2023年3月美联储加息时流量激增
我们分析周期性峰值,并利用这些峰值驱动容量轨迹。与峰值驱动的资源一样,我们希望了解峰值发生的时间,然后深入了解在这些周期中到底发生了什么。
除了防止过载之外,我们还考虑了自动扩展的重要性。自动扩展通过动态增加服务实例来处理过载情况。多余的流量随后被分配,单个服务实例(或依赖项)处理的流量保持可管理状态。
自动扩展虽然有其适用的场景,但无法独自处理过载的问题。流量突然增加时,它通常无法做出快速反应,只有流量逐渐增加时才能发挥最佳效果。
测量
测量在币安的容量管理工作中起着至关重要的作用,收集数据是我们进行的第一步测量。根据信息技术基础架构库(ITIL)标准,我们在容量管理子流程中收集测量数据,包括:
资源——应用程序/服务使用驱动的IT基础架构资源消耗。重点关注物理和虚拟计算资源的内部性能指标,包括服务器CPU、内存、磁盘存储、网络带宽等。
服务。应用程序级别的性能、SLA、延迟和吞吐量等指标均由业务活动产生。重点关注基于用户如何感知服务的外部性能指标,包括服务延迟、吞吐量、峰值等。
业务。收集衡量目标应用程序处理的业务活动数据,包括订单、用户注册、支付等。
仅基于基础架构资源利用率的容量管理会导致规划不准确。原因是它无法代表驱动基础架构容量的实际业务量和吞吐量。
预定事件为进一步探讨这个问题提供了契机。在币安直播观看2022年网络峰会,在加密货币盒子奖励活动中分享高达15,000 BUSD的奖金。除了基础资源和服务层指标之外,我们还需要考虑业务量。我们在业务指标的基础上进行容量规划,例如预估的直播观众量、加密货币盒子正在处理中的最大请求量、端到端延迟等因素。
收集数据之后,容量管理流程会针对特定的容量驱动因素进行聚合和总结。指标的聚合值是一个单一数值,能够用于容量警报、报告以及其他与容量相关的功能。
我们可以将几种数据聚合方法应用于周期性数据点,如总和、平均值、中值、最小值、最大值、百分位数和历史最高记录(ATH)。
我们选择的方法决定了容量管理流程的输出结果和相应的决策。场景不同,选择的方法也有所不同。例如,我们在关键服务和相关数据点中采用最大值法。为了记录最高流量,我们采用ATH方法。
对于不同的用例,我们使用不同的粒度类型进行数据聚合。大多数情况下,我们使用分钟、小时、天或ATH来进行聚合。
分钟粒度能够测量服务的工作负载,以便及时发出过载的警报。
我们使用每小时聚合的数据来建立每日数据,并对每小时的数据进行聚合来记录每日峰值。
通常,我们使用每日数据进行容量报告,并利用ATH数据进行容量建模和规划。
容量管理的核心指标之一是服务基准测试。该测试能够准确衡量服务性能和容量。我们通过负载测试获得服务基准,之后再对此展开深入研究。
基于优先级的容量管理
到目前为止,我们已经了解了如何收集容量指标并以不同粒度类型进行数据聚合。还有一个需要讨论的重要领域是优先级,优先级在警报和容量报告的情景中很有帮助。对IT资产进行排名之后,我们将有限的基础架构和计算资源优先分配给关键服务和活动。
我们有多种方法来定义服务和请求的重要性。Google的SRE书籍很有参考价值。书上将关键性分为CRITICAL_PLUS、CRITICAL、SHEDDABLE_PLUS等级别。同样,我们也定义了多个优先级级别,例如P0、P1、P2等。
我们将优先级定义如下:
P0:针对关键服务和请求,一旦发生故障,会对用户产生可见的严重影响。
P1:针对会对用户产生可见影响,但影响程度小于P0的服务和请求。P0和P1服务应被分配足够的容量。
P2:这是批处理作业和离线作业的默认优先级。即使出现服务和请求部分不可用的情况,也不一定对用户造成可见的影响。
什么是负载测试,为什么我们要在生产环境中使用它?
负载测试是一种非功能性软件测试过程,其中在特定工作负载下测试应用程序的性能。这有助于确定应用程序在被多个最终用户同时访问时的行为。
币安制定了一个解决方案,让我们能够在生产中运行负载测试。通常,负载测试在模拟环境中运行,但基于总体容量管理目标,我们无法采用这个方案。生产环境中的负载测试能够让我们:
收集真实负载条件下准确的服务基准。
增强对系统及其可靠性和性能的信心。
在生产环境中出现问题之前,识别系统中遇到的瓶颈。
对生产环境启动持续的监测。
通过定期进行的规范化测试周期,启用主动容量管理。
下文是币安的负载测试框架和一些关键要点:
币安的微服务框架包含基础层,支持基于配置和标志的流量路由,这对我们的TIP方法至关重要。
采用自动金丝雀分析(ACA)来评估我们正在测试的实例。该分析比较了监控系统中收集的关键指标,如果发生任何意外问题,我们可以暂停/终止测试,最大限度地减少对用户的影响。
在负载测试期间收集基准和指标,以生成有关行为和应用程序性能的数据见解。
API可以在各种场景中共享有价值的性能数据,例如容量管理和质量保证。这有助于建立一个开放的生态系统。
我们创建自动化工作流程,从端到端测试的角度协调所有步骤和控制点。我们还提供了与其他系统集成的灵活性,如CI/CD流水线和运维门户。
币安的生产测试(TIP)方法
传统的性能测试方法(在模拟或镜像流量的模拟环境中运行测试)的确提供了一些好处。不过,在币安环境中,部署类似生产的模拟环境存在更多缺陷:
它几乎使基础架构成本和维护工作增加了一倍。
在生产环境中实现端到端的工作流程十分复杂,尤其是在跨多个业务单元的大规模微服务环境中。
由于我们不可避免地需要在模拟环境中复制数据,这样的工作流程会增加数据隐私和安全风险。
模拟流量绝不会复制生产中发生的情况。在模拟环境中获得的基准测试结果可能不准确,也没什么参考价值。
在生产环境中测试,也称为TIP,是一种右移测试方法,其中在生产环境中测试新代码、功能和版本。我们在生产环境中采用的负载测试大有裨益,有助于:
分析系统的稳定性和鲁棒性。
发现应用程序在不同级别的流量、服务器规格和应用程序参数下的基准测试和瓶颈。
FlowFlag路由
我们在微服务基础框架中嵌入FlowFlag路由,为实现TIP提供了坚实的基础。这在特定情况下是正确的做法,包括使用Eureka服务发现流量分配的应用程序。
如图所示,币安网页服务器作为入口点,用FlowFlag头标记配置中指定的一定百分比的流量,在负载测试期间,我们可以选择特定服务的一个主机,并将其标记为配置中的目标性能实例,然后当这些带有性能标记的请求到达服务进行处理时,最终被路由到性能实例。
该路由完全由配置驱动且为热加载,我们可以利用自动化轻松调整工作负载的百分比,而无需部署新版本。
该机制是网关和基本包的一部分,可以广泛应用于大部分服务。
单一变更点也说明在生产环境中易于进行回滚,以降低风险。
在将我们的解决方案转变为云原生的同时,我们也在探索如何制定类似的方法来支持公共云供应商或Kubernetes提供的其他流量路由。
自动化金丝雀分析,最大限度地降低用户影响风险
Canary部署是一种部署策略,旨在降低将新软件版本部署到生产环境中的风险。通常包括向一小部分用户部署一个新版本的软件,称为金丝雀版本,还有一个是稳定运行的版本。然后,我们在两个版本之间分配流量,以便将一部分传入请求转移到金丝雀。
然后通过所谓的金丝雀分析来评估金丝雀版本的质量。这种分析比较了描述新旧版本行为的关键指标。如果指标出现显著下跌的情况,金丝雀测试将被中止,并将所有流量路由到稳定版本,最大限度地减少意外行为的影响。
我们使用相同的概念来制定自动负载测试解决方案。该解决方案利用Kayenta平台,通过Spinnaker进行自动化金丝雀分析(ACA),从而实现自动化的金丝雀部署。遵循此方法时,我们的典型负载测试流程如下:
通过工作流程,我们根据指定的目标逐步增加流量负载(例如5%、10%、25%、50%),直到达到临界点。
在每个负载下,使用Kayenta重复运行金丝雀分析,一段时间内(比如5分钟)与预负载时期的基准和当前负载后期的实验进行比较,以比较测试主机的关键指标。
比较(金丝雀配置模型)的重点是检查目标主机是否:
达到资源限制,例如CPU使用率超过90%,
出现故障的指标显著增加,例如错误日志、HTTP异常或速率限制拒绝。
核心应用程序指标是否仍然合理,例如,HTTP延迟小于2秒(可针对每项服务进行自定义)
针对每次分析,Kayenta都会给我们一份报告来说明分析结果,并且在测试失败后立即终止。
这种故障检测通常需要的时间不超过30秒,极大降低了影响最终用户体验的几率。
启用数据洞察力
收集关于所有先前描述的流程和测试执行的充分信息至关重要。我们的最终目的是提高系统的可靠性和稳健性,如果缺少数据洞察力,就无法实现这个目标。
总体测试摘要记录了主机能够处理的最大负载百分比、峰值CPU使用率和主机的QPS。根据这些信息,它还估算了我们可能需要部署的实例数量,以满足容量预留,同时考虑到服务的最高QPS。
其他有价值的分析信息包括软件版本、服务器规范、部署数量,以及到监控器面板的链接,我们可以在其中回顾测试期间发生的情况。
基准曲线显示了过去三个月性能的变化,我们从中可以发现与特定应用程序版本相关的可能发生的问题。
CPU和QPS趋势显示了CPU使用情况与服务器必须处理的请求量之间的关系。这个指标能够估计服务器的余量,以应对未来流量增长。
API延迟行为记录了前五个API在不同负载条件下的响应时间变化情况。如果需要,我们可以在单个API级别对系统进行优化。
API负载分布负载分布指标有助于了解API组合如何影响服务性能,并对改进领域提供更多见解。
规范化和产品化
随着系统不断发展壮大,我们将不断跟踪和提高服务的稳定性及可靠性。我们将通过以下方式实现:
针对关键服务制定定期和既定的负载测试计划。
自动负载测试是CI/CD流水线的其中一步。
提高整个解决方案的产品化程度,以准备在组织中大规模采用。
局限性
当前的负载测试方法存在一些局限性:
FlowFlag路由仅适用于我们的微服务框架。我们希望通过利用云负载均衡器或Kubernetes Ingress的通用加权路由功能,将解决方案扩展到更多路由场景。
由于我们的测试是基于产品中的真实用户流量,所以无法针对特定API或用例执行功能测试。此外,由于我们无法识别业务量极低服务的瓶颈所在,因此,自动负载测试的价值也会受限。
我们针对单个服务执行测试,而不是覆盖整个端到端的调用链。
如果出现故障,生产中的测试有时会影响实际用户。因此,我们必须具备完全自动化的故障分析和自动回滚功能。
结语
对我们来说,考虑流量激增的情况以防止系统过载并确保其正常运行时间至关重要。这就是为什么我们构建了本文中描述的容量管理和负载测试过程。总结下来主要是以下两点:
我们的容量管理以峰值为驱动,并嵌入到每个服务生命周期阶段中,通过测量、设置优先级、警报和容量报告等活动来防止过载的情况。最终使得币安的流程和需求与典型的容量管理情况不同。
从负载测试中获得的服务基准是容量管理和规划的重点。服务基准能够精准确定当前和未来业务所需的基础架构资源。而这一点最终要在生产环境中执行,采用一种由币安制定的特殊解决方案来满足我们的特定需求。
综合考虑,良好的规划和完善的框架有助于让币安用户了解并熟悉我们提供的服务。
延伸阅读
(博客)《币安账本如何支撑用户体验》
(博客)《币安预言机VRF介绍:下一代可验证的随机性》
(博客)《币安加入线上快速身份验证联盟,为推行通行密钥做好准备》
参考资料
[1]Dominic Ogbonna,《容量管理全面指南:企业IT监控和容量规划实用指南》,第4章和第6章。https://www.amazon.com/Capacity-Management-Implementing-Enterprise-Monitoring-ebook/dp/B07871VCFR
[2]Luis Quesada Torres,Doug Colish,《SRE最佳实践:容量管理》https://static.googleusercontent.com/media/sre.google/en//static/pdf/login_winter20_10_torres.pdf
[3]Alejandro Forero Cuervo,Sarah Chavis,谷歌SRE书籍,《第21章:处理过载》。https://sre.google/sre-book/handling-overload
推荐阅读: