如何评估服务的容量而不承受负载



迟早,任何增长的服务都必须评估其技术能力。 我们可以为多少游客服务? 系统的容量是多少? 如果我们吸引了数千名用户,我们是否达到了极限并且不会跌倒? 明年有多少额外的计算资源被预算以满足增长计划?

可以通过向经验丰富的开发人员/ DevOps / SRE /管理员解决问题来解析地获得答案。 评估的可靠性取决于众多因素:从向系统中填充功能的速度以及组件之间的关系图开始,到专家在交通中度过的时间结束。 系统越复杂,分析评估的适当性就越令人怀疑。

我叫Maxim Kupriyanov,已经在Yandex.Market工作了五年。 今天,我将告诉哈勃(Habr)的读者,我们如何学会评估我们的服务能力以及它的结果。



我们去的位置


市场组件的结构相当复杂,因此我们决定仅评估规模最大,最昂贵的服务的容量。 此外,对他们的每日请求数量应明确取决于市场的每日受众(每日活跃用户,DAU)的规模。 为什么是DAU的呢? 因为分析师在预测未来几个月和几年的时间时,总是会计算出受众的未来规模,所以我们将利用这种令人愉悦的情况。

现在,我们来谈谈没有它就不可能建立客观的评估:关于服务的指标。 如果服务请求的数量取决于DAU,那么我们肯定需要度量“每秒请求数”(每秒请求数,RPS)。 另外,要评估服务质量,您需要知道错误的百分比和响应时间(请求时间)。 该错误将被视为HTTP代码为500或更高的响应。 4xx范围的错误是客户端错误,在正常工作的系统中,通常不会说任何有关服务问题的信息。 至于计时,我们习惯上计算和存储响应时间的第80、95、99和99.9个百分位,但是每个服务的特定集合可能略有不同。

因此,我们具有请求频率,错误百分比和一组响应时间百分比的度量。 我们还知道DAU每天和将来的服务(以预测的形式)。 鉴于用户行为的平均模式每天变化不大,因此可以说以下几点:了解工作日最活跃时段的RPS(峰值RPS),只要我们有DAU预测,就可以预测未来时段的峰值RPS。 反之亦然:如果我们知道系统每秒可以承受多少请求而又不违反响应时间和错误百分比的约定,那么我们就可以估计我们可以为多少用户提供服务,即我们知道系统的容量。

好吧,我们决定了任务:以协议的形式确定响应时间和错误百分比,并找到系统在这些条件下可以承受的最大RPS。 我们将如何决定?



我们向目标射击


这是解决问题的经典方法:我们收集一个测试站点,从生产环境中获取系统访问日志,制作它们的盒带并启动系统,增加请求的频率,直到该站点在响应时间和/或错误方面表现出明显的下降。 在这一点上,我们停止并确定请求的频率(相同的RPS)。 胜利的 不管如何 这就是为什么:

  • 通常,测试站点与生产环境中服务所在的平台不同;
  • 服务代码每天或什至更频繁地更改;
  • 实验可能会影响负载;
  • 用户请求的严重性取决于一天中的时间和其他条件;
  • 现代服务很少孤立地工作,更多时候它们成为其他服务的子查询,因此必须以某种方式加以考虑。

改进:我们将每天自动启动该服务,并在高峰时段从杂志中收集墨盒。 并且为了不浪费资源在测试站点上,我们将开始依次在同一个机架上封装我们感兴趣的组件。 听起来很复杂,并不能解决所有问题。 但是还有其他选择吗?



模拟现实


总体思路是这样的:我们将部分流量从平衡器复制到站点,在那里我们以微型模式收集生产环境的完整模拟,然后调整复制流量的大小,寻找降级点。 这个想法很漂亮,我们在市场中这样做是为了测试新功能,并将新版本与旧版本的行为进行比较。 我的同事尤金(Eugene)详细讨论了这一点 -请参见阴影群集部分。 但是也有明显的困难:

  • 与外部组件交互的问题没有得到解决,因为复制整个生产环境非常昂贵;
  • 请求来自镜像系统的日志可能会意外地与来自生产环境的日志混合,这意味着有必要构建一个带有镜像流量标记的系统,以便可以找到并清除它。
  • 请求通常被全部或全部镜像,并且这种准确性不适合我们(但是可以解决,我们正在朝这个方向努力)。

通常,生产模仿是一种非常好的且很有前途的方法,但是非常昂贵并且有很大的局限性。



直接在生产中进行测试


然后我们终于到了美味。 对于每个经过测试的组件,我们在生产中提出一个单独的实例,该请求的频率由平衡器以高精度进行调节。 上一次, 读者问我们 :“ HAProxy是否足够您使用? 是否需要编写自己的东西?” 因此,这是非常罕见的情况,当时还不够,我不得不写。

同时,还有一个单独的服务可以密切监视已加载实例的指标,并且当指标接近临界值时,它将关闭平衡器上的阀门,从而减少了请求的频率。 如果维修工作在可接受的范围内,则阀门打开。 当然,加载实时服务时的时间和错误阈值比训练场要保守得多(通常为5-10%),因为我们不想恶化与用户的交互。 因此,加载的实例始终可以发挥最大作用。 我们修复了这些指标。 然后我们进行算术运算:我们知道每时每刻都处于负载状态的服务核心的数量,我们知道DAU。 由此,当禁用一个或另一个位置时,我们考虑回收,容量储备和系统行为选项。 所有这些都放置在构建精美图形的基础上。 根据这些数据,当容量下降到阈值以下时,将触发警报。

让我们看一下图




这就是我们控制流向测试实例的流量的方式。 该步长可以是1 RPS的任意倍数。 在图上,为说明起见,我们以3分钟为间隔对爬升进行了建模:首先是从650到1K RPS,以50为增量,然后是从200到1K RPS,以100为增量。让我提醒您,这是客户收到答复的真实用户流量。



这显示了三个实例的RPS:一个在负载下,两个在控制下。 该对象被人为设置为600 RPS的上限。 服务可能更多,但变得太不稳定并且取决于外部影响。 可以清楚地看到,在一天的前半部分,平均服务请求较重,并且在可接受的条件下该实例无法达到峰值容量,但是到了晚上,一切都恢复了正常。 图表上的突发和遗漏是实例重新启动,用于布置发行版和其他更新(它们都处于平衡状态,没有人受到伤害)。 对测试对象的逐步RPS调整只是寻求可能性极限的算法的工作。



服务请求的频率和一个实例可以承受的负载清晰可见。



在这里,我们以利用率的百分比重新计算所有内容。 该图显示该服务负载很重,并且其中一个位置被关闭时,SLA仍有可能离开。 但是现在一切都很好:资源已添加到服务中,回收已恢复到可接受的极限。

因此,生产中的负载测试使您可以快速评估系统的容量并预测将来的资源消耗。 同时,该系统实际上不会增加​​可观的费用,并且您可以安全地使用有状态服务,因为我们不会产生新的流量,而只会准确地重新分配流量。 最后:要正常工作,不需要更改实验系统本身的代码,这甚至可以测试旧版应用程序。



反映


这种方法在市场上已经使用了一年多,我们可以分享观察和建议:

  • 在加载的实例旁边,必须有一个普通的-控制,最好是蒸汽,因为降级通常不是因为实例过载而发生,而是由于整个服务的一般问题而发生。
  • 该技术仅适用于那些负载高于某个位置每秒数百个请求的组件。 原因很简单:我们需要同时加载测试实例和一个或两个控件。 如果没有足够的流量,我们将无法达到饱和,或者我们将无法诚实地进行比较。 而且,如果每个实例的限制RPS非常小,那么将请求频率更改为1 RPS的最小步骤可能太粗糙了。
  • 最好在不同位置测试前端和后端,以便负载测试后端的工件不会影响前端容量的估计。
  • 当我们分析响应时间并寻找降级的迹象时,我们通常采用五分钟的汇总并计算中位数,以免对随机突发做出反应。
  • 加载的服务实例崩溃的主要原因是日志文件(日志)的磁盘空间。 他们总是忘记他。
  • 即使是在SSD上,登录到Web服务器的I / O加载磁盘也是导致时间恶化的非常普遍的原因。 始终打开缓冲,异步记录等功能,只是不要等到记录结束。
  • 夜间负载不是指示性的,因为由于机器人的份额较大,因此请求平均较重。 因此,为了估计容量,最好将固定范围设置为白天的常规轻时间,而在晚上,只有在出现降级迹象时才减少请求流量。
  • 由于网络可用性保证很少超过99%,因此响应时间的99.9%对容量估计没有用。
  • 开始时间表并记录服务发布和其他重要事件。 它有助于找出导致容量减少的原因。
  • 在详细分析降级原因时,跟踪也很有用:将标记标头添加到每个服务请求,该请求标头从前端到最后一个后端,并输入所有日志。 这样,您可以跟踪整个请求路径并了解导致延迟的原因。

Source: https://habr.com/ru/post/zh-CN481134/


All Articles